DocsReact (Vite, CRA)4 min read

React (Vite, CRA)

One instance for the app, one context provider, one hook. The only React-specific problem is repaint: a translation that arrives after the first render has to make the tree re-render.

siyak.ts
import { init, type Siyak } from 'siyak-js';

export const siyak: Siyak = init({
  apiKey: import.meta.env.VITE_SIYAK_KEY,
  endpoint: import.meta.env.VITE_SIYAK_URL,
  target: 'ar',
  // cache:false in tests and Storybook; leave localStorage on in the app.
  cache: import.meta.env.MODE === 'test' ? false : undefined,
});
SiyakProvider.tsx
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
import { siyak } from './siyak';

const Ctx = createContext(siyak);

export function SiyakProvider({ children }: { children: ReactNode }) {
  const [ready, setReady] = useState(false);
  useEffect(() => {
    void siyak.preload();          // one request, every known string
    siyak.onReady.then(() => setReady(true));
  }, []);
  return <Ctx.Provider value={siyak}>{children}</Ctx.Provider>;
  // ready is only here to force one repaint after the batch lands.
}

export const useSiyak = () => useContext(Ctx);
Checkout.tsx
const { t } = useSiyak();

<button>{t('Continue', 'screen:checkout')}</button>
  • Strict Mode runs effects twice in dev; the SDK coalesces identical misses, so the second mount costs nothing.
  • If you would rather not repaint the whole tree, subscribe per string with useSyncExternalStore — the instance queue is not an event emitter, so gate on the provider's ready flag or on a version counter you keep yourself.
  • Add http://localhost:5173 (and any preview host) to the project's allowed domains in the dashboard.