Skip to main content
Next.js projects use separate server and client Fimo surfaces. The application keeps its file-system routes, rendering policy, locale infrastructure, links, and per-page metadata overrides; Fimo supplies content, labels, editing context, and the site-wide SEO defaults from Studio’s SEO settings. New Fimo projects pin Next.js to 16.4.2, which includes the stable fix for Pages Router development hydration. Existing projects keep their installed Next.js version until you update it. Install fimo-next and fimo-react alongside fimo at the same version:

Configure the runtime

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 site 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 site (.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 adds the hosted preview origins to next dev. If you do not set Next.js’s devIndicators, Fimo hides it in hosted Previews while local next dev keeps Next’s default. Any explicit devIndicators setting is preserved:
The wrapper is not the application’s Fimo 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:
Server Components can read and render tracked values directly:
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.

SEO values and routes

The App Router starter reads global values from SEO settings in the root layout and converts them to Next’s native exports:
No pathname means global values only. Read an explicit pathname in a page to apply its configured route SEO, including Home:
Dynamic pages pass their real pathname and the content used by SEO templates:
One dynamic route module covers all its slugs. Add a route’s generateViewport only when its theme color differs; otherwise it inherits the root color. {{article.title}} uses the supplied content. Missing or empty template values fall back for the entire field to the global value. Set global values at seo and route overrides at routes.<id>.seo in your existing Fimo config (normally .fimo/config.json), preserving other keys:
toNextMetadata maps title, description, site name, site base URL, share image, favicon, Twitter account, robots and social locale. toNextViewport maps theme color, which Next renders separately from metadata. The converters are pure and accept FimoSEO from fimo/seo. Missing SEO produces an empty object. The Node reader uses Fimo’s current or legacy config file, with optional rootDir for monorepos. Invalid JSON and read failures other than a missing file throw. Static output needs a rebuild after config changes; cached routes follow your app’s revalidation policy. Fetched content can stay cached across builds, so use your data-cache invalidation policy and check the rendered value after a content edit. For Edge or bundled config, use resolveSeoForPath(pathname, publicSeoConfig, routeData) from fimo/seo and pass its result to the same converters. Include the selected config in your server deployment when using a custom config location. An Edge page’s ancestor layouts must also use Edge-safe data, not the Node reader.
Next replaces nested metadata objects such as openGraph and alternates; it does not merge them field by field. Existing apps should adopt only chosen Fimo fields and preserve section policies, generated social images, icons and existing SEO integrations. Do not spread every global default into a leaf.
Next derives social titles/descriptions and Twitter images from the final page metadata when those fields are unset. Keep one title-suffix owner; use Next’s absolute title form when a Fimo template already includes the full suffix. Next’s layout title template does not apply to a page in that same segment; give Home a complete title if it needs the same suffix. Canonical URLs use the current route relative to the configured site base. Custom canonical rules, hreflang, sitemaps and robots.txt remain yours. When the SEO settings have a site name and URL, the starter’s root layout also renders the site’s Organization and WebSite JSON-LD. buildSiteSchemas returns nothing until both are set; serializeJsonLd escapes the JSON for a script tag:
Page-specific JSON-LD, such as Article or Product, remains yours. Existing buildFimoMetadata(rootDir?) and buildFimoViewport(rootDir?) calls from fimo-next remain supported for global defaults. Their argument is a directory, not a route.

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:
getStaticProps and getServerSideProps must return plain JSON. Serialize tracked content before returning props, then hydrate it with the generated client module:
Use the same pair with getServerSideProps. Static slug routes list slugs in getStaticPaths and load entries with getBySlug().

Labels and locales

Pass the locale already resolved by the Next.js application into Fimo reads and providers.