{"version":3,"file":"client.cjs","names":["initReactI18next","I18nextProvider"],"sources":["../../src/appRouter/client.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { createInstance } from 'i18next'\nimport type { i18n as I18NextClient, Resource, FlatNamespace, KeyPrefix, Module } from 'i18next'\nimport {\n  I18nextProvider,\n  useTranslation,\n  type UseTranslationOptions,\n  type UseTranslationResponse,\n  type FallbackNs,\n} from 'react-i18next'\nimport { initReactI18next } from 'react-i18next/initReactI18next'\nimport resourcesToBackend from 'i18next-resources-to-backend'\nimport { useParams, useRouter } from 'next/navigation'\n\ntype $Tuple<T> = readonly [T?, ...T[]]\n\n// ---------------------------------------------------------------------------\n// I18nProvider\n// ---------------------------------------------------------------------------\n\nexport interface I18nProviderProps {\n  children: React.ReactNode\n  /** Current language (detected on the server, passed from layout) */\n  language: string\n  /** Server-loaded resources to hydrate the client instance */\n  resources?: Resource\n  /** All supported languages */\n  supportedLngs?: string[]\n  /** Default namespace */\n  defaultNS?: string\n  /** Fallback language */\n  fallbackLng?: string | string[] | Record<string, string[]>\n  /** Path to locale files (for lazy-loading additional namespaces on the client) */\n  localePath?: string\n  /** Locale file structure pattern */\n  localeStructure?: string\n  /** Locale file extension */\n  localeExtension?: string\n  /** Extra i18next plugins (e.g., i18next-http-backend, i18next-locize-backend) */\n  use?: any[]\n  /** Additional i18next init options */\n  i18nextOptions?: Record<string, any>\n}\n\n/**\n * Client-side i18next provider for App Router.\n * Creates an i18next instance hydrated with server-loaded resources,\n * with fallback dynamic loading for additional namespaces.\n *\n * Supports custom backends via the `use` prop — pass i18next-http-backend,\n * i18next-locize-backend, or i18next-chained-backend to load translations\n * from external sources.\n *\n * @example\n * ```tsx\n * // In app/[lng]/layout.tsx (Server Component)\n * import { I18nProvider } from 'next-i18next/client'\n * import { getT, getResources } from 'next-i18next/server'\n *\n * export default async function Layout({ children, params }) {\n *   const { lng } = await params\n *   const { i18n } = await getT()\n *   const resources = getResources(i18n, ['common'])\n *   return (\n *     <I18nProvider language={lng} resources={resources}>\n *       {children}\n *     </I18nProvider>\n *   )\n * }\n * ```\n */\nexport function I18nProvider({\n  children,\n  language,\n  resources,\n  supportedLngs,\n  defaultNS = 'common',\n  fallbackLng,\n  localePath = '/locales',\n  localeStructure = '{{lng}}/{{ns}}',\n  localeExtension = 'json',\n  use = [],\n  i18nextOptions = {},\n}: I18nProviderProps) {\n  const [instance] = useState<I18NextClient>(() => {\n    const inst = createInstance()\n    inst.use(initReactI18next)\n\n    const userHasBackend = use.some((b: Module) => b.type === 'backend')\n\n    // Track which namespaces are bundled in the server-provided resources\n    // so the default fetch backend can skip them\n    const bundledNsSet = resources\n      ? new Set(Object.values(resources).flatMap(r => Object.keys(r as Record<string, unknown>)))\n      : new Set<string>()\n    const bundledNs = bundledNsSet.size > 0 ? [...bundledNsSet] : [defaultNS]\n\n    // Only add the default fetch-based backend if user hasn't provided one.\n    // This allows using i18next-http-backend, i18next-locize-backend,\n    // i18next-chained-backend, etc.\n    if (!userHasBackend) {\n      inst.use(resourcesToBackend((lng: string, ns: string) => {\n        // Skip fetching for namespaces already provided via server resources\n        if (bundledNsSet.has(ns)) return {}\n        const path = `${localePath}/${localeStructure\n          .replace('{{lng}}', lng)\n          .replace('{{ns}}', ns)}.${localeExtension}`\n        return fetch(path).then(r => r.ok ? r.json() : {})\n      }))\n    }\n\n    // Apply user-provided plugins\n    use.forEach((plugin: any) => inst.use(plugin))\n\n    const hasAnyBackend = userHasBackend || !resources\n\n    inst.init({\n      lng: language,\n      resources,\n      ns: bundledNs,\n      partialBundledLanguages: hasAnyBackend,\n      defaultNS,\n      fallbackLng: fallbackLng ?? language,\n      supportedLngs: supportedLngs ?? (resources ? Object.keys(resources) : [language]),\n      fallbackNS: defaultNS,\n      interpolation: { escapeValue: false },\n      react: { useSuspense: false },\n      ...i18nextOptions,\n    })\n\n    return inst\n  })\n\n  // Sync language when the prop changes (e.g., after navigation)\n  useEffect(() => {\n    if (instance.language !== language) {\n      instance.changeLanguage(language)\n    }\n  }, [instance, language])\n\n  return (\n    <I18nextProvider i18n={instance}>\n      {children}\n    </I18nextProvider>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// useT — translation hook for Client Components\n// ---------------------------------------------------------------------------\n\n/**\n * Translation hook for Client Components in App Router.\n * Works in both locale-in-path and no-locale-path modes:\n * - Locale-in-path: reads language from URL params (`[lng]` or `[locale]`) and syncs\n * - No-locale-path: uses the language set by I18nProvider (from server detection)\n *\n * @example\n * ```tsx\n * 'use client'\n * import { useT } from 'next-i18next/client'\n *\n * export default function Counter() {\n *   const { t } = useT('home')\n *   return <p>{t('greeting')}</p>\n * }\n * ```\n */\nexport function useT<\n  Ns extends FlatNamespace | $Tuple<FlatNamespace> | undefined = undefined,\n  KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,\n>(\n  ns?: Ns,\n  options?: UseTranslationOptions<KPrefix>,\n): UseTranslationResponse<FallbackNs<Ns>, KPrefix> {\n  const params = useParams()\n  // Support both [lng] and [locale] param names\n  const lngFromParams = typeof params?.lng === 'string'\n    ? params.lng\n    : typeof params?.locale === 'string'\n      ? params.locale\n      : undefined\n  const ret = useTranslation(ns, options)\n\n  // Sync language from URL params (locale-in-path mode)\n  useEffect(() => {\n    if (lngFromParams && ret.i18n.resolvedLanguage !== lngFromParams) {\n      ret.i18n.changeLanguage(lngFromParams)\n    }\n  }, [lngFromParams, ret.i18n])\n\n  return ret\n}\n\n// ---------------------------------------------------------------------------\n// useChangeLanguage — for no-locale-path mode\n// ---------------------------------------------------------------------------\n\n/**\n * Hook for changing the language without URL navigation (no-locale-path mode).\n * Updates cookie + i18next instance + triggers server re-render via router.refresh().\n *\n * @example\n * ```tsx\n * 'use client'\n * import { useChangeLanguage } from 'next-i18next/client'\n *\n * export default function LanguageSwitcher() {\n *   const changeLanguage = useChangeLanguage()\n *   return <button onClick={() => changeLanguage('de')}>Deutsch</button>\n * }\n * ```\n */\nexport function useChangeLanguage(cookieName = 'i18next') {\n  const { i18n } = useTranslation()\n  const router = useRouter()\n\n  return useCallback(async (newLng: string) => {\n    document.cookie = `${cookieName}=${newLng};path=/;max-age=${365 * 24 * 60 * 60};SameSite=Lax`\n    await i18n.changeLanguage(newLng)\n    router.refresh()\n  }, [i18n, router, cookieName])\n}\n\n// Re-export useful react-i18next utilities for convenience\nexport { Trans } from 'react-i18next'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyEA,SAAgB,aAAa,EAC3B,UACA,UACA,WACA,eACA,YAAY,UACZ,aACA,aAAa,YACb,kBAAkB,kBAClB,kBAAkB,QAClB,MAAM,EAAE,EACR,iBAAiB,EAAE,IACC;CACpB,MAAM,CAAC,aAAA,GAAA,MAAA,gBAA0C;EAC/C,MAAM,QAAA,GAAA,QAAA,iBAAuB;AAC7B,OAAK,IAAIA,+BAAAA,iBAAiB;EAE1B,MAAM,iBAAiB,IAAI,MAAM,MAAc,EAAE,SAAS,UAAU;EAIpE,MAAM,eAAe,YACjB,IAAI,IAAI,OAAO,OAAO,UAAU,CAAC,SAAQ,MAAK,OAAO,KAAK,EAA6B,CAAC,CAAC,mBACzF,IAAI,KAAa;EACrB,MAAM,YAAY,aAAa,OAAO,IAAI,CAAC,GAAG,aAAa,GAAG,CAAC,UAAU;AAKzE,MAAI,CAAC,eACH,MAAK,KAAA,GAAA,6BAAA,UAAwB,KAAa,OAAe;AAEvD,OAAI,aAAa,IAAI,GAAG,CAAE,QAAO,EAAE;GACnC,MAAM,OAAO,GAAG,WAAW,GAAG,gBAC3B,QAAQ,WAAW,IAAI,CACvB,QAAQ,UAAU,GAAG,CAAC,GAAG;AAC5B,UAAO,MAAM,KAAK,CAAC,MAAK,MAAK,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC;IAClD,CAAC;AAIL,MAAI,SAAS,WAAgB,KAAK,IAAI,OAAO,CAAC;EAE9C,MAAM,gBAAgB,kBAAkB,CAAC;AAEzC,OAAK,KAAK;GACR,KAAK;GACL;GACA,IAAI;GACJ,yBAAyB;GACzB;GACA,aAAa,eAAe;GAC5B,eAAe,kBAAkB,YAAY,OAAO,KAAK,UAAU,GAAG,CAAC,SAAS;GAChF,YAAY;GACZ,eAAe,EAAE,aAAa,OAAO;GACrC,OAAO,EAAE,aAAa,OAAO;GAC7B,GAAG;GACJ,CAAC;AAEF,SAAO;GACP;AAGF,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,SAAS,aAAa,SACxB,UAAS,eAAe,SAAS;IAElC,CAAC,UAAU,SAAS,CAAC;AAExB,QACE,iBAAA,GAAA,kBAAA,KAACC,cAAAA,iBAAD;EAAiB,MAAM;EACpB;EACe,CAAA;;;;;;;;;;;;;;;;;;;AAyBtB,SAAgB,KAId,IACA,SACiD;CACjD,MAAM,UAAA,GAAA,gBAAA,YAAoB;CAE1B,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,WACzC,OAAO,MACP,OAAO,QAAQ,WAAW,WACxB,OAAO,SACP,KAAA;CACN,MAAM,OAAA,GAAA,cAAA,gBAAqB,IAAI,QAAQ;AAGvC,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,iBAAiB,IAAI,KAAK,qBAAqB,cACjD,KAAI,KAAK,eAAe,cAAc;IAEvC,CAAC,eAAe,IAAI,KAAK,CAAC;AAE7B,QAAO;;;;;;;;;;;;;;;;;AAsBT,SAAgB,kBAAkB,aAAa,WAAW;CACxD,MAAM,EAAE,UAAA,GAAA,cAAA,iBAAyB;CACjC,MAAM,UAAA,GAAA,gBAAA,YAAoB;AAE1B,SAAA,GAAA,MAAA,aAAmB,OAAO,WAAmB;AAC3C,WAAS,SAAS,GAAG,WAAW,GAAG,OAAO,kBAAkB,MAAM,KAAK,KAAK,GAAG;AAC/E,QAAM,KAAK,eAAe,OAAO;AACjC,SAAO,SAAS;IACf;EAAC;EAAM;EAAQ;EAAW,CAAC"}