ShipNext

Internationalization

Understand app locale routing, copy loading, language switching, SEO, and the docs-only language switch.

ShipNext has two different language concerns:

  • Product and marketing pages can use route-aware locale behavior.
  • The docs use an in-page language switch at the bottom of docs pages. Docs URLs do not include locale prefixes.

Docs language behavior

Docs currently support:

LocaleNameURL behavior
enEnglishDefault docs language
zhChineseSame /docs/... URL, selected through the docs switcher

The selected docs language is stored in both:

  • localStorage: shipnext-docs-locale
  • cookie: shipnext-docs-locale

The cookie lets the server render the selected language on the first paint. localStorage keeps the browser preference and can resync the cookie if needed.

Product locale routing

If the full app uses route-based i18n, the typical pattern is:

export const i18nConfig = {
  defaultLocale: "en",
  locales: {
    en: { flag: "US", name: "English", hreflang: "en" },
    zh: { flag: "CN", name: "Chinese", hreflang: "zh-CN" },
  },
  localePrefix: "as-needed",
} as const;

Default-language pages should avoid /en prefixes, while non-default languages may use prefixes such as /zh.

Docs content structure

Docs content is stored by locale:

content/docs/
├── en/
│   ├── meta.json
│   └── ...
└── zh/
    ├── meta.json
    └── ...

Both locale trees keep the same slugs. That means /docs/getting-started/installation can render either English or Chinese without changing the URL.

Copy loading

If product pages use JSON message files, keep the same keys in every locale:

src/i18n/messages/
├── en/
│   ├── common.json
│   └── ...
└── zh/
    ├── common.json
    └── ...

New namespaces must be registered in the request loader before components can read them.

For route-aware product pages, prefer locale-aware navigation helpers where available:

import { Link, useRouter } from "@/i18n/navigation";

For docs language switching, do not push a new URL. Update storage/cookie and refresh the current route.

SEO

  • Product pages should generate canonical URLs and alternate languages based on app routing.
  • Docs pages should not generate separate /en/docs or /zh/docs routes.
  • Docs frontmatter still provides page title and description.

Adding a new product language

  1. Add the locale to the product i18n config.
  2. Copy and translate all JSON message namespaces.
  3. Register any new namespace in the request loader.
  4. Add content for docs only if docs should support the new language.
  5. Verify canonical and alternate metadata.

Adding a new docs language

  1. Add the language to the docs i18n config.
  2. Add content/docs/<locale>/** with the same slugs as other docs languages.
  3. Add the language option to the docs language switcher.
  4. Ensure the cookie/localStorage validation accepts the new locale.
  5. Verify search indexes include the new locale.

Checklist

  • Docs language switching never changes the URL.
  • Docs content exists for each supported docs locale.
  • Product locale routing does not affect /docs.
  • Search filters by the selected docs language.
  • Server render uses the docs language cookie.

On this page