Learn Remix - API Integration & External Data
Series/Learn Remix/Episode 13
Episode 13 of 24

Learn Remix - API Integration & External Data

This episode covers integrating external data: fetching APIs in loaders and actions, working with REST and GraphQL backends, secure auth token and request handling, and good rate limiting and error fallbacks.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Real applications rarely live alone. Search uses external services, payments use third-party providers, and recommendations come from AI models. Episode 13 covers how Remix talks to the outside world securely and efficiently.

The biggest advantage: because loaders and actions run on the server, external API calls are invisible to the client. Tokens and keys stay hidden, CORS is not a problem, and data can be processed before it's sent to the browser. This is another reason Remix's server-first pattern is so practical.

Episode 13 covers fetching in loaders and actions, REST and GraphQL integration, token handling, and rate limiting with error fallbacks.

Fetching APIs in Loaders and Actions

The Loader as a Server Proxy

A loader can call an external API with fetch, process the response, and send clean results to the component:

JSFetching an external API in a loader
export async function loader() {
  const res = await fetch("https://api.contoh.dev/posts", {
    headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
  });
 
  if (!res.ok) {
    throw new Response("Gagal memuat data", { status: 502 });
  }
 
  const posts = await res.json();
  return { posts };
}

The token is never visible to the client because the fetch happens on the server. CORS is irrelevant here — you're free to call any domain from the server.

Reading the URL in a Loader

A loader receives a request whose URL can be read for page parameters, search terms, or filters. new URL(request.url) gives access to searchParams, which are then forwarded to the external API. This pattern keeps one source of truth: the URL.

Working with REST and GraphQL

REST with Transformation

REST APIs generally return more data than you need. Transforming in the loader — picking fields, renaming them, adding supporting data — keeps components simple and the client payload as small as possible.

JSTransforming a REST response
export async function loader() {
  const res = await fetch("https://api.contoh.dev/posts?limit=10");
  const data = await res.json();
 
  const ringkas = data.posts.map((p) => ({
    id: p.id,
    judul: p.title,
    penulis: p.author.username,
  }));
 
  return { posts: ringkas };
}

Transforming in the loader means the client doesn't have to rewrite raw data. The structure sent to the browser matches the UI's needs, not the API's needs.

GraphQL with Specific Queries

GraphQL lets you request exactly the fields you need in a single request. In the loader, just send the query and token:

JSGraphQL query in a loader
export async function loader() {
  const query = "{ posts { id title } }";
  const res = await fetch("https://api.contoh.dev/graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.GRAPHQL_TOKEN}`,
    },
    body: JSON.stringify({ query }),
  });
  return { posts: (await res.json()).data.posts };
}

GraphQL reduces over-fetching, but still run it on the server to keep tokens safe. For complex queries, libraries like urql or Apollo can be used, but plain fetch is often enough for a route's needs.

Token Handling and Secure Requests

Tokens Only on the Server

External auth tokens are stored in environment variables and only read in loaders and actions. Never expose them to the client. If a token needs to be used on the client for some reason, create a resource route that acts as a proxy — the client calls your endpoint, not the external API.

Retry and Timeout

External requests can fail or be slow. Add a timeout with AbortSignal and consider retrying for transient errors. A healthy pattern: fail fast with a clear message rather than hang without any word.

Rate Limiting and Error Fallbacks

Respecting API Limits

External APIs have quotas. Avoid repeated calls for data that rarely changes by reusing the caching from episode 9. Also consider queues for heavy work that doesn't have to be synchronous.

Fallbacks When an API Fails

When an external API goes down, your application shouldn't go down with it. A common pattern: provide backup data (for example, the last version from the database), or show a clear empty state with a message users can understand.

JSFallback when an API fails
export async function loader() {
  try {
    const res = await fetch("https://api.contoh.dev/posts");
    if (!res.ok) throw new Error("bad status");
    return { posts: await res.json() };
  } catch {
    return { posts: [], sumber: "cadangan" };
  }
}

Try/catch in the loader turns an external failure into a controlled response. The UI still renders, and users are informed through the source field.

Conclusion

Episode 13 opens your application to the world: external fetching in loaders and actions, REST and GraphQL integration with data transformation, tokens that only live on the server, and rate limiting with error fallbacks that keep the application breathing when other services fall over.

The key takeaways:

  • Call external APIs in loaders and actions, not in the client.
  • Tokens and keys live in server environment variables.
  • REST data is processed and simplified in the loader before reaching the client.
  • GraphQL cuts over-fetching; still run it on the server.
  • Add timeouts with AbortSignal and retries for transient errors.
  • Provide a fallback when an external API fails so the UI keeps working.

In the next episode, episode 14, we'll discuss network performance and caching — HTTP caching strategies for Remix, CDN and edge cache integration, prefetching data and links, and optimizing the first load and subsequent navigation. External data comes in; now let's make sure it travels as fast as possible.

Learn Remix - API Integration & External Data | Learn Remix