Đặt câu hỏi và nhận tóm tắt tài liệu bằng cách tham chiếu trang này và nhà cung cấp AI bạn chọn
Lịch sử phiên bản
- "Cập nhật cách sử dụng API useIntlayer của Solid sang truy cập thuộc tính trực tiếp"v8.9.04/5/2026
- "Init doc"v8.4.520/3/2026
Nội dung của trang này đã được dịch bằng AI.
Xem phiên bản mới nhất của nội dung gốc bằng tiếng AnhIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Intlayer với Storybook
Mục lục
Tại sao Intlayer thay thế các lựa chọn thay thế?
So với các giải pháp chính như storybook-react-i18next hay i18next, Intlayer là giải pháp đi kèm với các tính năng tối ưu hóa tích hợp như:
Intlayer được tối ưu hóa để hoạt động hoàn hảo với Storybook bằng cách cung cấp trình trang trí câu chuyện đa ngôn ngữ, chuyển đổi ngôn ngữ và tất cả các tính năng cần thiết để mở rộng quy mô quốc tế hóa (i18n) trên hệ thống thiết kế của bạn.
Thay vì tải các tệp JSON lớn vào trang của bạn, hãy chỉ tải nội dung cần thiết. Intlayer giúp giảm tới 50% kích thước bundle và kích thước trang.
Xác định phạm vi nội dung ứng dụng của bạn tạo điều kiện bảo trì cho các ứng dụng quy mô lớn. Bạn có thể sao chép hoặc xóa một thư mục tính năng mà không phải lo lắng về việc xem lại toàn bộ cơ sở mã nội dung của mình. Ngoài ra, Intlayer được nhập đầy đủ để đảm bảo tính chính xác cho nội dung của bạn.
Nội dung cùng định vị giảm ngữ cảnh cần thiết của Mô hình ngôn ngữ lớn (LLM). Intlayer cũng đi kèm một bộ công cụ, chẳng hạn như CLI để kiểm tra các bản dịch bị thiếu,LSP, MCP và agent Skills, để giúp trải nghiệm của nhà phát triển (DX) trở nên mượt mà hơn nữa đối với các tác nhân AI.
Sử dụng tính năng tự động hóa để dịch trong quy trình CI/CD của bạn bằng cách sử dụng LLM mà bạn chọn với chi phí do nhà cung cấp AI của bạn chi trả. Intlayer cũng cung cấp trình biên dịch để tự động trích xuất nội dung cũng như nền tảng web để giúp dịch ở chế độ nền.
Việc kết nối các tệp JSON lớn với các thành phần có thể dẫn đến các vấn đề về hiệu suất và khả năng phản hồi. Intlayer tối ưu hóa việc tải nội dung của bạn tại thời điểm build.
Không chỉ là giải pháp i18n, Intlayer còn cung cấp trình chỉnh sửa trực quan và CMS đầy đủ để giúp bạn quản lý nội dung đa ngôn ngữ của mình trong thời gian thực, giúp việc cộng tác với người dịch, người viết quảng cáo và các thành viên khác trong nhóm trở nên liền mạch. Nội dung có thể được lưu trữ cục bộ và/hoặc từ xa.
Tại sao nên sử dụng Intlayer với Storybook?
Storybook là công cụ tiêu chuẩn trong ngành để phát triển và lập tài liệu cho các thành phần UI một cách độc lập. Việc kết hợp nó với Intlayer cho phép bạn:
- Xem trước mọi ngôn ngữ trực tiếp bên trong canvas của Storybook bằng trình chuyển đổi trên thanh công cụ.
- Phát hiện các bản dịch còn thiếu trước khi chúng được đưa vào sản xuất.
- Lập tài liệu cho các thành phần đa ngôn ngữ với nội dung thực tế, an toàn về kiểu dữ liệu thay vì các chuỗi được mã hóa cứng.
Thiết lập từng bước
Cài đặt các phụ thuộc
Sao chép mã vào clipboard
npm install intlayer react-intlayernpm install vite-intlayer --save-devMở bảng trong một cửa sổ bật lên để xem toàn bộ nội dung dữ liệu một cách rõ ràng
| Gói | Vai trò |
|---|---|
intlayer | Cốt lõi - cấu hình, biên dịch nội dung, CLI |
react-intlayer | Liên kết React - IntlayerProvider, hook useIntlayer |
vite-intlayer | Plugin Vite - theo dõi và biên dịch các tệp khai báo nội dung |
Tạo cấu hình Intlayer
Tạo intlayer.config.ts tại thư mục gốc của dự án (hoặc bên trong gói hệ thống thiết kế của bạn):
Sao chép mã vào clipboard
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, // thêm các ngôn ngữ khác nếu cần ], defaultLocale: Locales.ENGLISH, }, content: { contentDir: ["./src"], // nơi chứa các tệp *.content.ts của bạn },};export default config;Để xem danh sách đầy đủ các tùy chọn, hãy tham khảo tài liệu cấu hình.
Thêm Plugin Vite vào Storybook
Hook viteFinal của Storybook cho phép bạn mở rộng cấu hình Vite nội bộ. Nhập và thêm plugin intlayer() tại đó:
Sao chép mã vào clipboard
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", // …các addon khác ], 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() theo dõi các tệp *.content.ts của bạn và tự động xây dựng lại các từ điển bất cứ khi nào chúng thay đổi trong quá trình phát triển trên Storybook.
Thêm Decorator `IntlayerProvider` và Thanh công cụ Ngôn ngữ
Tệp preview của Storybook là nơi thích hợp để bao bọc mọi câu chuyện với IntlayerProvider và hiển thị trình chuyển đổi ngôn ngữ trên thanh công cụ:
Sao chép mã vào clipboard
import type { Preview, StoryContext } from "@storybook/react";import { IntlayerProvider } from "react-intlayer";const preview: Preview = { // Bao bọc mọi câu chuyện bên trong IntlayerProvider decorators: [ (Story, context: StoryContext) => { const locale = context.globals.locale ?? "en"; return ( <IntlayerProvider locale={locale}> <Story /> </IntlayerProvider> ); }, ], // Hiển thị trình chuyển đổi ngôn ngữ trên thanh công cụ Storybook globalTypes: { locale: { description: "Ngôn ngữ đang kích hoạt", defaultValue: "en", toolbar: { title: "Ngôn ngữ", 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;Các giá trịlocalephải khớp với các ngôn ngữ được khai báo trongintlayer.config.tscủa bạn.
</Step>
</Steps>
Khai báo nội dung
Tạo tệp *.content.ts bên cạnh mỗi thành phần. Intlayer sẽ tự động nhận diện nó trong quá trình biên dịch.
Sao chép mã vào clipboard
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;Để biết thêm các định dạng khai báo nội dung và tính năng khác, hãy xem tài liệu khai báo nội dung.
Sử dụng useIntlayer trong một thành phần
Sao chép mã vào clipboard
"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} > Sao chép </button> );};useIntlayer trả về từ điển đã biên dịch cho ngôn ngữ hiện tại được cung cấp bởi IntlayerProvider gần nhất. Việc chuyển đổi ngôn ngữ trên thanh công cụ Storybook sẽ tự động hiển thị lại câu chuyện với các bản dịch đã cập nhật.
Viết các câu chuyện (Story) cho các thành phần đa ngôn ngữ
Với decorator IntlayerProvider đã được thiết lập, các câu chuyện của bạn sẽ hoạt động chính xác như trước đây. Thanh công cụ ngôn ngữ kiểm soát ngôn ngữ đang hoạt động cho toàn bộ canvas:
Sao chép mã vào clipboard
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>;/** Câu chuyện mặc định - chuyển đổi ngôn ngữ trên thanh công cụ để xem trước các bản dịch. */export const Default: Story = { args: { content: "npm install intlayer react-intlayer", },};/** Hiển thị nút bên trong một khối mã, một trường hợp sử dụng thực tế phổ biến. */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", },};Mỗi câu chuyện kế thừa biến toàn cục locale từ thanh công cụ, vì vậy bạn có thể xác minh mọi ngôn ngữ mà không cần thay đổi bất kỳ mã nguồn câu chuyện nào.
Kiểm thử các bản dịch trong các câu chuyện
Sử dụng các hàm play của Storybook để khẳng định rằng văn bản được dịch chính xác được hiển thị cho một ngôn ngữ nhất định:
Sao chép mã vào clipboard
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"); // Xác minh nút có tên dễ tiếp cận không trống await expect(button).toHaveAccessibleName(); // Xác minh nút không bị vô hiệu hóa await expect(button).not.toBeDisabled(); // Xác minh khả năng tiếp cận bằng bàn phím await expect(button).toHaveAttribute("tabindex", "0"); },};