CoreMVP

Internationalization

Use the saved English/French dashboard language and extend its messages, or enable the separate public-page showcase.

Choose Français from the actual dashboard's language menu to translate its interface. The language survives dashboard navigation and reloads without changing /dashboard/** URLs. English is the default when this browser has no saved choice. The shared demo at /demo/dashboard has the same menu and uses sample data.

To make the dashboard English-only or uninstall the translation runtime, use Disable or Remove i18n. The guide includes every edit point, verification, and instructions for your coding agent.

Translate your dashboard components

The translation setup is already connected:

  • src/i18n/config.ts lists languages and their menu names.
  • src/i18n/messages/en.json and fr.json contain the interface text.
  • src/i18n/request.ts reads the validated browser preference and loads its language's messages for server rendering.
  • src/app/dashboard/layout.tsx supplies the same language and messages to DashboardI18nProvider, so interactive components can read them too.

For an async Server Component, import getTranslations and getLocale from next-intl/server. For a Client Component, import useTranslations and useLocale from next-intl. Use the existing dashboard layout as the client provider boundary. The complete dashboard component example connects message files, a server heading, a client counter, and the page that renders them. The next-intl server/client reference explains the two APIs.

The language menu calls the Server Action in src/i18n/actions.ts. It saves coremvp_dashboard_locale as a validated, HttpOnly browser cookie for one year, with SameSite=Lax and Secure in production. Server rendering reads that cookie; client components read the provider instead of document.cookie. Changing language refreshes the current page's translations. Another browser or device starts in English; the preference is not a database account field.

Add a dashboard language

For Spanish, copy the complete existing catalog from the template root:

cp src/i18n/messages/en.json src/i18n/messages/es.json

Translate the string values in es.json, retaining every key, interpolation placeholder, plural branch, and rich-text tag. Then add "es" to dashboardLocales and es: "Español" to dashboardLocaleNames in src/i18n/config.ts. Keep English as the default. The selector, validation, and request loader read that shared list and matching file name; no new URL prefix, environment variable, provider, or database column is needed.

Follow Add a Language for the exact configuration edit and visible checkpoints. Run the normal unit checks after catalog edits, then the focused local dashboard browser check:

bun run test
./coremvp e2e dashboard:i18n

Keep your normal local app and Supabase running for the browser check. It uses a temporary local account and checks saved English/French selection in the actual dashboard and the shared demo pages. New languages need your own translation review and browser checks; passing catalog syntax checks does not prove their wording or every screen state.

Keep public content separate

The saved preference translates the dashboard interface. Public landing, pricing, Auth, Docs, and Blog pages retain their current language. The landing page's embedded dashboard preview also stays English. Database content, user names, provider messages, Stripe amounts/currencies, permissions, and access state retain their existing values.

For a new public page with a distinct URL per language, the complete optional page example uses separate catalogs and explicit URL locales. Translating existing MDX articles requires translated source files as well as interface messages.

Run the optional showcase

The separate examples/i18n showcase demonstrates translated Overview, Landing, Pricing, Dashboard, and Documentation previews. It is disabled by default. Its activation switch enables only /i18n/**; the actual dashboard language menu works independently.

Start from a template checkout with dependencies installed and Docker running.

Enable internationalization

./coremvp feature enable i18n

This command changes only examples/i18n/config.json. Run ./coremvp feature status i18n at any time to inspect the feature state.

Start the normal local dependencies

bunx supabase start
./coremvp env sync

The showcase uses the same supported local runtime as the rest of the template. It does not add another app or deployment.

Start the app

bun run dev

Open http://localhost:3000/i18n. Use the language select to switch between English and French while staying on the same preview page.

Test the complete example

Keep the app running, then use another terminal:

./coremvp e2e i18n

The focused browser test checks the English-default routes, French content, locale-aware formatting, invalid-route boundaries, and unchanged sibling routes.

Customize the example

All editable example code stays together:

config.json
showcase-router.tsx

Edit the message catalogs for interface copy. Edit the two MDX files for the documentation preview. The example components and pages show how a route-local next-intl translator, locale-preserving links, and Intl formatting fit together.

The default English URLs do not include a locale segment:

PreviewEnglishFrench
Overview/i18n/i18n/fr
Landing/i18n/landing/i18n/fr/landing
Pricing/i18n/pricing/i18n/fr/pricing
Dashboard/i18n/dashboard/i18n/fr/dashboard
Documentation preview/i18n/documentation/i18n/fr/documentation

Keep the showcase independent

This optional showcase reads explicit URL locales, rather than the saved dashboard preference. It has a fixed English/French pair, separate message catalogs, and separate MDX sources. Dashboard catalog edits do not add showcase routes. Its pages emit noindex, have no canonical or hreflang links, and stay out of the sitemap.

Neither the showcase nor a translated dashboard changes Supabase Auth, Stripe prices, billing, tax, or access state. Use the showcase to inspect public-page and MDX patterns; define the languages, content, routing, and search metadata separately for public pages you add.

Was this page helpful?

On this page