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.