Langsys với Next.js
Mô hình này giống nhau ở mọi nơi: máy chủ tải danh mục một lần (khóa ghi luôn nằm ở phía máy chủ), còn máy khách khởi tạo langsys-js-react từ dữ liệu nạp sẵn đó bằng khóa chỉ đọc — không tải trùng lặp. Việc dịch diễn ra ngay trong trình duyệt: HTML do máy chủ gửi về dùng ngôn ngữ gốc, cũng là nội dung mà các công cụ tìm kiếm lập chỉ mục, và trang sẽ chuyển sang ngôn ngữ của khách truy cập khi tải xong.
1 · Tải danh mục bản dịch trên máy chủ
Một Server Component lấy danh mục bằng fetch thuần — không cần SDK trên máy chủ. Khóa ghi được giữ ở máy chủ; máy khách chỉ nhận khóa chỉ đọc. Cả hai phía đều thấy cùng một danh mục — máy khách chỉ bỏ qua lần fetch ban đầu.
// app/layout.tsx (Server Component)
import type { iCategories } from 'langsys-js-react';
import { LangsysClient } from './LangsysClient';
async function getTranslations(locale: string): Promise<iCategories> {
const res = await fetch(
`https://api.langsys.dev/api/projects/${process.env.LANGSYS_PROJECT_ID}/translations?locale=${locale}`,
{ headers: { 'x-Authorization': process.env.LANGSYS_API_KEY! } }
);
const result = await res.json();
return result.data as iCategories;
}
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const locale = 'en-US'; // from cookie / Accept-Language / route segment
const translations = await getTranslations(locale);
return (
<html lang={locale}>
<body>
<LangsysClient
locale={locale}
translations={translations}
projectId={process.env.LANGSYS_PROJECT_ID!}
apiKey={process.env.NEXT_PUBLIC_LANGSYS_API_KEY!} // read-only
>
{children}
</LangsysClient>
</body>
</html>
);
} 2 · Khởi tạo ở phía client
Một lớp bao 'use client' nhỏ khởi tạo SDK trong trình duyệt cùng danh mục đã được nạp sẵn, nên SDK khởi động mà không cần tải thêm gì. Văn bản sẽ chuyển từ ngôn ngữ gốc sang ngôn ngữ của khách truy cập khi hiệu ứng này chạy.
// app/LangsysClient.tsx
'use client';
import { useEffect, type ReactNode } from 'react';
import { LangsysApp, useLocaleStore, type iCategories } from 'langsys-js-react';
export function LangsysClient(props: {
locale: string;
translations: iCategories;
projectId: string;
apiKey: string;
children: ReactNode;
}) {
const [, , localeStore] = useLocaleStore(props.locale);
useEffect(() => {
LangsysApp.init({
projectid: props.projectId,
key: props.apiKey,
UserLocaleStore: localeStore,
initialTranslations: props.translations,
initialTranslationsLocale: props.locale,
ssrTokenStrategy: 'client',
});
}, [localeStore, props.projectId, props.apiKey, props.translations, props.locale]);
return <>{props.children}</>;
} 3 · Dùng ở bất kỳ đâu bên dưới
Từ đây trở đi, đó chính là SDK React thông thường: dùng useT() trong bất kỳ Client Component nào, chuyển đổi ngôn ngữ thông qua cùng một store. Hãy giữ một store ngôn ngữ duy nhất cho ứng dụng (được tạo ở nơi bạn gọi init) và truyền setLocale xuống các thành phần con, thay vì tạo store mới trong những cây thành phần không liên quan.
'use client';
import { useT } from 'langsys-js-react';
export function Hero() {
const t = useT();
return <h1>{t('Welcome to our store', 'Home')}</h1>;
}