Terima notifikasi tentang rilis Intlayer yang akan datang
    Dibuat:2025-09-09Terakhir diperbarui:2025-09-09

    Terjemahkan situs web Tanstack Start Anda menggunakan Intlayer | Internasionalisasi (i18n)

    Daftar Isi

    Panduan ini menunjukkan cara mengintegrasikan Intlayer untuk internasionalisasi yang mulus dalam proyek Tanstack Start dengan routing yang mendukung locale, dukungan TypeScript, dan praktik pengembangan modern.

    Apa itu Intlayer?

    Intlayer adalah perpustakaan internasionalisasi (i18n) sumber terbuka yang inovatif, 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 autocompletion dan deteksi kesalahan.
    • Manfaatkan fitur canggih, seperti deteksi dan pengalihan locale secara dinamis.
    • Aktifkan routing yang mendukung locale dengan sistem routing berbasis file Tanstack Start.

    Panduan Langkah demi Langkah untuk Mengatur Intlayer dalam Aplikasi Tanstack Start

    Lihat Template Aplikasi di GitHub.

    Langkah 1: Buat Proyek

    Mulailah dengan membuat proyek TanStack Start baru dengan mengikuti panduan Mulai proyek baru di situs web TanStack Start.

    Langkah 2: Pasang Paket Intlayer

    Pasang paket yang diperlukan menggunakan manajer paket pilihan Anda:

    npm install intlayer react-intlayernpm install vite-intlayer --save-dev
    • intlayer

      Paket inti yang menyediakan alat internasionalisasi untuk manajemen konfigurasi, terjemahan, deklarasi konten, transpile, dan perintah CLI.

    • react-intlayer Paket yang mengintegrasikan Intlayer dengan aplikasi React. Paket ini menyediakan context providers dan hooks untuk internasionalisasi React.

    • vite-intlayer Termasuk plugin Vite untuk mengintegrasikan Intlayer dengan Vite bundler, serta middleware untuk mendeteksi locale yang dipilih pengguna, mengelola cookie, dan menangani pengalihan URL.

    Langkah 3: Konfigurasi proyek Anda

    Buat file konfigurasi untuk mengatur bahasa aplikasi Anda:

    intlayer.config.ts
    import type { IntlayerConfig } from "intlayer";import { Locales } from "intlayer";const config: IntlayerConfig = {  internationalization: {    defaultLocale: Locales.ENGLISH,    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],  },};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 lainnya. Untuk daftar lengkap parameter yang tersedia, lihat dokumentasi konfigurasi.

    Langkah 4: Integrasikan Intlayer dalam Konfigurasi Vite Anda

    Tambahkan plugin intlayer ke dalam konfigurasi Anda:

    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [reactRouter(), tsconfigPaths(), intlayer()],});
    Plugin Vite intlayer() digunakan untuk mengintegrasikan Intlayer dengan Vite. Plugin ini memastikan pembuatan file deklarasi konten dan memantau file tersebut dalam mode pengembangan. Plugin ini juga mendefinisikan variabel lingkungan Intlayer di dalam aplikasi Vite. Selain itu, plugin ini menyediakan alias untuk mengoptimalkan performa.

    Langkah 5: Buat Komponen Layout

    Atur layout root Anda dan layout khusus locale:

    Layout Root

    src/routes/{-$locale}/route.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes";export const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Langkah 6: Deklarasikan Konten Anda

    Buat dan kelola deklarasi konten Anda untuk menyimpan terjemahan:

    src/contents/page.content.ts
    import type { Dictionary } from "intlayer";import { t } from "intlayer";const appContent = {  content: {    links: {      about: t({        id: "Tentang",        en: "About",        es: "Acerca de",        fr: "À propos",      }),      home: t({        id: "Beranda",        en: "Home",        es: "Inicio",        fr: "Accueil",      }),    },    meta: {      description: t({        id: "Ini adalah contoh penggunaan Intlayer dengan TanStack Router",        en: "This is an example of using Intlayer with TanStack Router",        es: "Este es un ejemplo de uso de Intlayer con TanStack Router",        fr: "Ceci est un exemple d'utilisation d'Intlayer avec TanStack Router",      }),    },    title: t({      id: "Selamat datang di Intlayer + TanStack Router",      en: "Welcome to Intlayer + TanStack Router",      es: "Bienvenido a Intlayer + TanStack Router",      fr: "Bienvenue à Intlayer + TanStack Router",    }),  },  key: "app",} satisfies Dictionary;export default appContent;
    Deklarasi konten Anda dapat didefinisikan di mana saja dalam aplikasi Anda selama sudah dimasukkan ke dalam direktori contentDir (secara default, ./app). Dan sesuai dengan ekstensi file deklarasi konten (secara default, .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}).
    Untuk detail lebih lanjut, lihat dokumentasi deklarasi konten.

    Langkah 7: Buat Komponen dan Hooks yang Mendukung Locale

    Buat komponen LocalizedLink untuk navigasi yang mendukung locale:

    src/components/localized-link.tsx
    import type { FC } from "react";import { Link, type LinkComponentProps } from "@tanstack/react-router";import { useLocale } from "react.intlayer";export const LOCALE_ROUTE = "{-$locale}" as const;// Utilitas utamaexport type RemoveLocaleParam<T> = T extends string  ? RemoveLocaleFromString<T>  : T;export type To = RemoveLocaleParam<LinkComponentProps["to"]>;type CollapseDoubleSlashes<S extends string> =  S extends `${infer H}//${infer T}` ? CollapseDoubleSlashes<`${H}/${T}`> : S;type LocalizedLinkProps = {  to?: To;} & Omit<LinkComponentProps, "to">;// Pembantutype RemoveAll<  S extends string,  Sub extends string,> = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<  RemoveAll<S, typeof LOCALE_ROUTE>>;export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {  const { locale } = useLocale();  const { localePrefix } = getPrefix(locale);  return (    <Link      {...props}      params={{        locale: localePrefix,        ...(typeof props?.params === "object" ? props?.params : {}),      }}      to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]}    />  );};

    Komponen ini memiliki dua tujuan:

    • Menghapus prefix {-$locale} yang tidak perlu dari URL.
    • Menyisipkan parameter locale ke dalam URL untuk memastikan pengguna langsung diarahkan ke rute yang sudah dilokalkan.

    Kemudian kita dapat membuat hook useLocalizedNavigate untuk navigasi secara programatik:

    src/hooks/useLocalizedNavigate.tsx
    import { useLocale } from "react.intlayer";import { useNavigate } from "@tanstack/react-router";import { LOCALE_ROUTE } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";export const useLocalizedNavigate = () => {  const navigate = useNavigate();  const { locale } = useLocale();  type StripLocalePrefix<T extends string> = T extends    | `/${typeof LOCALE_ROUTE}`    | `/${typeof LOCALE_ROUTE}/`    ? "/"    : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`      ? `/${Rest}`      : never;  type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;  interface LocalizedNavigate {    (to: LocalizedTo): ReturnType<typeof navigate>;    (      opts: { to: LocalizedTo } & Record<string, unknown>    ): ReturnType<typeof navigate>;  }  const localizedNavigate: LocalizedNavigate = (args: any) => {    if (typeof args === "string") {      return navigate({ to: `/${LOCALE_ROUTE}${args}`, params: { locale } });    }    const { to, ...rest } = args;    const localedTo = `/${LOCALE_ROUTE}${to}` as any;    return navigate({ to: localedTo, params: { locale, ...rest } as any });  };  return localizedNavigate;};

    Langkah 8: Gunakan Intlayer di Halaman Anda

    Akses kamus konten Anda di seluruh aplikasi Anda:

    Halaman Beranda yang Dilokalkan

    src/routes/{-$locale}/index.tsx
    import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";import { useIntlayer } from "react-intlayer";import LocaleSwitcher from "@/components/locale-switcher";import { LocalizedLink } from "@/components/localized-link";import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = params;    const metaContent = getIntlayer("app", locale);    return {      meta: [        { title: metaContent.title },        { content: metaContent.meta.description, name: "description" },      ],    };  },});function RouteComponent() {  const content = useIntlayer("app");  const navigate = useLocalizedNavigate();  return (    <div>      <div>        {content.title}        <LocaleSwitcher />        <div>          <LocalizedLink to="/">{content.links.home}</LocalizedLink>          <LocalizedLink to="/about">{content.links.about}</LocalizedLink>        </div>        <div>          <button onClick={() => navigate({ to: "/" })}>            {content.links.home}          </button>          <button onClick={() => navigate({ to: "/about" })}>            {content.links.about}          </button>        </div>      </div>    </div>  );}
    Untuk mempelajari lebih lanjut tentang hook useIntlayer, lihat dokumentasi.

    Langkah 9: Buat Komponen Locale Switcher

    Buat komponen untuk memungkinkan pengguna mengganti bahasa:

    src/components/locale-switcher.tsx
    import type { FC } from "react";import { useLocation } from "@tanstack/react-router";import {  getHTMLTextDir,  getLocaleName,  getPathWithoutLocale,  getPrefix,} from "intlayer";import { setLocaleInStorage, useIntlayer, useLocale } from "react-intlayer";import { LocalizedLink, To } from "./localized-link";export const LocaleSwitcher: FC = () => {  const { localeSwitcherLabel } = useIntlayer("locale-switcher");  const { pathname } = useLocation();  const { availableLocales, locale } = useLocale();  const pathWithoutLocale = getPathWithoutLocale(pathname);  return (    <ol>      {availableLocales.map((localeEl) => (        <li key={localeEl}>          <LocalizedLink            aria-current={localeEl === locale ? "page" : undefined}            aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeEl)}`}            onClick={() => setLocaleInStorage(localeEl)}            params={{ locale: getPrefix(localeEl).localePrefix }}          >            <span>              {/* Locale - misalnya FR */}              {localeItem}            </span>            <span>              {/* Bahasa dalam Locale-nya sendiri - misalnya Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* Bahasa dalam Locale saat ini - misalnya Francés dengan locale saat ini disetel ke Locales.SPANISH */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* Bahasa dalam bahasa Inggris - misalnya French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </LocalizedLink>        </li>      ))}    </ol>  );};
    Untuk mempelajari lebih lanjut tentang hook useLocale, lihat dokumentasi.

    Langkah 10: Tambahkan Manajemen Atribut HTML (Opsional)

    Buat hook untuk mengelola atribut lang dan dir pada HTML:

    src/hooks/useI18nHTMLAttributes.tsx
    // src/hooks/useI18nHTMLAttributes.tsximport { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  useEffect(() => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  }, [locale]);};

    Kemudian gunakan di komponen root Anda:

    src/routes/{-$locale}/index.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes"; // impor hookexport const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  useI18nHTMLAttributes(); // tambahkan baris ini  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={locale ?? defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Langkah 11: Tambahkan middleware (Opsional)

    Anda juga dapat menggunakan intlayerProxy untuk menambahkan routing sisi server ke aplikasi Anda. Plugin ini akan secara otomatis mendeteksi locale saat ini berdasarkan URL dan mengatur cookie locale yang sesuai. Jika tidak ada locale yang ditentukan, plugin akan menentukan locale yang paling sesuai berdasarkan preferensi bahasa browser pengguna. Jika tidak ada locale yang terdeteksi, maka akan mengarahkan ke locale default.

    Perlu diperhatikan bahwa untuk menggunakan intlayerProxy di produksi, Anda perlu memindahkan paket vite-intlayer dari devDependencies ke dependencies.
    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [    tailwindcss(),    reactRouter(),    tsconfigPaths(),    intlayer(),    intlayerProxy(),  ],});

    Langkah 12: Konfigurasi TypeScript (Opsional)

    Intlayer menggunakan module augmentation untuk mendapatkan manfaat dari TypeScript dan membuat codebase Anda lebih kuat.

    Pastikan konfigurasi TypeScript Anda menyertakan tipe yang dihasilkan secara otomatis:

    tsconfig.json
    {  // ... konfigurasi Anda yang sudah ada  include: [    // ... include Anda yang sudah ada    ".intlayer/**/*.ts", // Sertakan tipe yang dihasilkan otomatis  ],}

    Konfigurasi Git

    Disarankan untuk mengabaikan file yang dihasilkan oleh Intlayer. Ini memungkinkan Anda menghindari meng-commit file tersebut ke repositori Git Anda.

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

    .gitignore
    # 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.

    Pasang dari VS Code Marketplace

    Ekstensi ini menyediakan:

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

    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.


    Referensi Dokumentasi

    Panduan komprehensif ini menyediakan semua yang Anda butuhkan untuk mengintegrasikan Intlayer dengan Tanstack Start guna aplikasi yang sepenuhnya diinternasionalkan dengan routing yang sadar locale dan dukungan TypeScript.

    Terima notifikasi tentang rilis Intlayer yang akan datang