SvelteKit で使う Langsys

どの環境でもパターンは同じです。サーバーがカタログを1回だけ取得し(書き込みキーはサーバー側に保持)、クライアントは読み取り専用キーを使ってそのシードから langsys-js-svelte を初期化します。重複した取得は発生しません。翻訳そのものはブラウザー上で行われます。サーバーが送信する HTML は基準言語のままで、検索エンジンにインデックスされるのもこの言語です。ページは読み込み時に訪問者の言語へ切り替わります。

1 · +layout.server.ts でカタログを読み込む

サーバーの load 関数はページのレンダリングごとにカタログを1回取得し、SvelteKit がそれをページデータにシリアライズします。書き込みキーはサーバー側にとどまり、クライアントには読み取り専用キーが渡されます。どちらも同じカタログを参照し、クライアントは最初の取得をスキップするだけです。

// src/routes/+layout.server.ts
import { LANGSYS_API_KEY, LANGSYS_PROJECT_ID } from '$env/static/private';

export const load = async ({ fetch }) => {
  const locale = 'en-US'; // from cookie / Accept-Language
  const res = await fetch(
    `https://api.langsys.dev/api/projects/${LANGSYS_PROJECT_ID}/translations?locale=${locale}`,
    { headers: { 'x-Authorization': LANGSYS_API_KEY } }
  );
  const { data: translations } = await res.json();
  return { locale, translations };
};

2 · +layout.svelteで初期化する

標準的な Svelte の writable がロケールストアになり、Svelte バインディングが SDK 用にそれを適合させます。Init はシード済みのカタログを使って onMount 内で実行されるため、同じデータを二重に取得することはありません。onMount が実行されると、テキストは基準言語から訪問者の言語に切り替わります。

<!-- src/routes/+layout.svelte -->
<script>
  import { onMount } from 'svelte';
  import { writable } from 'svelte/store';
  import { LangsysApp } from 'langsys-js-svelte';
  import { PUBLIC_LANGSYS_API_KEY, PUBLIC_LANGSYS_PROJECT_ID } from '$env/static/public';

  export let data;

  const locale = writable(data.locale);

  onMount(() => {
    LangsysApp.init({
      projectid: PUBLIC_LANGSYS_PROJECT_ID,
      key: PUBLIC_LANGSYS_API_KEY, // read-only
      UserLocaleStore: locale,
      initialTranslations: data.translations,
      initialTranslationsLocale: data.locale,
      ssrTokenStrategy: 'client',
    });
  });
</script>

<slot />

3 · 以下のどこでも使用する

ここからは通常の Svelte SDK です。どのコンポーネントでも $t を使用でき(シグナルは Svelte のストアの規約をネイティブに満たします)、$locale = 'fr-FR' でアプリ全体の言語を切り替えられます。

<script>
  import { t } from 'langsys-js-svelte';
</script>

<h1>{$t('Welcome to our store', 'Home')}</h1>
ドキュメントとラーニングセンターを検索