घरसैंडबॉक्सशोकेसएप्पडॉकब्लॉग
    • Englishअंग्रेज़ी
      EN
    • русскийरूसी
      RU
    • 日本語जापानी
      JA
    • françaisफ़्रेंच
      FR
    • 한국어कोरियाई
      KO
    • 中文चीनी
      ZH
    • españolस्पेनिश
      ES
    • Deutschजर्मन
      DE
    • العربيةअरबी
      AR
    • italianoइतालवी
      IT
    • British Englishब्रिटिश अंग्रेज़ी
      EN-GB
    • portuguêsपुर्तगाली
      PT
    • हिन्दीहिन्दी
      HI
    • Türkçeतुर्की
      TR
    • polskiपोलिश
      PL
    • Indonesiaइंडोनेशियाई
      ID
    • Tiếng Việtवियतनामी
      VI
    • українськаयूक्रेनियाई
      UK
    /
    फ्रेमवर्क द्वारा डॉक्स फ़िल्टर करें
    Alt+←
    Intlayer का क्यों लाभ
    शुरू करें
    अवधारणा
    • Intlayer कैसे काम करता है
    • कॉन्फ़िगरेशन
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • विज़ुअल एडिटर
    • CMS
    • CI/CD एकीकरण
    • अनुवादबहुवचनगणनाशर्तलिंगसम्मिलनफ़ाइलनेस्टिंगMarkdownHTMLफ़ंक्शन फेचिंग
    • प्रति लोकेल फ़ाइल
    • कंपाइलर
    • स्वतः भरण
    • परीक्षण
    • बंडल ऑप्टिमाइज़ेशन
    पर्यावरण
    • Next.js 14 और ऐप राउटर
      Next.js 15
      Next.js बिना लोकेल URL
      Next.js और पेज राउटर
      कंपाइलर
    • Tanstack Start Solid
    • Astro और React
      Astro और Svelte
      Astro और Vue
      Astro और Solid
      Astro और Preact
      Astro और Lit
      Astro और Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt और Vue
    • Vite और Solid
    • SvelteKit
    • Vite और Preact
    • Vite और Vanilla JS
    • Vite और Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native और Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx और React
    Plugins
    • JSON
    • gettext (.po)
    VS Code एक्सटेंशन
    एजेंट
    • इंटलेयर MCP सर्वर
    • एजेंट कौशल
    रिलीज
    • v8
    • v7
    • v6
    बेंचमार्क
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    ब्लॉग
    प्रश्न करें
    1. Documentation
    2. Next intl
    Creation:2025-10-05Last update:2025-10-05
    GitHub पर एप्लिकेशन टेम्पलेट देखें

    इस पृष्ठ के लिए एक एप्लिकेशन टेम्पलेट उपलब्ध है।

    इस दस्तावेज़ को अपने पसंदीदा AI एसिस्टेंट के साथ संदर्भित करें
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    अपने प्रश्न को पूछें और दस्तावेज़ का सारांश प्राप्त करें, इस पृष्ठ और आपके चुने हुए AI प्रदाता का उपयोग करके

    इस पृष्ठ की सामग्री एक AI द्वारा अनुवादित की गई है।

    अंग्रेजी में मूल सामग्री के अंतिम संस्करण देखें
    इस दस्तावेज़ को संपादित करें

    अगर आपके पास इस दस्तावेज़ को सुधारने के लिए कोई विचार है, तो कृपया GitHub पर एक पुल अनुरोध सबमिट करके योगदान देने में संकोच न करें।

    दस्तावेज़ के लिए GitHub लिंक
    Copy

    दस्तावेज़ का Markdown को क्लिपबोर्ड पर कॉपी करें

    Intlayer का उपयोग करके अपने Next.js 15 को next-intl वेबसाइट के साथ अनुवादित करें | अंतरराष्ट्रीयकरण (i18n)

    यह गाइड आपको Next.js 15 (App Router) ऐप में next-intl के सर्वोत्तम अभ्यासों के माध्यम से मार्गदर्शन करता है, और दिखाता है कि Intlayer को मजबूत अनुवाद प्रबंधन और स्वचालन के लिए कैसे ऊपर जोड़ा जाए।

    next-i18next vs next-intl vs Intlayer में तुलना देखें।

    • जूनियर्स के लिए: एक कार्यशील बहुभाषी ऐप प्राप्त करने के लिए चरण-दर-चरण अनुभागों का पालन करें।
    • मध्य स्तर के डेवलपर्स के लिए: payload अनुकूलन और सर्वर/क्लाइंट पृथक्करण पर ध्यान दें।
    • वरिष्ठों के लिए: स्थैतिक जनरेशन, मिडलवेयर, SEO एकीकरण, और स्वचालन हुक्स पर ध्यान दें।

    हम क्या कवर करेंगे:

    • सेटअप और फ़ाइल संरचना
    • संदेशों को लोड करने के तरीके का अनुकूलन
    • क्लाइंट और सर्वर कंपोनेंट का उपयोग
    • SEO के लिए मेटाडेटा, साइटमैप, रोबोट्स
    • स्थानीय रूटिंग के लिए मिडलवेयर
    • Intlayer को ऊपर जोड़ना (CLI और स्वचालन)

    next-intl का उपयोग करके अपना एप्लिकेशन सेट करें

    next-intl निर्भरताएँ इंस्टॉल करें:

    bash
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    npm install next-intl
    bash
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    .├── locales│   ├── en│   │  ├── common.json│   │  └── about.json│   ├── fr│   │  ├── common.json│   │  └── about.json│   └── es│      ├── common.json│      └── about.json└── src    ├── i18n.ts    ├── middleware.ts    ├── app    │   └── [locale]    │       ├── layout.tsx    │       └── about    │           └── page.tsx    └── components        ├── ClientComponentExample.tsx        └── ServerComponent.tsx

    सेटअप और कंटेंट लोड करना

    केवल उन namespaces को लोड करें जिनकी आपकी routes को आवश्यकता है और प्रारंभ में locales को मान्य करें। जब संभव हो तो सर्वर कंपोनेंट्स को synchronous रखें और केवल आवश्यक संदेशों को क्लाइंट पर भेजें।

    src/i18n.ts
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import { getRequestConfig } from "next-intl/server";import { notFound } from "next/navigation";export const locales = ["en", "fr", "es"] as const;export const defaultLocale = "en" as const;async function loadMessages(locale: string) {  // केवल उन namespaces को लोड करें जिनकी आपकी layout/pages को आवश्यकता है  const [common, about] = await Promise.all([    import(`../locales/${locale}/common.json`).then((m) => m.default),    import(`../locales/${locale}/about.json`).then((m) => m.default),  ]);  return { common, about } as const;}export default getRequestConfig(async ({ locale }) => {  if (!locales.includes(locale)) notFound();  return {    messages: await loadMessages(locale),  };});
    src/app/[locale]/layout.tsx
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import type { ReactNode } from "react";import { locales } from "@/i18n";import {  getLocaleDirection,  unstable_setRequestLocale,} from "next-intl/server";export const dynamic = "force-static";export function generateStaticParams() {  return locales.map((locale) => ({ locale }));}export default async function LocaleLayout({  children,  params,}: {  children: ReactNode;  params: { locale: string };}) {  const { locale } = params;  // इस सर्वर रेंडर (RSC) के लिए सक्रिय अनुरोध locale सेट करें  unstable_setRequestLocale(locale);  const dir = getLocaleDirection(locale);  return (    <html lang={locale} dir={dir}>      <body>{children}</body>    </html>  );}
    src/app/[locale]/about/page.tsx
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import { getTranslations, getMessages, getFormatter } from "next-intl/server";import { NextIntlClientProvider } from "next-intl";import pick from "lodash/pick";import ServerComponent from "@/components/ServerComponent";import ClientComponentExample from "@/components/ClientComponentExample";export const dynamic = "force-static";export default async function AboutPage({  params,}: {  params: { locale: string };}) {  const { locale } = params;  // संदेश सर्वर-साइड लोड किए जाते हैं। केवल आवश्यक चीज़ें क्लाइंट को भेजें।  const messages = await getMessages();  const clientMessages = pick(messages, ["common", "about"]);  // सख्ती से सर्वर-साइड अनुवाद/फॉर्मेटिंग  const tAbout = await getTranslations("about");  const tCounter = await getTranslations("about.counter");  const format = await getFormatter();  const initialFormattedCount = format.number(0);  return (    <NextIntlClientProvider locale={locale} messages={clientMessages}>      <main>        <h1>{tAbout("title")}</h1>        <ClientComponentExample />        <ServerComponent          formattedCount={initialFormattedCount}          label={tCounter("label")}          increment={tCounter("increment")}        />      </main>    </NextIntlClientProvider>  );}

    क्लाइंट कंपोनेंट में उपयोग

    आइए एक क्लाइंट कंपोनेंट का उदाहरण लें जो एक काउंटर रेंडर करता है।

    अनुवाद (आकार पुन: उपयोग किया गया; इन्हें next-intl संदेशों में अपनी पसंद के अनुसार लोड करें)

    locales/en/about.json
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    {  "counter": {    "label": "Counter",    "increment": "Increment"  }}
    locales/fr/about.json
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    {  "counter": {    "label": "Compteur",    "increment": "Incrémenter"  }}

    क्लाइंट कंपोनेंट

    src/components/ClientComponentExample.tsx
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    "use client";import React, { useState } from "react";import { useTranslations, useFormatter } from "next-intl";const ClientComponentExample = () => {  // सीधे नेस्टेड ऑब्जेक्ट के लिए स्कोप करें  const t = useTranslations("about.counter");  const format = useFormatter();  const [count, setCount] = useState(0);  return (    <div>      <p>{format.number(count)}</p>      <button        aria-label={t("label")}        onClick={() => setCount((count) => count + 1)}      >        {t("increment")}      </button>    </div>  );};

    पेज क्लाइंट संदेश में "about" संदेश जोड़ना न भूलें (केवल उन namespaces को शामिल करें जिनकी आपके क्लाइंट को वास्तव में आवश्यकता है)।

    एक सर्वर कंपोनेंट में उपयोग

    यह UI कंपोनेंट एक सर्वर कंपोनेंट है और इसे क्लाइंट कंपोनेंट के अंतर्गत रेंडर किया जा सकता है (पेज → क्लाइंट → सर्वर)। इसे सिंक्रोनस रखें प्रीकंप्यूटेड स्ट्रिंग्स पास करके।

    src/components/ServerComponent.tsx
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    type ServerComponentProps = {  formattedCount: string;  label: string;  increment: string;};const ServerComponent = ({  formattedCount,  label,  increment,}: ServerComponentProps) => {  return (    <div>      <p>{formattedCount}</p>      <button aria-label={label}>{increment}</button>    </div>  );};

    नोट्स:

    • formattedCount सर्वर-साइड पर कंप्यूट करें (जैसे, const initialFormattedCount = format.number(0)).
    • सर्वर कंपोनेंट्स में फंक्शन्स या नॉन-सीरियलाइजेबल ऑब्जेक्ट्स पास करने से बचें।
    src/app/[locale]/about/layout.tsx
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import type { Metadata } from "next";import { locales, defaultLocale } from "@/i18n";import { getTranslations } from "next-intl/server";function localizedPath(locale: string, path: string) {  return locale === defaultLocale ? path : "/" + locale + path;}export async function generateMetadata({  params,}: {  params: { locale: string };}): Promise<Metadata> {  const { locale } = params;  const t = await getTranslations({ locale, namespace: "about" });  const url = "/about";  const languages = Object.fromEntries(    locales.map((locale) => [locale, localizedPath(locale, url)])  );  return {    title: t("title"),    description: t("description"),    alternates: {      canonical: localizedPath(locale, url),      languages: { ...languages, "x-default": url },    },  };}// ... पेज कोड का बाकी हिस्सा
    src/app/sitemap.ts
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const formatterLocalizedPath = (locale: string, path: string) =>  locale === defaultLocale ? origin + path : origin + "/" + locale + path;export default function sitemap(): MetadataRoute.Sitemap {  const aboutLanguages = Object.fromEntries(    locales.map((l) => [l, formatterLocalizedPath(l, "/about")])  );  return [    {      url: formatterLocalizedPath(defaultLocale, "/about"),      lastModified: new Date(),      changeFrequency: "monthly",      priority: 0.7,      alternates: { languages: aboutLanguages },    },  ];}
    src/app/robots.ts
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const withAllLocales = (path: string) => [  path,  ...locales    .filter((locale) => locale !== defaultLocale)    .map((locale) => "/" + locale + path),];export default function robots(): MetadataRoute.Robots {  const disallow = [    ...withAllLocales("/dashboard"),    ...withAllLocales("/admin"),  ];  return {    rules: { userAgent: "*", allow: ["/"], disallow },    host: origin,    sitemap: origin + "/sitemap.xml",  };}

    स्थानिक रूटिंग के लिए मिडलवेयर

    स्थानीय पता लगाने और रूटिंग को संभालने के लिए एक मिडलवेयर जोड़ें:

    src/middleware.ts
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import createMiddleware from "next-intl/middleware";import { locales, defaultLocale } from "@/i18n";export default createMiddleware({  locales: [...locales],  defaultLocale,  localeDetection: true,});export const config = {  // API, Next के आंतरिक और स्थैतिक संसाधनों को छोड़ें  matcher: ["/((?!api|_next|.*\\..*).*)"],};

    सर्वोत्तम प्रथाएँ

    • html lang और dir सेट करें: src/app/[locale]/layout.tsx में, getLocaleDirection(locale) के माध्यम से dir की गणना करें और <html lang={locale} dir={dir}> सेट करें।
    • namespace द्वारा संदेश विभाजित करें: JSON को locale और namespace (जैसे, common.json, about.json) के अनुसार व्यवस्थित करें।
    • क्लाइंट पेलोड को कम करें: पेजों पर, केवल आवश्यक namespaces को NextIntlClientProvider को भेजें (जैसे, pick(messages, ['common', 'about']))।
    • स्थैतिक पेजों को प्राथमिकता दें: export const dynamic = 'force-static' को एक्सपोर्ट करें और सभी locales के लिए स्थैतिक पैरामीटर जनरेट करें।
    • सिंक्रोनस सर्वर कंपोनेंट्स: प्रीकंप्यूटेड स्ट्रिंग्स (अनुवादित लेबल, फॉर्मेटेड नंबर) पास करें, बजाय असिंक्रोनस कॉल्स या नॉन-सीरियलाइजेबल फंक्शन्स के।

    next-intl के ऊपर Intlayer को लागू करें

    intlayer डिपेंडेंसीज़ इंस्टॉल करें:

    bash
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    npm install intlayer @intlayer/sync-json-plugin --save-dev

    intlayer कॉन्फ़िगरेशन फ़ाइल बनाएं:

    intlayer.config.ts
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    import { type IntlayerConfig, Locales } from "intlayer";import { syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  ai: {    apiKey: process.env.OPENAI_API_KEY,  },  plugins: [    // अपने प्रति-namespace फ़ोल्डर संरचना को Intlayer के साथ सिंक में रखें    syncJSON({      format: "icu",      source: ({ key, locale }) => `./locales/${locale}/${key}.json`,    }),  ],};export default config;

    package.json स्क्रिप्ट जोड़ें:

    package.json
    कोड कॉपी करें

    कोड को क्लिपबोर्ड पर कॉपी करें

    {  "scripts": {    "i18n:fill": "intlayer fill",    "i18n:test": "intlayer test"  }}

    नोट्स:

    • intlayer fill: आपके कॉन्फ़िगर किए गए लोकल्स के आधार पर आपकी AI प्रदाता का उपयोग करके गायब अनुवादों को भरता है।
    • intlayer test: गायब/अमान्य अनुवादों की जांच करता है (इसे CI में उपयोग करें)।

    आप तर्क और प्रदाताओं को कॉन्फ़िगर कर सकते हैं; देखें Intlayer CLI।

    Intlayer का क्यों लाभ
    Alt+→

    इस पृष्ठ में

      चर्चाएं गुमनाम हैं और सामान्य मुद्दों को संबोधित करने के लिए नियमित रूप से समीक्षा की जाती हैं। फीचर आइडिया, डॉक्यूमेंटेशन पर फीडबैक, या Intlayer से संबंधित कुछ भी साझा करने में संकोच न करें, हम इस इनपुट का उपयोग अपने रोडमैप को आकार देने और उत्पाद को बेहतर बनाने के लिए करते हैं।

      npm install next-intl
      .├── locales│   ├── en│   │  ├── common.json│   │  └── about.json│   ├── fr│   │  ├── common.json│   │  └── about.json│   └── es│      ├── common.json│      └── about.json└── src    ├── i18n.ts    ├── middleware.ts    ├── app    │   └── [locale]    │       ├── layout.tsx    │       └── about    │           └── page.tsx    └── components        ├── ClientComponentExample.tsx        └── ServerComponent.tsx
      import { getRequestConfig } from "next-intl/server";import { notFound } from "next/navigation";export const locales = ["en", "fr", "es"] as const;export const defaultLocale = "en" as const;async function loadMessages(locale: string) {  // केवल उन namespaces को लोड करें जिनकी आपकी layout/pages को आवश्यकता है  const [common, about] = await Promise.all([    import(`../locales/${locale}/common.json`).then((m) => m.default),    import(`../locales/${locale}/about.json`).then((m) => m.default),  ]);  return { common, about } as const;}export default getRequestConfig(async ({ locale }) => {  if (!locales.includes(locale)) notFound();  return {    messages: await loadMessages(locale),  };});
      import type { ReactNode } from "react";import { locales } from "@/i18n";import {  getLocaleDirection,  unstable_setRequestLocale,} from "next-intl/server";export const dynamic = "force-static";export function generateStaticParams() {  return locales.map((locale) => ({ locale }));}export default async function LocaleLayout({  children,  params,}: {  children: ReactNode;  params: { locale: string };}) {  const { locale } = params;  // इस सर्वर रेंडर (RSC) के लिए सक्रिय अनुरोध locale सेट करें  unstable_setRequestLocale(locale);  const dir = getLocaleDirection(locale);  return (    <html lang={locale} dir={dir}>      <body>{children}</body>    </html>  );}
      import { getTranslations, getMessages, getFormatter } from "next-intl/server";import { NextIntlClientProvider } from "next-intl";import pick from "lodash/pick";import ServerComponent from "@/components/ServerComponent";import ClientComponentExample from "@/components/ClientComponentExample";export const dynamic = "force-static";export default async function AboutPage({  params,}: {  params: { locale: string };}) {  const { locale } = params;  // संदेश सर्वर-साइड लोड किए जाते हैं। केवल आवश्यक चीज़ें क्लाइंट को भेजें।  const messages = await getMessages();  const clientMessages = pick(messages, ["common", "about"]);  // सख्ती से सर्वर-साइड अनुवाद/फॉर्मेटिंग  const tAbout = await getTranslations("about");  const tCounter = await getTranslations("about.counter");  const format = await getFormatter();  const initialFormattedCount = format.number(0);  return (    <NextIntlClientProvider locale={locale} messages={clientMessages}>      <main>        <h1>{tAbout("title")}</h1>        <ClientComponentExample />        <ServerComponent          formattedCount={initialFormattedCount}          label={tCounter("label")}          increment={tCounter("increment")}        />      </main>    </NextIntlClientProvider>  );}
      {  "counter": {    "label": "Counter",    "increment": "Increment"  }}
      {  "counter": {    "label": "Compteur",    "increment": "Incrémenter"  }}
      "use client";import React, { useState } from "react";import { useTranslations, useFormatter } from "next-intl";const ClientComponentExample = () => {  // सीधे नेस्टेड ऑब्जेक्ट के लिए स्कोप करें  const t = useTranslations("about.counter");  const format = useFormatter();  const [count, setCount] = useState(0);  return (    <div>      <p>{format.number(count)}</p>      <button        aria-label={t("label")}        onClick={() => setCount((count) => count + 1)}      >        {t("increment")}      </button>    </div>  );};
      type ServerComponentProps = {  formattedCount: string;  label: string;  increment: string;};const ServerComponent = ({  formattedCount,  label,  increment,}: ServerComponentProps) => {  return (    <div>      <p>{formattedCount}</p>      <button aria-label={label}>{increment}</button>    </div>  );};
      import type { Metadata } from "next";import { locales, defaultLocale } from "@/i18n";import { getTranslations } from "next-intl/server";function localizedPath(locale: string, path: string) {  return locale === defaultLocale ? path : "/" + locale + path;}export async function generateMetadata({  params,}: {  params: { locale: string };}): Promise<Metadata> {  const { locale } = params;  const t = await getTranslations({ locale, namespace: "about" });  const url = "/about";  const languages = Object.fromEntries(    locales.map((locale) => [locale, localizedPath(locale, url)])  );  return {    title: t("title"),    description: t("description"),    alternates: {      canonical: localizedPath(locale, url),      languages: { ...languages, "x-default": url },    },  };}// ... पेज कोड का बाकी हिस्सा
      import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const formatterLocalizedPath = (locale: string, path: string) =>  locale === defaultLocale ? origin + path : origin + "/" + locale + path;export default function sitemap(): MetadataRoute.Sitemap {  const aboutLanguages = Object.fromEntries(    locales.map((l) => [l, formatterLocalizedPath(l, "/about")])  );  return [    {      url: formatterLocalizedPath(defaultLocale, "/about"),      lastModified: new Date(),      changeFrequency: "monthly",      priority: 0.7,      alternates: { languages: aboutLanguages },    },  ];}
      import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const withAllLocales = (path: string) => [  path,  ...locales    .filter((locale) => locale !== defaultLocale)    .map((locale) => "/" + locale + path),];export default function robots(): MetadataRoute.Robots {  const disallow = [    ...withAllLocales("/dashboard"),    ...withAllLocales("/admin"),  ];  return {    rules: { userAgent: "*", allow: ["/"], disallow },    host: origin,    sitemap: origin + "/sitemap.xml",  };}
      import createMiddleware from "next-intl/middleware";import { locales, defaultLocale } from "@/i18n";export default createMiddleware({  locales: [...locales],  defaultLocale,  localeDetection: true,});export const config = {  // API, Next के आंतरिक और स्थैतिक संसाधनों को छोड़ें  matcher: ["/((?!api|_next|.*\\..*).*)"],};
      npm install intlayer @intlayer/sync-json-plugin --save-dev
      import { type IntlayerConfig, Locales } from "intlayer";import { syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  ai: {    apiKey: process.env.OPENAI_API_KEY,  },  plugins: [    // अपने प्रति-namespace फ़ोल्डर संरचना को Intlayer के साथ सिंक में रखें    syncJSON({      format: "icu",      source: ({ key, locale }) => `./locales/${locale}/${key}.json`,    }),  ],};export default config;
      {  "scripts": {    "i18n:fill": "intlayer fill",    "i18n:test": "intlayer test"  }}