All posts
Platform migrations

Next.js Internationalization for Migrated Marketing Sites

Next.js i18n migration for marketing sites: locale routing in the App Router, CMS locale fields, and generating hreflang and sitemaps from one locale config.

By Mehdi Hassan7 min read

The short answer

A Next.js i18n migration sets up localization in three layers: a locale segment in the URL handled by the App Router, localized fields in your headless CMS, and hreflang plus sitemaps generated from the same locale list. Define locales once in config, read them everywhere, and keep old translated URLs identical or redirected.

Key takeaways

  • In the App Router, locales are a dynamic route segment such as app/[locale], not a next.config setting.
  • Keep one locale config file and generate routes, hreflang and sitemaps from it so nothing drifts.
  • Choose field-level or document-level localization in the CMS based on how different each locale's pages are.
  • Use generateMetadata alternates for hreflang and add language alternates to sitemap entries.
  • Map translated slugs from the old platform before you build, so routes match the URLs that already rank.

Part of Migrating a Multilingual Website: Platforms, URLs and Translation Tools

What does a nextjs i18n migration involve?

A Next.js i18n migration takes a multilingual site from a builder or WordPress and rebuilds its locales in code. You design the URL structure as routes, store translations as localized CMS fields, and generate hreflang and sitemaps yourself. Nothing is automatic, which is both the cost and the benefit.

Teams move multilingual marketing sites to Next.js when per-locale fees, CMS limits or editing workflows on builders get in the way. You pay with developer time instead of a per-locale subscription. Before choosing this route, read the multilingual website migration playbook, which covers URL strategy and translation exports that apply to every destination, and compare it with Webflow Localization, Framer Localization and Weglot.

How does locale routing work in the Next.js App Router?

In the App Router, locale routing is a dynamic segment at the top of your app folder, usually app/[locale]/, plus a small piece of request-time code that detects or enforces the locale. The Pages Router had a built-in i18n setting in next.config; the App Router doesn't, so you build routing explicitly or use a library.

  • Route segment. Every page lives under app/[locale]/, so /de/pricing and /fr/pricing render the same component with a different locale.
  • Static params. generateStaticParams returns each locale, and each slug per locale for CMS pages, so pages are pre-rendered.
  • Locale detection. Middleware, renamed proxy in Next.js 16, can redirect the root path to a default locale or read the Accept-Language header. Keep detection to the root path, and never force-redirect search engines away from a URL they requested.
  • Default locale prefix. Decide whether English lives at / or /en/. Matching what your old site did avoids redirecting your strongest pages.
  • Libraries. Libraries such as next-intl handle routing, message files and formatting, which saves time on sites with UI strings in many components.

How should you structure CMS locale fields?

Use field-level localization when every locale has the same page structure with translated text, and document-level localization when locales need different sections, offers or pages. Most marketing sites are mostly field-level, with a few locale-only documents.

Approach

How it works

Best for

Trade-off

Field-level

One document, each field has a value per locale

Same layout in every language

Hard to vary structure by market

Document-level

A separate document per locale, linked together

Different pages or offers per market

More documents to keep in sync

Hybrid

Field-level by default, document-level for a few page types

Most marketing sites

Needs clear rules for editors

Payload, Contentful and Strapi support field-level localization natively, and Sanity supports both patterns through its internationalization tooling. Whichever CMS you pick, localize the slug and SEO fields as well as the body, and add a fallback rule for missing translations so a half-translated page doesn't render blanks. Our notes on setting up Payload CMS for a marketing site cover the localization config we use in production.

For example, suppose a pricing page differs by market

Hypothetical example: a SaaS company sells the same plans in English and German, but the German pricing page needs a VAT note and a different FAQ.

With field-level localization, the pricing document has localized plan descriptions and FAQ fields, and a German-only rich-text field for the VAT note that renders only when present. With document-level localization, there are two pricing documents linked as translations. The field-level version keeps plan names and prices in one place, which avoids the classic bug where a price changes in English but not in German. Use document-level only when the pages are genuinely different.

How do you generate hreflang in Next.js?

Generate hreflang from the same locale config and CMS slugs that build your routes. In the App Router, the alternates field returned by generateMetadata renders hreflang link tags, and sitemap entries can carry language alternates too. One source of truth means a new locale shows up in routes, tags and sitemaps together.

  1. Fetch every locale's slug for the page

    When rendering a CMS page, query the slug for each locale in the same request, not just the current one.

  2. Return alternates in generateMetadata

    Set a self-referencing canonical and a languages map from locale code to absolute URL, including x-default.

  3. Skip missing locales

    If a page has no German version, leave German out of its alternates rather than pointing at a fallback or a 404.

  4. Add alternates to the sitemap

    In sitemap generation, give each URL its language alternates so search engines see the same relationships as in the HTML.

  5. Test with a crawler

    Crawl a preview deployment and check for missing return tags, relative URLs and alternates that point at redirects.

Google's documentation on localized versions of your pages is the reference for what valid annotations look like. For a deeper Next.js treatment of routing and content, see our guide to multilingual Next.js sites and i18n routing.

How do you migrate translated content and URLs into Next.js?

Export each locale from the old platform, reshape it into your CMS's locale model, and import with a script. Then build redirects in next.config or at the edge for any URL that changed. The order is content model, import, routes, redirects.

Where the content comes from changes the export work. Webflow and Framer export CMS collections but leave static page translations to be copied. WPML and Polylang store each translation as a linked post, so you need the translation group in your export, which our WPML and Polylang migration guide explains. Weglot keeps translations in its own database, covered in the Weglot to Webflow guide, and the export step is the same for a Next.js destination.

Is Next.js the right platform for a multilingual marketing site?

Next.js is the right platform when you run many locales, need market-specific logic or want to avoid per-locale fees, and you have developers available to maintain it. It's the wrong platform when a small marketing team needs to ship new pages in every language without engineering help.

Pros

  • No per-locale platform fee; adding a language is config plus translation.
  • Full control over URLs, hreflang, fallbacks and market-specific content.
  • Works with any headless CMS and any translation workflow or vendor.

Cons

  • Developers own routing, metadata and redirects, so changes need engineering time.
  • Framework updates must be tested across every locale; see [keeping a Next.js site healthy](/blog/next-js-maintenance).
  • Marketers depend on the CMS's editing experience, which varies widely.

If engineering time is the bottleneck, the reverse move can make sense. Our guides to Next.js to Framer and Next.js to Webflow explain when handing a multilingual site back to marketing is the better choice.

Frequently asked questions

Does the Next.js App Router support i18n out of the box?
Not as a config option. The Pages Router had a built-in i18n setting, but the App Router expects you to add a locale route segment and handle detection yourself, or use a library such as next-intl. That gives you more control over URLs and fallbacks, at the cost of a little more setup in the first week of the build.
Should the default language have a prefix like /en/?
Match what your current site does. If English lives at the root today, keep it there so your strongest URLs don't change. A prefix for every locale is cleaner in code, but adding it during a migration means redirecting every English page. If you're starting fresh with no rankings, either choice works; pick one and keep it.
Which headless CMS is best for a multilingual Next.js site?
Most mainstream headless CMSs handle localization well, including Payload, Sanity, Contentful and Strapi. Choose on editing experience, hosting model and how each one handles field-level versus document-level localization. Test with a real page in two languages, including a locale-only section, before committing, because editor workflow matters more than feature lists.
Can I auto-redirect visitors based on browser language?
You can, but do it carefully. Redirecting only the bare root path to a preferred locale is generally fine. Redirecting every URL based on the Accept-Language header can stop search engines and users from reaching the page they asked for. A visible language switcher plus a gentle suggestion banner is usually the better experience.
How do translated slugs work with Next.js routes?
Store a localized slug field in the CMS and resolve the page by locale and slug in the route. generateStaticParams returns every locale and slug pair so pages pre-render. Your hreflang alternates then use each locale's own slug, so /de/preise and /pricing point at each other correctly.

· CEO & Design Director

Copywriter, designer and developer, and founder of Designify Studio. Over five years, 60+ projects across 14+ industries, for startups that have raised $300M+.

Want this done for you? Website, $8,000.

A multi-page marketing site, designed by us, developed in Next.js and animated. $8,000, one-time, up to 6 pages. Book a free 30-minute call to see if it fits.

Schedule Call