# React Router + DatoCMS Overview

React Router is the routing standard of the React ecosystem, and since version 7 it also ships a full-stack framework mode: server rendering, nested routes, data loading, actions and type-safe route modules, all built on top of Vite. It lets you get started without having to write much boilerplate code, and with a set of sane defaults from which you can build upon.

React Router fully supports edge functions and advanced caching mechanisms, and React Router projects can be deployed on many different hostings, such as [Netlify](https://netlify.com/), [Vercel](https://vercel.com/) and [Cloudflare Workers](https://workers.cloudflare.com/). See the [deploying guide](https://reactrouter.com/start/framework/deploying) for the full list of options.

DatoCMS is the perfect companion to React Router since it offers content, images, and videos on a globally-distributed CDN. With this combo, you can have an **infinitely scalable website, ready to handle prime-time TV traffic spikes, at a fraction of the regular cost.**

> [!NOTE] Coming from Remix?
> React Router v7 in framework mode is the direct continuation of Remix v2: same route modules, same `loader` and `action` functions, same progressive enhancement. The main difference is that imports moved from `@remix-run/*` to `react-router`. If you have an existing Remix v2 project, follow the official [upgrade guide](https://reactrouter.com/upgrading/remix).
> 
> Be aware that [Remix v3](https://remix.run/) is a different, React-less framework, with no migration path from Remix v2. This guide does not cover it.

Our [marketplace](https://www.datocms.com/marketplace/starters.md) features different demo projects you can learn from and get started easily. The following one is built with Remix, but every pattern in it applies to React Router as well:

### Fetching content from our GraphQL API

First, use the React Router wizard to set up a new project. Read more about your options on the [React Router docs](https://reactrouter.com/start/framework/installation).

Terminal window

```bash
npx create-react-router@latest
```

The way you fetch content from external sources in React Router is by exporting a `loader` function from your [route modules](https://reactrouter.com/start/framework/route-module). Whatever the loader returns is handed over to the React component through its `loaderData` prop:

app/routes/home.tsx

```tsx
import type { Route } from './+types/home';

export async function loader() {
  return { foo: 'bar' };
}

export default function Homepage({ loaderData }: Route.ComponentProps) {
  const { foo } = loaderData;

  // ...
}
```

Route modules are then wired up in `app/routes.ts`, which is where you declare the URL each of them responds to:

app/routes.ts

```typescript
import { type RouteConfig, index } from '@react-router/dev/routes';

export default [index('routes/home.tsx')] satisfies RouteConfig;
```

Inside the `loader` function, we can use any Node.JS GraphQL client (or HTTP client, really) to fetch content from the [Content Delivery API](https://www.datocms.com/docs/content-delivery-api.md) of DatoCMS.

Let's start by installing `@datocms/cda-client`, a lightweight, TypeScript-ready package that offers various helpers around the native Fetch API to perform GraphQL requests towards [DatoCMS Content Delivery API](https://www.datocms.com/docs/content-delivery-api/api-endpoints.md):

Terminal window

```bash
npm install --save @datocms/cda-client
```

> [!PROTIP] Pro tip: Top 5 JavaScript GraphQL Client Libraries
> Our `@datocms/cda-client` is not the only option. This [blog post](https://www.datocms.com/blog/best-javascript-graphql-clients.md) ranks the best JavaScript GraphQL client libraries, helping you choose the right tool based on your project’s specific needs and ensuring efficient and optimized GraphQL data fetching.

We can now create a function we can use in all of our components that need to fetch content from DatoCMS: Create a new directory called `lib` inside `app`, and inside of it, add a file called `datocms.js`:

app/lib/datocms.js

```javascript
import { executeQuery } from '@datocms/cda-client';

export const load = (query, options) => {
  return executeQuery(query, {
    ...options,
    token: process.env.DATOCMS_READONLY_TOKEN,
    environment: process.env.DATOCMS_ENVIRONMENT,
  });
}
```

We want to store inside environment variables both the API token and the name of the DatoCMS environment we want to fetch content from to hide them from the code, and so that we'll be able to modify them later without touching the code. React Router runs on [Vite](https://vite.dev/guide/env-and-mode), so a `.env` file at the root of your project is all you need during development. Loaders and actions only ever run on the server, so they can safely read those secrets from `process.env`.

To create an API token for a DatoCMS project, go to `Settings > API Tokens` section of your DatoCMS backend. Make sure to only give it permissions to access the (read-only) Content Delivery API.

(Video content)

It's time to use our function in a real page! Open up `app/routes/home.tsx`, which is the route that renders the homepage, and define the `loader` function and a basic page component:

```tsx
import type { Route } from './+types/home';
import { load } from '~/lib/datocms';

const HOMEPAGE_QUERY = `query HomePage($limit: IntType) {
  posts: allBlogPosts(first: $limit) {
    title
  }
}`;

export async function loader() {
  return load(HOMEPAGE_QUERY, {
    variables: { limit: 10 },
  });
}

export default function Home({ loaderData }: Route.ComponentProps) {
  const { posts } = loaderData;

  return <div>{JSON.stringify(posts, null, 2)}</div>;
}
```

The `HOMEPAGE_QUERY` is the GraphQL query, and of course it depends on the models available in your specific DatoCMS project. You can learn everything you need regarding how to build GraphQL queries on our [Content Delivery API documentation](https://www.datocms.com/docs/content-delivery-api.md).

For more information on what to do next, we recommend reading the next sections of this integration guide!

## Related content in "React Router"

- [React Router + DatoCMS Overview](https://www.datocms.com/docs/react-router.md)
- [Managing images](https://www.datocms.com/docs/react-router/managing-images.md)
- [Displaying videos](https://www.datocms.com/docs/react-router/displaying-videos.md)
- [Structured Text fields](https://www.datocms.com/docs/react-router/structured-text-fields.md)
- [Adding SEO to pages](https://www.datocms.com/docs/react-router/seo-management.md)
- [Setting up a preview mode](https://www.datocms.com/docs/react-router/setting-up-a-preview-mode.md)
- [Real-time updates](https://www.datocms.com/docs/react-router/real-time-updates.md)