UNPKG

next-i18next

Version:

The easiest way to translate your NextJs apps.

165 lines (164 loc) 6.21 kB
'use client'; "use client"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion let react = require("react"); react = __toESM(react); let i18next = require("i18next"); let react_i18next = require("react-i18next"); let react_i18next_initReactI18next = require("react-i18next/initReactI18next"); let i18next_resources_to_backend = require("i18next-resources-to-backend"); i18next_resources_to_backend = __toESM(i18next_resources_to_backend); let next_navigation = require("next/navigation"); let react_jsx_runtime = require("react/jsx-runtime"); //#region src/appRouter/client.tsx /** * Client-side i18next provider for App Router. * Creates an i18next instance hydrated with server-loaded resources, * with fallback dynamic loading for additional namespaces. * * Supports custom backends via the `use` prop — pass i18next-http-backend, * i18next-locize-backend, or i18next-chained-backend to load translations * from external sources. * * @example * ```tsx * // In app/[lng]/layout.tsx (Server Component) * import { I18nProvider } from 'next-i18next/client' * import { getT, getResources } from 'next-i18next/server' * * export default async function Layout({ children, params }) { * const { lng } = await params * const { i18n } = await getT() * const resources = getResources(i18n, ['common']) * return ( * <I18nProvider language={lng} resources={resources}> * {children} * </I18nProvider> * ) * } * ``` */ function I18nProvider({ children, language, resources, supportedLngs, defaultNS = "common", fallbackLng, localePath = "/locales", localeStructure = "{{lng}}/{{ns}}", localeExtension = "json", use = [], i18nextOptions = {} }) { const [instance] = (0, react.useState)(() => { const inst = (0, i18next.createInstance)(); inst.use(react_i18next_initReactI18next.initReactI18next); const userHasBackend = use.some((b) => b.type === "backend"); const bundledNsSet = resources ? new Set(Object.values(resources).flatMap((r) => Object.keys(r))) : /* @__PURE__ */ new Set(); const bundledNs = bundledNsSet.size > 0 ? [...bundledNsSet] : [defaultNS]; if (!userHasBackend) inst.use((0, i18next_resources_to_backend.default)((lng, ns) => { if (bundledNsSet.has(ns)) return {}; const path = `${localePath}/${localeStructure.replace("{{lng}}", lng).replace("{{ns}}", ns)}.${localeExtension}`; return fetch(path).then((r) => r.ok ? r.json() : {}); })); use.forEach((plugin) => inst.use(plugin)); const hasAnyBackend = userHasBackend || !resources; inst.init({ lng: language, resources, ns: bundledNs, partialBundledLanguages: hasAnyBackend, defaultNS, fallbackLng: fallbackLng ?? language, supportedLngs: supportedLngs ?? (resources ? Object.keys(resources) : [language]), fallbackNS: defaultNS, interpolation: { escapeValue: false }, react: { useSuspense: false }, ...i18nextOptions }); return inst; }); (0, react.useEffect)(() => { if (instance.language !== language) instance.changeLanguage(language); }, [instance, language]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_i18next.I18nextProvider, { i18n: instance, children }); } /** * Translation hook for Client Components in App Router. * Works in both locale-in-path and no-locale-path modes: * - Locale-in-path: reads language from URL params (`[lng]` or `[locale]`) and syncs * - No-locale-path: uses the language set by I18nProvider (from server detection) * * @example * ```tsx * 'use client' * import { useT } from 'next-i18next/client' * * export default function Counter() { * const { t } = useT('home') * return <p>{t('greeting')}</p> * } * ``` */ function useT(ns, options) { const params = (0, next_navigation.useParams)(); const lngFromParams = typeof params?.lng === "string" ? params.lng : typeof params?.locale === "string" ? params.locale : void 0; const ret = (0, react_i18next.useTranslation)(ns, options); (0, react.useEffect)(() => { if (lngFromParams && ret.i18n.resolvedLanguage !== lngFromParams) ret.i18n.changeLanguage(lngFromParams); }, [lngFromParams, ret.i18n]); return ret; } /** * Hook for changing the language without URL navigation (no-locale-path mode). * Updates cookie + i18next instance + triggers server re-render via router.refresh(). * * @example * ```tsx * 'use client' * import { useChangeLanguage } from 'next-i18next/client' * * export default function LanguageSwitcher() { * const changeLanguage = useChangeLanguage() * return <button onClick={() => changeLanguage('de')}>Deutsch</button> * } * ``` */ function useChangeLanguage(cookieName = "i18next") { const { i18n } = (0, react_i18next.useTranslation)(); const router = (0, next_navigation.useRouter)(); return (0, react.useCallback)(async (newLng) => { document.cookie = `${cookieName}=${newLng};path=/;max-age=${365 * 24 * 60 * 60};SameSite=Lax`; await i18n.changeLanguage(newLng); router.refresh(); }, [ i18n, router, cookieName ]); } //#endregion exports.I18nProvider = I18nProvider; Object.defineProperty(exports, "Trans", { enumerable: true, get: function() { return react_i18next.Trans; } }); exports.useChangeLanguage = useChangeLanguage; exports.useT = useT; //# sourceMappingURL=client.cjs.map