Creation:2026-03-20Last update:2026-05-31

    Intlayer dengan Storybook

    Daftar Isi

    Mengapa Intlayer dibandingkan alternatif?

    Dibandingkan dengan solusi utama seperti storybook-react-i18next atau i18next, Intlayer adalah solusi yang hadir dengan pengoptimalan terintegrasi seperti:

    Intlayer dioptimalkan agar berfungsi sempurna dengan Storybook dengan menawarkan dekorator cerita multibahasa, pengalihan lokal, dan semua fitur yang diperlukan untuk meningkatkan internasionalisasi (i18n) di seluruh sistem desain Anda.

    Daripada memuat file JSON berukuran besar ke halaman Anda, muat saja konten yang diperlukan. Intlayer membantu mengurangi ukuran bundle dan halaman Anda hingga 50%.

    Mencakup konten aplikasi Anda memfasilitasi pemeliharaan untuk aplikasi berskala besar. Anda dapat menduplikasi atau menghapus satu folder fitur tanpa beban mental untuk meninjau seluruh basis kode konten Anda. Selain itu, Intlayer diketik sepenuhnya untuk memastikan keakuratan konten Anda.

    Menempatkan konten bersama mengurangi konteks yang diperlukan dengan Model Bahasa Besar (LLM). Intlayer juga dilengkapi dengan serangkaian alat, seperti CLI untuk menguji terjemahan yang hilang,LSP, MCP, dan agent skill, untuk menjadikan pengalaman pengembang (DX) lebih lancar bagi agen AI.

    Gunakan otomatisasi untuk menerjemahkan dalam saluran CI/CD Anda menggunakan LLM pilihan Anda dengan biaya penyedia AI Anda. Intlayer juga menawarkan compiler untuk mengotomatiskan ekstraksi konten, serta platform web untuk membantu menerjemahkan di latar belakang.

    Menghubungkan file JSON berukuran besar ke komponen dapat menyebabkan masalah kinerja dan reaktivitas. Intlayer mengoptimalkan pemuatan konten Anda pada waktu pembuatan.

    Lebih dari sekedar solusi i18n, Intlayer menyediakan editor visual yang dihosting sendiri dan CMS lengkap untuk membantu Anda mengelola konten multibahasa secara real-time, membuat kolaborasi dengan penerjemah, copywriter, dan anggota tim lainnya menjadi lancar. Konten dapat disimpan secara lokal dan/atau jarak jauh.


    Mengapa menggunakan Intlayer dengan Storybook?

    Storybook adalah alat standar industri untuk mengembangkan dan mendokumentasikan komponen UI secara terisolasi. Menggabungkannya dengan Intlayer memungkinkan Anda untuk:

    • Pratinjau setiap lokal langsung di dalam kanvas Storybook menggunakan pengalih bilah alat.
    • Menemukan terjemahan yang hilang sebelum mencapai tahap produksi.
    • Mendokumentasikan komponen multibahasa dengan konten asli yang aman secara tipe, bukan string yang dikodekan secara statis.

    Pengaturan Langkah demi Langkah

    1. Instal Dependensi

      bash
      npm install intlayer react-intlayernpm install vite-intlayer --save-dev
      Paket Peran
      intlayer Inti - konfigurasi, kompilasi konten, CLI
      react-intlayer Pengikatan React - IntlayerProvider, hook useIntlayer
      vite-intlayer Plugin Vite - memantau dan mengompilasi file deklarasi konten

    2. Buat Konfigurasi Intlayer

      Buat intlayer.config.ts di root proyek Anda (atau di dalam paket sistem desain Anda):

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      // tambahkan lebih banyak lokal jika diperlukan    ],    defaultLocale: Locales.ENGLISH,  },  content: {    contentDir: ["./src"], // lokasi file *.content.ts Anda  },};export default config;
      Untuk daftar lengkap opsi, lihat referensi konfigurasi.

    3. Tambahkan Plugin Vite ke Storybook

      Hook viteFinal Storybook memungkinkan Anda memperluas konfigurasi Vite internal. Impor dan tambahkan plugin intlayer() di sana:

      .storybook/main.ts
      import type { StorybookConfig } from "@storybook/react-vite";import { defineConfig, mergeConfig } from "vite";import { intlayer } from "vite-intlayer";const config: StorybookConfig = {  stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],  addons: [    "@storybook/addon-essentials",    // …addons lainnya  ],  framework: {    name: "@storybook/react-vite",    options: {},  },  async viteFinal(baseConfig, { configType }) {    const env = {      command: configType === "DEVELOPMENT" ? "serve" : "build",      mode: configType === "DEVELOPMENT" ? "development" : "production",    } as const;    const viteConfig = defineConfig(() => ({      plugins: [intlayer()],    }));    return mergeConfig(baseConfig, viteConfig(env));  },};export default config;

      Plugin intlayer() memantau file *.content.ts Anda dan membangun kembali kamus secara otomatis setiap kali ada perubahan selama pengembangan Storybook.


    4. Tambahkan Dekorator `IntlayerProvider` dan Bilah Alat Lokal

    5. File preview Storybook adalah tempat yang tepat untuk membungkus setiap story dengan IntlayerProvider dan mengekspos pengalih lokal di bilah alat:

      .storybook/preview.tsx
      import type { Preview, StoryContext } from "@storybook/react";import { IntlayerProvider } from "react-intlayer";const preview: Preview = {  // Bungkus setiap story di dalam IntlayerProvider  decorators: [    (Story, context: StoryContext) => {      const locale = context.globals.locale ?? "en";      return (        <IntlayerProvider locale={locale}>          <Story />        </IntlayerProvider>      );    },  ],  // Ekspos pengalih lokal di bilah alat Storybook  globalTypes: {    locale: {      description: "Lokal yang aktif",      defaultValue: "en",      toolbar: {        title: "Lokal",        icon: "globe",        items: [          { value: "en", title: "English" },          { value: "fr", title: "Français" },          { value: "es", title: "Español" },        ],        dynamicTitle: true,      },    },  },  parameters: {    controls: {      matchers: {        color: /(background|color)$/i,        date: /Date$/i,      },    },  },};export default preview;
      Nilai locale harus sesuai dengan lokal yang dideklarasikan dalam intlayer.config.ts Anda.

      </Step>

      </Steps>

      Mendeklarasikan Konten

      Buat file *.content.ts di samping setiap komponen. Intlayer akan mengambilnya secara otomatis selama proses kompilasi.

      src/components/CopyButton/CopyButton.content.ts
      import { type Dictionary, t } from "intlayer";
      
      const copyButtonContent = {
        key: "copy-button",
        content: {
          label: t({
            en: "Copy content",
            fr: "Copier le contenu",
            es: "Copiar contenido",
          }),
        },
      } satisfies Dictionary;
      
      export default copyButtonContent;
      Untuk format dan fitur deklarasi konten lainnya, lihat dokumentasi deklarasi konten.

      Menggunakan useIntlayer dalam Komponen

      src/components/CopyButton/index.tsx
      "use client";import { type FC } from "react";import { useIntlayer } from "react-intlayer";type CopyButtonProps = {  content: string;};export const CopyButton: FC<CopyButtonProps> = ({ content }) => {  const { label } = useIntlayer("copy-button");  return (    <button      onClick={() => navigator.clipboard.writeText(content)}      aria-label={label.value}      title={label.value}    >      Salin    </button>  );};

      useIntlayer mengembalikan kamus yang telah dikompilasi untuk lokal saat ini yang disediakan oleh IntlayerProvider terdekat. Mengalihkan lokal di bilah alat Storybook akan secara otomatis me-render ulang story dengan terjemahan yang diperbarui.


      Menulis Story untuk Komponen yang di-Internasionalisasi

      Dengan adanya dekorator IntlayerProvider, story Anda akan bekerja sama persis seperti sebelumnya. Bilah alat lokal mengontrol lokal aktif untuk seluruh kanvas:

      src/components/CopyButton/CopyButton.stories.tsx
      import type { Meta, StoryObj } from "@storybook/react";import { CopyButton } from ".";const meta: Meta<typeof CopyButton> = {  title: "Components/CopyButton",  component: CopyButton,  tags: ["autodocs"],  argTypes: {    content: { control: "text" },  },};export default meta;type Story = StoryObj<typeof CopyButton>;/** Story default - ubah lokal di bilah alat untuk melihat pratinjau terjemahan. */export const Default: Story = {  args: {    content: "npm install intlayer react-intlayer",  },};/** Me-render tombol di dalam blok kode, kasus penggunaan dunia nyata yang umum. */export const InsideCodeBlock: Story = {  render: (args) => (    <div style={{ position: "relative", display: "inline-block" }}>      <pre style={{ background: "#1e1e1e", color: "#fff", padding: "1rem" }}>        <code>{args.content}</code>      </pre>      <CopyButton        content={args.content}        style={{ position: "absolute", top: 8, right: 8 }}      />    </div>  ),  args: {    content: "npx intlayer init",  },};
      Setiap story mewarisi global locale dari bilah alat, jadi Anda dapat memverifikasi setiap lokal tanpa mengubah kode story apa pun.

      Menguji Terjemahan dalam Story

      Gunakan fungsi play Storybook untuk menegaskan bahwa teks terjemahan yang benar telah dirender untuk lokal tertentu:

      src/components/CopyButton/CopyButton.stories.tsx
      import type { Meta, StoryObj } from "@storybook/react";import { expect, within } from "@storybook/test";import { CopyButton } from ".";const meta: Meta<typeof CopyButton> = {  title: "Components/CopyButton",  component: CopyButton,  tags: ["autodocs"],};export default meta;type Story = StoryObj<typeof CopyButton>;export const AccessibleLabel: Story = {  args: { content: "Hello World" },  play: async ({ canvasElement }) => {    const canvas = within(canvasElement);    const button = canvas.getByRole("button");    // Verifikasi tombol memiliki nama aksesibel yang tidak kosong    await expect(button).toHaveAccessibleName();    // Verifikasi tombol tidak dinonaktifkan    await expect(button).not.toBeDisabled();    // Verifikasi aksesibilitas keyboard    await expect(button).toHaveAttribute("tabindex", "0");  },};

      Sumber Daya Tambahan