BerandaSandboxShowcaseAplikasiDokumentasiBlog
    • EnglishInggris
      EN
    • русскийRusia
      RU
    • 日本語Jepang
      JA
    • françaisPrancis
      FR
    • 한국어Korea
      KO
    • 中文Tionghoa
      ZH
    • españolSpanyol
      ES
    • DeutschJerman
      DE
    • العربيةArab
      AR
    • italianoItalia
      IT
    • British EnglishInggris (Britania)
      EN-GB
    • portuguêsPortugis
      PT
    • हिन्दीHindi
      HI
    • TürkçeTurki
      TR
    • polskiPolski
      PL
    • IndonesiaIndonesia
      ID
    • Tiếng ViệtVietnam
      VI
    • українськаUkraina
      UK
    /
    Filter dokumen berdasarkan framework
    Alt+←
    Mengapa Intlayer?
    Mulai
    Konsep
    • Bagaimana Intlayer bekerja
    • Konfigurasi
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Editor visual
    • CMS
    • Integrasi CI/CD
    • TerjemahanPluralPenumeraanKondisiJenis kelaminPenambahanBerkasNestingMarkdownHTMLPengambilan fungsi
    • File untuk setiap lokal
    • Kompilator
    • Pengisian otomatis
    • Pengujian
    • Optimasi paket
    Lingkungan
    • Next.js 14 dan App Router
      Next.js 15
      Next.js tanpa locale URL
      Next.js dan Page Router
      Compiler
    • Tanstack Start Solid
    • Astro dan React
      Astro dan Svelte
      Astro dan Vue
      Astro dan Solid
      Astro dan Preact
      Astro dan Lit
      Astro dan Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt dan Vue
    • Vite dan Solid
    • SvelteKit
    • Vite dan Preact
    • Vite dan Vanilla JS
    • Vite dan Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native dan Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx dan React
    Plugins
    • JSON
    • gettext (.po)
    Ekstensi VS Code
    Agen
    • Server MCP
    • Keahlian agen
    Rilis
    • v8
    • v7
    • v6
    Benchmark
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Blog
    Ajukan pertanyaan
    1. Documentation
    2. Lingkungan
    3. Vite and vanilla
    Dibuat:2026-03-23Terakhir diperbarui:2026-05-06
    Lihat template aplikasi di GitHub

    Halaman ini memiliki template aplikasi yang tersedia.

    Lihat aplikasi showcase

    Halaman ini menautkan ke demo langsung template.

    Referensikan dokumen ini ke asisten AI favorit Anda
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    Ajukan pertanyaan Anda dan dapatkan ringkasan dokumen dengan merujuk halaman ini dan penyedia AI pilihan Anda

    Riwayat Versi

    1. "Perbarui penggunaan API useIntlayer Solid ke akses properti langsung"
      v8.9.04/5/2026
    2. "Riwayat awal"
      v8.4.1023/3/2026

    Konten halaman ini diterjemahkan menggunakan AI.

    Lihat versi terakhir dari konten aslinya dalam bahasa Inggris
    Sunting dokumen ini

    Jika Anda memiliki ide untuk meningkatkan dokumentasi ini, silakan berkontribusi dengan mengajukan pull request di GitHub.

    Tautan GitHub ke dokumentasi
    Salin

    Salin Markdown dokumentasi ke clipboard

    Terjemahkan situs web Vite dan Vanilla JS Anda dengan Intlayer | Internasionalisasi (i18n)

    ide.intlayer.org
    intlayer-vite-vanilla.vercel.app

    Daftar Isi

    Apa itu Intlayer?

    Intlayer adalah perpustakaan internasionalisasi (i18n) sumber terbuka dan inovatif yang dirancang untuk menyederhanakan dukungan multibahasa dalam aplikasi web modern.

    Dengan Intlayer, Anda dapat:

    • Mengelola terjemahan dengan mudah menggunakan kamus deklaratif di tingkat komponen.
    • Melokalkan metadata, rute, dan konten secara dinamis.
    • Memastikan dukungan TypeScript dengan tipe yang dihasilkan secara otomatis, meningkatkan pelengkapan otomatis dan deteksi kesalahan.
    • Memanfaatkan fitur-fitur canggih, seperti deteksi dan pengalihan lokal dinamis.

    Panduan Langkah-demi-Langkah untuk Menyiapkan Intlayer dalam Aplikasi Vite dan Vanilla JS

    Langkah 1: Instal Dependensi

    Instal paket yang diperlukan menggunakan npm:

    bash
    Salin kode

    Salin kode ke clipboard

    npm install intlayer vanilla-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer Paket inti yang menyediakan alat internasionalisasi untuk manajemen konfigurasi, terjemahan, deklarasi konten, transpilasi, dan perintah CLI.

    • vanilla-intlayer Paket yang mengintegrasikan Intlayer dengan aplikasi JavaScript / TypeScript murni. Paket ini menyediakan pub/sub singleton (IntlayerClient) dan pembantu berbasis callback (useIntlayer, useLocale, dll.) sehingga bagian mana pun dari aplikasi Anda dapat bereaksi terhadap perubahan lokal tanpa bergantung pada kerangka kerja UI.

    • vite-intlayer Menyertakan plugin Vite untuk mengintegrasikan Intlayer dengan Vite bundler, serta middleware untuk mendeteksi lokal pilihan pengguna, mengelola cookie, dan menangani pengalihan URL.

    Langkah 2: Konfigurasi Proyek Anda

    Buat file konfigurasi untuk mengatur bahasa aplikasi Anda:

    intlayer.config.ts
    Salin kode

    Salin kode ke clipboard

    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          // Lokal lainnya
        ],
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    export default config;
    Melalui file konfigurasi ini, Anda dapat mengatur URL yang dilokalkan, pengalihan middleware, nama cookie, lokasi dan ekstensi deklarasi konten Anda, menonaktifkan log Intlayer di konsol, dan banyak lagi. Untuk daftar lengkap parameter yang tersedia, lihat dokumentasi konfigurasi.

    Langkah 3: Integrasikan Intlayer ke dalam Konfigurasi Vite Anda

    Tambahkan plugin intlayer ke konfigurasi Anda.

    vite.config.ts
    Salin kode

    Salin kode ke clipboard

    import { defineConfig } from "vite";
    import { intlayer } from "vite-intlayer";
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [intlayer()],
    });
    Plugin Vite intlayer() digunakan untuk mengintegrasikan Intlayer dengan Vite. Plugin ini memastikan pembuatan file deklarasi konten dan memantaunya dalam mode pengembangan. Plugin ini mendefinisikan variabel lingkungan Intlayer di dalam aplikasi Vite. Selain itu, plugin ini menyediakan alias untuk mengoptimalkan kinerja.

    Langkah 4: Bootstrap Intlayer di Titik Masuk Anda

    Panggil installIntlayer() sebelum merender konten apa pun sehingga singleton lokal global siap digunakan.

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import { installIntlayer } from "vanilla-intlayer";// Harus dipanggil sebelum merender konten i18n apa pun.installIntlayer();// Impor dan jalankan modul aplikasi Anda.import "./app.js";

    Jika Anda juga menggunakan deklarasi konten md() (Markdown), instal juga perender markdown:

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import { installIntlayer, installIntlayerMarkdown } from "vanilla-intlayer";installIntlayer();installIntlayerMarkdown();import "./app.js";

    Langkah 5: Deklarasikan Konten Anda

    Buat dan kelola deklarasi konten Anda untuk menyimpan terjemahan:

    src/app.content.ts
    Salin kode

    Salin kode ke clipboard

    import { insert, t, type Dictionary } from "intlayer";
    
    const appContent = {
      key: "app",
      content: {
        title: "Vite + Vanilla",
    
        viteLogoLabel: t({
          en: "Vite Logo",
          fr: "Logo Vite",
          es: "Logo Vite",
        }),
    
        count: insert(
          t({
            en: "count is {{count}}",
            fr: "le compte est {{count}}",
            es: "el recuento es {{count}}",
          })
        ),
    
        readTheDocs: t({
          en: "Click on the Vite logo to learn more",
          fr: "Cliquez sur le logo Vite pour en savoir plus",
          es: "Klik pada logo Vite untuk mempelajari lebih lanjut",
        }),
      },
    } satisfies Dictionary;
    
    export default appContent;

    Deklarasi konten Anda dapat ditentukan di mana saja di aplikasi Anda selama mereka termasuk dalam direktori contentDir (secara default ./src). Dan cocok dengan ekstensi file deklarasi konten (secara default .content.{json,ts,tsx,js,jsx,mjs,cjs}).

    Untuk detail lebih lanjut, lihat dokumentasi deklarasi konten.

    Langkah 6: Gunakan Intlayer di JavaScript Anda

    vanilla-intlayer mencerminkan API permukaan react-intlayer: useIntlayer(key, locale?) mengembalikan konten yang diterjemahkan secara langsung. Rantai .onChange() pada hasilnya untuk berlangganan perubahan lokal - padanan eksplisit dari render ulang React.

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import { installIntlayer, useIntlayer } from "vanilla-intlayer";installIntlayer();// Dapatkan konten awal untuk lokal saat ini.// Rantai .onChange() untuk diberitahu setiap kali lokal berubah.const content = useIntlayer("app").onChange((newContent) => {  // Hanya render ulang atau perbaiki node DOM yang terpengaruh  document.querySelector<HTMLHeadingElement>("h1")!.textContent = String(    newContent.title  );  document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =    String(newContent.readTheDocs);});// Render awaldocument.querySelector<HTMLHeadingElement>("h1")!.textContent = String(  content.title);document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =  String(content.readTheDocs);

    Akses nilai leaf sebagai string dengan merangkumnya dalam String(), yang memanggil metode toString() node dan mengembalikan teks yang diterjemahkan.

    Saat Anda memerlukan nilai untuk atribut HTML asli (misalnya, alt, aria-label), gunakan .value secara langsung:

    typescript
    Salin kode

    Salin kode ke clipboard

    img.alt = content.viteLogoLabel.value;

    (Opsional) Langkah 7: Ubah Bahasa Konten Anda

    Untuk mengubah bahasa konten, gunakan fungsi setLocale yang disediakan oleh useLocale.

    src/locale-switcher.ts
    Salin kode

    Salin kode ke clipboard

    import { getLocaleName } from "intlayer";import { useLocale } from "vanilla-intlayer";export function setupLocaleSwitcher(container: HTMLElement): () => void {  const { locale, availableLocales, setLocale, subscribe } = useLocale();  const select = document.createElement("select");  select.setAttribute("aria-label", "Language");  const render = (currentLocale: string) => {    select.innerHTML = availableLocales      .map(        (loc) =>          `<option value="${loc}"${loc === currentLocale ? " selected" : ""}>            ${getLocaleName(loc)}          </option>`      )      .join("");  };  render(locale);  container.appendChild(select);  select.addEventListener("change", () => setLocale(select.value as any));  // Jaga agar dropdown tetap sinkron ketika lokal berubah dari tempat lain  return subscribe((newLocale) => render(newLocale));}

    (Opsional) Langkah 8: Render Konten Markdown dan HTML

    Intlayer mendukung deklarasi konten md() dan html(). Dalam Vanilla JS, output yang dikompilasi dimasukkan sebagai HTML mentah melalui innerHTML.

    Kompilasi dan masukkan HTML:

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import {  compileMarkdown,  installIntlayerMarkdown,  useIntlayer,} from "vanilla-intlayer";installIntlayerMarkdown();const content = useIntlayer("app").onChange((newContent) => {  const el = document.querySelector<HTMLDivElement>(".edit-note")!;  el.innerHTML = compileMarkdown(String(newContent.editNote));});document.querySelector<HTMLDivElement>(".edit-note")!.innerHTML =  compileMarkdown(String(content.editNote));
    TIP
    String(content.editNote) memanggil toString() pada IntlayerNode yang mengembalikan string Markdown mentah. Berikan itu ke compileMarkdown untuk mendapatkan string HTML, lalu pasang melalui innerHTML.
    WARNING

    Hanya gunakan innerHTML dengan konten tepercaya. Jika markdown berasal dari input pengguna, bersihkan terlebih dahulu (misalnya dengan DOMPurify). Anda dapat menginstal perender pembersih secara dinamis:

    typescript
    Salin kode

    Salin kode ke clipboard

    import { installIntlayerMarkdownDynamic } from "vanilla-intlayer";await installIntlayerMarkdownDynamic(async () => {  const DOMPurify = await import("dompurify");  return (markdown) => DOMPurify.sanitize(compileMarkdown(markdown));});

    (Opsional) Langkah 9: Tambahkan Localized Routing ke aplikasi Anda

    Untuk membuat rute unik untuk setiap bahasa (berguna untuk SEO), Anda dapat menggunakan intlayerProxy dalam konfigurasi Vite untuk deteksi lokal sisi server.

    Pertama, tambahkan intlayerProxy ke konfigurasi Vite Anda:

    Perhatikan bahwa untuk menggunakan intlayerProxy di produksi, Anda perlu memindahkan vite-intlayer dari devDependencies ke dependencies.
    vite.config.ts
    Salin kode

    Salin kode ke clipboard

    import { defineConfig } from "vite";
    import { intlayer, intlayerProxy } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [
        intlayerProxy(), // sebaiknya diletakkan pertama
        intlayer(),
      ],
    });

    (Opsional) Langkah 10: Ubah URL ketika lokal berubah

    Untuk memperbarui URL browser saat lokal berubah, panggil useRewriteURL() setelah menginstal Intlayer:

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import { installIntlayer, useRewriteURL } from "vanilla-intlayer";installIntlayer();// Menulis ulang URL segera dan pada setiap perubahan lokal berikutnya.// Mengembalikan fungsi berhenti berlangganan untuk pembersihan.const stopRewriteURL = useRewriteURL();

    (Opsional) Langkah 11: Alihkan Atribut Bahasa dan Arah HTML

    Perbarui atribut lang dan dir dari tag <html> agar sesuai dengan lokal saat ini demi aksesibilitas dan SEO.

    src/main.ts
    Salin kode

    Salin kode ke clipboard

    import { getHTMLTextDir } from "intlayer";import { installIntlayer, useLocale } from "vanilla-intlayer";installIntlayer();useLocale({  onLocaleChange: (locale) => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  },});

    (Opsional) Langkah 12: Lazy-load kamus per lokal

    Untuk aplikasi besar, Anda mungkin ingin membagi kamus setiap lokal ke dalam penggalannya sendiri. Gunakan useDictionaryDynamic bersama dengan import() dinamis Vite:

    src/app.ts
    Salin kode

    Salin kode ke clipboard

    import { installIntlayer, useDictionaryDynamic } from "vanilla-intlayer";installIntlayer();const unsubscribe = useDictionaryDynamic(  {    en: () => import("../.intlayer/dictionaries/en/app.mjs"),    fr: () => import("../.intlayer/dictionaries/fr/app.mjs"),    es: () => import("../.intlayer/dictionaries/es/app.mjs"),  },  "app").onChange((content) => {  document.querySelector("h1")!.textContent = String(content.title);});
    Bundel masing-masing lokal hanya diambil ketika lokal tersebut menjadi aktif dan hasilnya disimpan di cache - pengalihan berikutnya ke lokal yang sama bersifat instan.

    (Opsional) Langkah 13: Ekstrak konten komponen Anda

    Jika Anda memiliki kode dasar yang sudah ada, mengubah ribuan file bisa memakan waktu.

    Untuk meringankan proses ini, Intlayer mengusulkan kompilator / ekstraktor untuk mentransformasi komponen Anda dan mengekstrak konten.

    Untuk menyiapkannya, Anda dapat menambahkan bagian compiler di file intlayer.config.ts Anda:

    intlayer.config.ts
    Salin kode

    Salin kode ke clipboard

    import { type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  // ... Sisa konfigurasi Anda  compiler: {    /**     * Menunjukkan apakah kompilator harus diaktifkan.     */    enabled: true,    /**     * Mendefinisikan jalur file keluaran     */    output: ({ fileName, extension }) => `./${fileName}${extension}`,    /**     * Menunjukkan apakah komponen harus disimpan setelah ditransformasi.     * Dengan begitu, kompilator hanya dapat dijalankan sekali untuk mengubah aplikasi, dan kemudian dapat dihapus.     */    saveComponents: false,    /**     * Awalan kunci kamus     */    dictionaryKeyPrefix: "",  },};export default config;

    Jalankan ekstraktor untuk mentransformasi komponen Anda dan mengekstrak konten

    bash
    Salin kode

    Salin kode ke clipboard

    npx intlayer extract

    Perbarui vite.config.ts Anda untuk menyertakan plugin intlayerCompiler:

    vite.config.ts
    Salin kode

    Salin kode ke clipboard

    import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Menambahkan plugin kompilator ],});
    bash
    Salin kode

    Salin kode ke clipboard

    npm run build # Atau npm run dev

    (Opsional) Sitemap dan robots.txt (generate saat build)

    Intlayer menyediakan generateSitemap dan getMultilingualUrls untuk memformat sitemap.xml multibahasa dan robots.txt yang siap untuk crawler, lalu menulisnya secara otomatis ke public/. Biasanya skrip Node kecil dijalankan sebelum Vite (misalnya hook npm predev / prebuild).

    Sitemap

    Generator sitemap Intlayer menghormati konfigurasi locale dan menambahkan metadata untuk crawler.

    Sitemap mendukung namespace xhtml:link (hreflang). Alih-alih hanya daftar URL datar, Intlayer menghubungkan semua varian bahasa setiap halaman secara dua arah (mis. /about, /fr/about, atau /about?lang=fr tergantung mode routing).

    Robots.txt

    Gunakan getMultilingualUrls agar aturan Disallow mencakup semua varian URL jalur sensitif.

    1. Buat generate-seo.mjs di root proyek

    generate-seo.mjs
    Salin kode

    Salin kode ke clipboard

    import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");

    Paket intlayer harus terpasang. Setel SITE_URL di lingkungan produksi (misalnya di CI).

    Disarankan generate-seo.mjs untuk ESM Node. Jika memakai generate-seo.js, pastikan "type": "module" di package.json atau aktifkan ESM lainnya.

    2. Jalankan skrip sebelum Vite

    package.json
    Salin kode

    Salin kode ke clipboard

    {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}

    Sesuaikan perintah jika memakai pnpm atau yarn. Skrip juga bisa dipanggil dari CI.

    Konfigurasi TypeScript

    Pastikan konfigurasi TypeScript Anda menyertakan tipe yang dihasilkan secara otomatis.

    tsconfig.json
    Salin kode

    Salin kode ke clipboard

    {  "compilerOptions": {    // ...  },  "include": ["src", ".intlayer/**/*.ts"],}

    Konfigurasi Git

    Disarankan untuk mengabaikan file yang dihasilkan oleh Intlayer. Ini memungkinkan Anda untuk menghindari memasukkannya ke dalam repositori Git Anda.

    Untuk melakukan ini, Anda dapat menambahkan instruksi berikut ke file .gitignore Anda:

    bash
    Salin kode

    Salin kode ke clipboard

    # Abaikan file yang dihasilkan oleh Intlayer.intlayer

    Ekstensi VS Code

    Untuk meningkatkan pengalaman pengembangan Anda dengan Intlayer, Anda dapat menginstal Ekstensi VS Code Intlayer resmi.

    Instal dari VS Code Marketplace

    Ekstensi ini menyediakan:

    • Autocompletion untuk kunci terjemahan.
    • Deteksi kesalahan waktu nyata untuk terjemahan yang hilang.
    • Pratinjau sebaris dari konten yang diterjemahkan.
    • Tindakan cepat untuk membuat dan memperbarui terjemahan dengan mudah.

    Untuk detail lebih lanjut tentang cara menggunakan ekstensi, lihat dokumentasi Ekstensi VS Code Intlayer.


    Melangkah Lebih Jauh

    Untuk melangkah lebih jauh, Anda dapat mengimplementasikan editor visual atau mengeksternalisasi konten Anda menggunakan CMS.

    Vite dan Preact
    Vite dan Lit
    Alt+→

    Di halaman ini

      Diskusi bersifat anonim dan ditinjau secara berkala untuk mengatasi masalah umum. Jangan ragu untuk berbagi ide fitur, masukan tentang dokumentasi, atau apa pun yang terkait dengan Intlayer, kami menggunakan masukan ini untuk membentuk peta jalan dan meningkatkan produk.

      npm install intlayer vanilla-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { installIntlayer } from "vanilla-intlayer";// Harus dipanggil sebelum merender konten i18n apa pun.installIntlayer();// Impor dan jalankan modul aplikasi Anda.import "./app.js";
      import { installIntlayer, installIntlayerMarkdown } from "vanilla-intlayer";installIntlayer();installIntlayerMarkdown();import "./app.js";
      import { installIntlayer, useIntlayer } from "vanilla-intlayer";installIntlayer();// Dapatkan konten awal untuk lokal saat ini.// Rantai .onChange() untuk diberitahu setiap kali lokal berubah.const content = useIntlayer("app").onChange((newContent) => {  // Hanya render ulang atau perbaiki node DOM yang terpengaruh  document.querySelector<HTMLHeadingElement>("h1")!.textContent = String(    newContent.title  );  document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =    String(newContent.readTheDocs);});// Render awaldocument.querySelector<HTMLHeadingElement>("h1")!.textContent = String(  content.title);document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =  String(content.readTheDocs);
      img.alt = content.viteLogoLabel.value;
      import { getLocaleName } from "intlayer";import { useLocale } from "vanilla-intlayer";export function setupLocaleSwitcher(container: HTMLElement): () => void {  const { locale, availableLocales, setLocale, subscribe } = useLocale();  const select = document.createElement("select");  select.setAttribute("aria-label", "Language");  const render = (currentLocale: string) => {    select.innerHTML = availableLocales      .map(        (loc) =>          `<option value="${loc}"${loc === currentLocale ? " selected" : ""}>            ${getLocaleName(loc)}          </option>`      )      .join("");  };  render(locale);  container.appendChild(select);  select.addEventListener("change", () => setLocale(select.value as any));  // Jaga agar dropdown tetap sinkron ketika lokal berubah dari tempat lain  return subscribe((newLocale) => render(newLocale));}
      import {  compileMarkdown,  installIntlayerMarkdown,  useIntlayer,} from "vanilla-intlayer";installIntlayerMarkdown();const content = useIntlayer("app").onChange((newContent) => {  const el = document.querySelector<HTMLDivElement>(".edit-note")!;  el.innerHTML = compileMarkdown(String(newContent.editNote));});document.querySelector<HTMLDivElement>(".edit-note")!.innerHTML =  compileMarkdown(String(content.editNote));
      import { installIntlayerMarkdownDynamic } from "vanilla-intlayer";await installIntlayerMarkdownDynamic(async () => {  const DOMPurify = await import("dompurify");  return (markdown) => DOMPurify.sanitize(compileMarkdown(markdown));});
      import { installIntlayer, useRewriteURL } from "vanilla-intlayer";installIntlayer();// Menulis ulang URL segera dan pada setiap perubahan lokal berikutnya.// Mengembalikan fungsi berhenti berlangganan untuk pembersihan.const stopRewriteURL = useRewriteURL();
      import { getHTMLTextDir } from "intlayer";import { installIntlayer, useLocale } from "vanilla-intlayer";installIntlayer();useLocale({  onLocaleChange: (locale) => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  },});
      import { installIntlayer, useDictionaryDynamic } from "vanilla-intlayer";installIntlayer();const unsubscribe = useDictionaryDynamic(  {    en: () => import("../.intlayer/dictionaries/en/app.mjs"),    fr: () => import("../.intlayer/dictionaries/fr/app.mjs"),    es: () => import("../.intlayer/dictionaries/es/app.mjs"),  },  "app").onChange((content) => {  document.querySelector("h1")!.textContent = String(content.title);});
      import { type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  // ... Sisa konfigurasi Anda  compiler: {    /**     * Menunjukkan apakah kompilator harus diaktifkan.     */    enabled: true,    /**     * Mendefinisikan jalur file keluaran     */    output: ({ fileName, extension }) => `./${fileName}${extension}`,    /**     * Menunjukkan apakah komponen harus disimpan setelah ditransformasi.     * Dengan begitu, kompilator hanya dapat dijalankan sekali untuk mengubah aplikasi, dan kemudian dapat dihapus.     */    saveComponents: false,    /**     * Awalan kunci kamus     */    dictionaryKeyPrefix: "",  },};export default config;
      npx intlayer extract
      import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Menambahkan plugin kompilator ],});
      npm run build # Atau npm run dev
      import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");
      {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}
      {  "compilerOptions": {    // ...  },  "include": ["src", ".intlayer/**/*.ts"],}
      # Abaikan file yang dihasilkan oleh Intlayer.intlayer