i18n
Vite/React uses i18next. Next uses next-intl. Sections below are separate — do not mix APIs.
Defaults to No. When enabled, Dose injects a stack-native setup. Use only the section that matches your project.
Vite SPA & React Router
Libraries: i18next + react-i18next. Locale is not in the URL. Persist via localStorage.lang.
Files injected
src/i18n/index.ts
src/i18n/locales/en.json
src/i18n/locales/ar.json
src/hooks/useLocale.ts
src/i18n/i18next.d.ts # TypeScript onlyWhat we wire
RootProvider→<I18nextProvider i18n={i18n}>- Entry imports
@/i18nfrommain.*(SPA) orroot.*(Router) - Locales
en/ar, fallbacken
Helper hook — useLocale
import { useLocale } from "@/hooks/useLocale";
export function LanguageSwitcher() {
const { t, changeLanguage, currentLanguage } = useLocale();
return (
<div>
<p>{t("welcome")}</p>
<p>Current: {currentLanguage}</p>
<button type="button" onClick={() => changeLanguage("ar")}>
العربية
</button>
<button type="button" onClick={() => changeLanguage("en")}>
English
</button>
</div>
);
}changeLanguage writes localStorage.lang then calls i18n.changeLanguage. Add keys under src/i18n/locales/*.json. You can also use useTranslation() from react-i18next.
Next.js App Router
Library: next-intl. Locales live in the URL (/en/..., /ar/...). Do not use the Vite useLocale hook here.
Files injected
messages/en.json
messages/ar.json
src/i18n/routing.ts
src/i18n/navigation.ts
src/i18n/request.ts
src/proxy.ts
src/app/layout.tsx
src/app/page.tsx
src/app/[locale]/layout.tsx
src/app/[locale]/page.tsx
next.config.tsWhat we wire
[locale]/layoutwrapsNextIntlClientProviderviaRootProvider- Root
/redirects to/{locale} htmlgetslang+dir(ar→ RTL)next.configusescreateNextIntlPlugin()
Navigation — use @/i18n/navigation
import { Link, useRouter, usePathname } from "@/i18n/navigation";
export function NavLink() {
const pathname = usePathname();
const router = useRouter();
return (
<>
<Link href="/about">About</Link>
<button type="button" onClick={() => router.push("/contact")}>
Contact ({pathname})
</button>
</>
);
}Prefer these helpers over next/link and next/navigation so the active locale stays in the URL.
Translations — next-intl APIs
import { useTranslations, useLocale } from "next-intl";
export function Welcome() {
const t = useTranslations();
const locale = useLocale();
return (
<p>
{t("welcome")} — {locale}
</p>
);
}Add messages in messages/en.json and messages/ar.json. Server layouts use getMessages / setRequestLocale as in the generated [locale]/layout.