Skip to content
Projects

Next.js i18n Starter

An open-source Next.js 16 starter for multilingual apps: five locales, Arabic RTL, locale-aware formatting, and SEO metadata for every language.

Since May 2024 · 66 stars · 13 forks

The starter’s demo page in English, with installation steps beside the title
English
The same demo page in Arabic, with the whole layout mirrored right to left
Arabic, mirrored right to left

Most i18n examples stop at swapping strings. This starter covers what comes after: right-to-left layouts, dates and numbers that follow the reader’s locale, and search engines that can find every language version of a page.

What’s in it

  • English, Arabic, Chinese, Spanish, and Japanese, with English served at / and the others under /{locale}.
  • Automatic dir="rtl" for Arabic, plus an OmitRTL helper for pieces that must stay left-to-right, like code and phone numbers.
  • Currency, dates, compact numbers, and relative time formatted per locale through next-intl.
  • Canonical URLs, hreflang alternates, a sitemap, robots rules, JSON-LD, and an OG image for every locale.
  • Light and dark themes read from a cookie on the server, so the first paint uses the right theme.
  • A ten-minute guide that traces one request end to end, with exercises that break things on purpose so you can see what the checks catch.
  • Agent skills that teach coding assistants the project’s conventions.

Five things that must agree

Every i18n bug is one of these five disagreeing with another, so the starter keeps each in one place:

ThingWhere it livesHow it goes wrong
The URLrouting.ts, proxy.tsJapanese pages live at /jp while the language code is ja
The page language<html lang dir> in the locale layoutArabic renders left to right
The textdictionary/*.jsonA key exists in English and is missing in Arabic
The navigationi18n/navigation.tsA link drops the /ja prefix
The formattingrequest.ts, regional.tsA price shows dollars on the Spanish page

Checks catch the rest. bun run i18n:check validates the locale registry and confirms every dictionary mirrors English: keys, ICU arguments, rich-text tags, and plural branches. bun run seo:verify checks hreflang reciprocity, canonicals, lang, JSON-LD, and sitemap agreement on a running site.

Decisions worth noting

The locale comes from next/root-params. Earlier versions called setRequestLocale in every page. next-intl deprecated it, and reading the locale from the root params removed that boilerplate from every route.

A nonce-based Content Security Policy. The proxy (Next.js 16’s replacement for middleware) generates a fresh nonce for each request, so inline scripts are allowed only when the server put them there.

No automatic locale detection. Cookies and the browser’s language never redirect the default URL, so / always serves English and every language has one stable address for search engines.

shadcn/ui on Base UI. The components moved from Radix to Base UI in the base-nova style. Base UI reads text direction from a provider, so menus and tabs follow the locale’s direction.

A UI audit for RTL and CJK. A dedicated pass fixed accessibility issues and typography problems in Arabic, Chinese, and Japanese that Latin-first defaults miss.

Status

Maintained since May 2024 and kept current with Next.js releases; it runs on Next.js 16.3.8.

Built with Next.js 16, React 19, next-intl 4, TypeScript, Tailwind CSS 4, shadcn/ui.