KwadMarket Docs
Product Roadmap

Internationalization

FR + EN with next-intl — architecture and preparation steps

Priority: growth — decide early

The marketplace is French-only today and that's fine. But retrofitting i18n is painful — the zero-cost preparation steps below are worth following now, and the architecture decision (next-intl, subdirectory URLs) is made so nobody re-litigates it later.

Stack decision

LayerLibraryWhy
Frontendnext-intlBest Next.js App Router support, ICU message format
Backendnestjs-i18nAPI error messages, email templates
ContentTranslation JSON filesSimple, version-controlled

Frontend architecture

apps/web/
  messages/
    fr.json        # French translations (default)
    en.json        # English translations
  i18n/
    request.ts     # next-intl config
  app/
    [locale]/      # locale prefix in URL: /fr/deals, /en/deals
  middleware.ts    # locale detection from browser/cookie (extend existing)
apps/web/i18n/request.ts
import { getRequestConfig } from "next-intl/server";
export default getRequestConfig(async ({ locale }) => ({
  messages: (await import(`../messages/${locale}.json`)).default,
}));

URL strategy: subdirectory (/fr/deals, /en/deals) over subdomains — simpler, better SEO, single deployment.

What to translate

✅ UI labels, buttons, placeholders · form validation messages · toasts · error messages · email templates · legal pages (separate content per locale) · SEO metadata.

❌ User-generated content (deal titles, descriptions, chat) · product names, specs, categories — FPV terminology is universally English in the community ("frame", "motor", "ESC", "VTX").

Scope: ~200–300 translation keys for V1 — manageable manually, no Crowdin/Lokalise needed yet.

Preparation steps (now, zero effort)

  1. No hardcoded language-specific date formats — use Intl.DateTimeFormat / RelativeDate (already the convention).
  2. No hardcoded currency formatting — formatPrice() already uses Intl.NumberFormat correctly.
  3. Extract user-visible strings from new features into messages/fr.json as you build them — much cheaper than retroactive extraction.

Tasks

  • Install next-intl; create messages/fr.json + messages/en.json
  • Middleware locale detection; restructure routes under [locale]/
  • Replace hardcoded strings with useTranslations(); locale switcher (FR/EN) in header
  • nestjs-i18n for backend error messages; translate email templates
  • SEO: hreflang tags, localized metadata; legal pages per locale

On this page