Penulis:
    Dibuat:2026-04-02Terakhir diperbarui:2026-06-23

    Domain Kustom

    Intlayer mendukung perutean lokal berbasis domain, yang memungkinkan Anda menyajikan lokal tertentu dari nama host khusus. Misalnya, pengunjung dari Tiongkok dapat diarahkan ke intlayer.zh daripada intlayer.org/zh.

    Cara Kerjanya

    Peta domains di dalam routing mengaitkan setiap lokal dengan nama host. Intlayer menggunakan peta ini di dua tempat:

    1. Pembuatan URL (getLocalizedUrl): saat lokal target berada pada domain yang berbeda dari halaman saat ini, URL absolut akan dikembalikan (misalnya https://intlayer.zh/about). Saat kedua domain cocok, URL relatif akan dikembalikan (misalnya /fr/about).
    2. Proksi server (Next.js & Vite): permintaan masuk akan dialihkan atau ditulis ulang berdasarkan domain tempat mereka tiba.

    Domain eksklusif vs. bersama

    Perbedaan utamanya adalah eksklusivitas:

    • Domain eksklusif - hanya satu lokal yang memetakan ke nama host tersebut (misalnya zh → intlayer.zh). Domain itu sendiri bertindak sebagai pengidentifikasi lokal, sehingga tidak ada awalan lokal yang ditambahkan ke jalur. https://intlayer.zh/about menyajikan konten bahasa Mandarin.
    • Domain bersama - beberapa lokal memetakan ke nama host yang sama (misalnya en dan fr keduanya memetakan ke intlayer.org). Perutean berbasis awalan normal berlaku. intlayer.org/fr/about menyajikan konten bahasa Prancis.

    Konfigurasi

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          Locales.CHINESE,
        ],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-no-default",
        domains: {
          // Domain bersama - en dan fr menggunakan perutean awalan pada intlayer.org
          en: "intlayer.org",
          // Domain eksklusif - zh memiliki nama host sendiri, tidak perlu awalan /zh/
          zh: "intlayer.zh",
        },
      },
    };
    
    export default config;
    

    Lokal yang tidak tercantum dalam domains terus menggunakan perutean awalan standar tanpa penggantian domain apa pun.

    Pembuatan URL

    getLocalizedUrl secara otomatis menghasilkan jenis URL yang benar berdasarkan konteks pemanggilan.

    Lokal domain yang sama (URL relatif)

    ts
    // Halaman saat ini: intlayer.org/about
    getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });
    // → "/fr/about"
    
    getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });
    // → "/about" (lokal default, tanpa awalan)
    

    Lokal lintas domain (URL absolut)

    ts
    // Halaman saat ini: intlayer.org/about
    getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });
    // → "https://intlayer.zh/about" (domain eksklusif, tanpa awalan /zh/)
    

    Menyajikan dari domain lokal itu sendiri

    ts
    // Halaman saat ini: intlayer.zh/about
    getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });
    // → "/about" (sudah berada di domain yang benar - URL relatif)
    
    getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });
    // → "https://intlayer.org/fr/about" (tautan lintas domain kembali ke intlayer.org)
    

    Deteksi otomatis domain saat ini

    currentDomain bersifat opsional. Jika dihilangkan, getLocalizedUrl menyelesaikannya dalam urutan ini:

    1. Nama host dari URL input absolut (misalnya https://intlayer.org/aboutintlayer.org).
    2. window.location.hostname di lingkungan peramban.
    3. Jika keduanya tidak tersedia (SSR tanpa opsi eksplisit), URL relatif akan dikembalikan untuk lokal domain yang sama dan tidak ada URL absolut yang dihasilkan - ini adalah fallback yang aman.
    ts
    // Peramban - window.location.hostname === 'intlayer.org'
    getLocalizedUrl("/about", "zh");
    // → "https://intlayer.zh/about" (dideteksi otomatis dari jendela)
    
    // Dari URL absolut - domain terdeteksi secara otomatis
    getLocalizedUrl("https://intlayer.org/about", "zh");
    // → "https://intlayer.zh/about"
    

    getMultilingualUrls dengan domain

    getMultilingualUrls memanggil getLocalizedUrl untuk setiap lokal, sehingga menghasilkan campuran URL relatif dan absolut tergantung pada domain pemanggil:

    ts
    // currentDomain: 'intlayer.org'
    getMultilingualUrls("/about", { currentDomain: "intlayer.org" });
    // {
    //   en: "/about",
    //   fr: "/fr/about",
    //   es: "/es/about",
    //   zh: "https://intlayer.zh/about",
    // }
    

    URL absolut ini siap digunakan dalam tag <link rel="alternate" hreflang="..."> untuk SEO.

    Inferensi Tipe

    routing.domains diserialisasi ke dalam augmentasi modul yang dihasilkan, sehingga getLocalizedUrl dan getLocalizedPath mempersempit jenis pengembalian mereka ke URL yang tepat yang diselesaikan oleh locale yang dirutekan domain — termasuk penekanan prefiks.

    ts
    // routing: { mode: 'prefix-no-default', domains: { en: 'intlayer.org', zh: 'intlayer.zh' } }
    
    getLocalizedUrl("/about", "zh");
    //     ^? "https://intlayer.zh/about" | "/about"
    
    getLocalizedPath("/about", "zh");
    //     ^? "/about"   (tidak pernah merupakan origin, dan tidak ada prefiks /zh/)
    

    Jenis URL adalah union dari dua nilai yang dapat dikembalikan oleh fungsi: URL absolut di domain locale, dan yang relatif dikembalikan ketika halaman yang sedang dirender sudah berada di domain tersebut. getLocalizedPath tidak memiliki ambiguitas seperti itu - tidak pernah memancarkan origin - jadi tetap menjadi literal tunggal.

    Locale yang berbagi domain menyimpan prefiks normal mereka dalam tipe juga:

    ts
    getLocalizedUrl("/about", "fr");
    //     ^? "https://intlayer.org/fr/about" | "/fr/about"
    

    Regenerasi tipe (npx intlayer build, atau menjalankan dev server apa pun) setelah mengubah routing.domains - penyempitan berasal dari __RoutingRegistry yang dihasilkan, bukan dari file konfigurasi itu sendiri.

    Perilaku Proksi

    Next.js

    Middleware intlayerProxy menangani perutean domain secara otomatis. Tambahkan ke middleware.ts Anda:

    middleware.ts
    export { intlayerProxy as default } from "next-intlayer/proxy";
    
    export const config = {
      matcher: "/((?!api|static|assets|robots|sitemap|.*\\..*|_next).*)",
    };
    

    Redirect - permintaan tiba di domain yang salah untuk awalan lokal tertentu:

    plaintext
    GET intlayer.org/zh/about
    → 301 https://intlayer.zh/about
    

    Rewrite - permintaan tiba di domain eksklusif lokal tanpa awalan:

    plaintext
    GET intlayer.zh/about
    → tulis ulang ke /zh/about (hanya perutean internal Next.js, URL tetap bersih)
    

    Vite

    Plugin Vite intlayerProxy menerapkan logika yang sama selama pengembangan:

    Sejak Intlayer v9, intlayerProxy() digabungkan langsung ke dalam plugin intlayer() dan diaktifkan secara default melalui opsi routing.enableProxy (true secara default). Mendaftarkannya secara terpisah seperti yang ditunjukkan di bawah ini sekarang bersifat opsional — ini dipertahankan untuk kompatibilitas mundur dan untuk setup yang perlu mengontrol urutan plugin. Atur routing.enableProxy: false untuk memilih untuk tidak menggunakan. Lihat catatan rilis v9.
    vite.config.ts
    import { defineConfig } from "vite";
    import { intlayer } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [
        intlayer({
          proxy: {
            ignore: (req) => req.url?.startsWith("/api"),
          },
        }),
      ],
    });
    
    Catatan: dalam pengembangan lokal Anda biasanya menggunakan localhost, sehingga pengalihan lintas domain akan mengarah ke domain langsung alih-alih port lokal lainnya. Gunakan penggantian file hosts (misalnya 127.0.0.1 intlayer.zh) atau proksi terbalik jika Anda perlu menguji perutean multi-domain secara lokal.

    Pemilih Lokal (Locale Switcher)

    Hook useLocale dari next-intlayer menangani navigasi sadar domain secara otomatis. Saat pengguna beralih ke lokal di domain yang berbeda, hook melakukan navigasi halaman penuh (window.location.href) alih-alih router push sisi klien, karena router Next.js tidak dapat melintasi asal (origins).

    components/LocaleSwitcher.tsx
    "use client";
    
    import { useLocale } from "next-intlayer";
    
    export const LocaleSwitcher = () => {
      const { availableLocales, locale, setLocale } = useLocale();
    
      return (
        <ul>
          {availableLocales.map((l) => (
            <li key={l}>
              <button
                onClick={() => setLocale(l)}
                aria-current={l === locale ? "true" : undefined}
              >
                {l.toUpperCase()}
              </button>
            </li>
          ))}
        </ul>
      );
    };
    

    Tidak diperlukan konfigurasi tambahan - useLocale mendeteksi window.location.hostname secara internal dan memutuskan antara router.replace (domain yang sama) dan window.location.href (lintas domain).

    SEO: Tautan Alternatif hreflang

    Perutean berbasis domain biasanya digunakan bersama dengan hreflang untuk memberi tahu mesin telusur URL mana yang harus diindeks untuk setiap bahasa. Gunakan getMultilingualUrls untuk menghasilkan set lengkap URL alternatif:

    app/[locale]/layout.tsx
    import { getMultilingualUrls } from "intlayer";
    import type { Metadata } from "next";
    
    export const generateMetadata = (): Metadata => {
      const alternates = getMultilingualUrls("/", {
        currentDomain: process.env.NEXT_PUBLIC_DOMAIN, // mis. "intlayer.org"
      });
    
      return {
        alternates: {
          languages: alternates,
        },
      };
    };
    

    Ini menghasilkan:

    html
    <link rel="alternate" hreflang="en" href="https://intlayer.org/" />
    <link rel="alternate" hreflang="fr" href="https://intlayer.org/fr/" />
    <link rel="alternate" hreflang="es" href="https://intlayer.org/es/" />
    <link rel="alternate" hreflang="zh" href="https://intlayer.zh/" />
    

    Utilitas Inti

    UtilitasDeskripsi
    getLocalizedUrl(url, locale, { currentDomain })Mengembalikan URL relatif atau absolut tergantung pada apakah lokal target berada di domain saat ini.
    getMultilingualUrls(url, { currentDomain })Mengembalikan peta URL lokal yang diberi kunci lokal, mencampur relatif dan absolut sesuai kebutuhan.
    getPrefix(locale, { domains })Mengembalikan awalan kosong untuk lokal domain eksklusif, awalan normal jika sebaliknya.