> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fimo.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js

> Use Fimo in Next.js App Router and Pages Router projects.

Next.js projects use separate server and client Fimo surfaces. The application keeps its file-system routes, rendering policy, locale infrastructure, links, document metadata, and SEO.

Install `fimo-next` and `fimo-react` alongside `fimo` at the same version:

```bash theme={null}
npm install fimo fimo-react fimo-next
```

## Configure the runtime

```json theme={null}
{
  "runtime": { "framework": "nextjs" }
}
```

Next.js owns its route output and 404 behavior, so it needs no catch-all rewrite.

## Connect the application

Render `FimoProvider` once at the application root. It resolves the connection to your Fimo project on the server, hands only the public connection (tenant content URL, Branch, optional preview script) to the browser, and supplies React Query, labels, and the Studio preview script to everything below it. You do not create, copy, or read Fimo runtime environment variables.

* Locally, the connection comes from the linked project (`.fimo/project.json`) and the active git branch, so `git checkout` switches Branches.
* Hosted previews and production builds receive it from the platform.
* To point the app at another host, set `FIMO_CONTENT_API_URL` (and optionally `FIMO_ENV`); an explicit value always wins over derivation.

`withFimo` in `next.config` only adds the hosted preview origins to `next dev`; it is not the application's connection.

## Generate content clients

Create `src/schemas/<Uid>.json` and run `fimo schemas push <Uid>`. Fimo generates:

* `<Uid>.ts` for server reads and serialization;
* `<Uid>.client.ts` for React Query hooks and hydration;
* `<Uid>.types.ts` as an internal shared type module;
* `index.ts` as the generated content registry.

Server Components and data functions use `fimo-next` plus generated server modules. Client Components use `fimo-next/client` plus generated `.client.ts` modules. Do not import client modules into server-only code.

## App Router

Wrap the root layout with `FimoProvider` from `fimo-next`. It is a Server Component, so no page, route, or component receives a runtime prop:

```tsx theme={null}
import { FimoProvider, getLabels } from 'fimo-next';

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const labels = await getLabels({ locale: 'en' });

  return (
    <html lang="en">
      <body>
        <FimoProvider labels={labels.snapshot}>{children}</FimoProvider>
      </body>
    </html>
  );
}
```

Server Components can read and render tracked values directly:

```tsx theme={null}
import { getLabels, Text } from 'fimo-next';
import * as Article from '@/schemas/Article';

export default async function Page() {
  const [articles, labels] = await Promise.all([Article.list({ limit: 12 }), getLabels({ locale: 'en' })]);

  return <Text value={labels.t('articles.title')} as="h1" />;
}
```

Client Components use generated `.client` hooks and `useLabels` from `fimo-next/client` under that provider. `fimo-next` requires `@tanstack/react-query` as a peer dependency.

`FimoProvider` also owns the optional Studio preview runtime. Application code does not add a preview bridge, read Fimo preview environment variables, or inject a preview script.

## Pages Router

Wrap the root in `pages/_app.tsx` with `FimoProvider` from `fimo-next/client`. Pages Router has no Server Component above `_app`, so this provider resolves the connection while the server renders `_app` and writes it into the document for the browser:

```tsx theme={null}
import { FimoProvider, type LabelsSnapshot } from 'fimo-next/client';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps<{ fimoLabels?: LabelsSnapshot }>) {
  return (
    <FimoProvider labels={pageProps.fimoLabels}>
      <Component {...pageProps} />
    </FimoProvider>
  );
}
```

`getStaticProps` and `getServerSideProps` must return plain JSON. Serialize tracked content before returning props, then hydrate it with the generated client module:

```tsx theme={null}
import * as Article from '@/schemas/Article';
import * as ArticleClient from '@/schemas/Article.client';
import { Text } from 'fimo-next/client';
import type { GetStaticProps, InferGetStaticPropsType } from 'next';

export const getStaticProps = (async () => {
  const result = await Article.list({ limit: 1 });
  const article = result.items[0];
  if (!article) return { notFound: true };

  return { props: { article: Article.serialize(article) }, revalidate: 60 };
}) satisfies GetStaticProps;

export default function Page({ article: data }: InferGetStaticPropsType<typeof getStaticProps>) {
  const article = ArticleClient.hydrate(data);
  return <Text value={article.title} as="h1" />;
}
```

Use the same pair with `getServerSideProps`. Static slug routes list slugs in `getStaticPaths` and load entries with `getBySlug()`.

<Card title="Labels and locales" icon="globe" href="/docs/cli/locales">
  Pass the locale already resolved by the Next.js application into Fimo reads and providers.
</Card>
