var v=Object.defineProperty;var S=(a)=>a;function R(a,r){this[a]=S.bind(null,r)}var M=(a,r)=>{for(var l in r)v(a,l,{get:r[l],enumerable:!0,configurable:!0,set:R.bind(r,l)})};var O=(a,r)=>()=>(a&&(r=a(a=0)),r);var d=["@contractspec/lib.contracts-spec","@contractspec/lib.translation-runtime"],u=`import { createTranslationRuntime } from '@contractspec/lib.translation-runtime';
import { checkoutMessages } from './translations/checkout.messages';

const runtime = createTranslationRuntime({
  catalogs: [checkoutMessages],
  locale: 'fr-FR',
  fallbackLocales: ['fr', 'en-US'],
  onDiagnostic: (diagnostic) => reportTranslationIssue(diagnostic),
});

const label = runtime.t('checkout.pay', {
  amount: 4200,
  currency: 'EUR',
});`,m=`import { createInstance } from 'i18next';
import {
  createI18nextInitOptions,
  exportContractSpecToI18next,
} from '@contractspec/lib.translation-runtime/i18next';

const exported = exportContractSpecToI18next([checkoutMessages], {
  locale: 'en-US',
  assumeIcuFormatter: true,
});
const { options, diagnostics } = createI18nextInitOptions(exported, {
  lng: 'en-US',
});

const i18next = createInstance();
await i18next.init(options);
reportAdapterDiagnostics(diagnostics);`,h=`// Server: negotiate once, preload catalogs, and serialize the runtime snapshot.
const runtime = createTranslationRuntime({
  catalogs,
  locale: negotiatedLocale,
  fallbackLocales,
});
const snapshot = runtime.createSnapshot();

// Client: hydrate from the same snapshot so locale, resources, and fallback state match.
const hydratedRuntime = createTranslationRuntime({ snapshot });`,g=["Keep TranslationSpec as the source of truth; do not flatten metadata into i18next JSON as the canonical model.","Keep stable bundle identity in TranslationSpec.meta.key and keep BCP 47 language tags in TranslationSpec.locale.","Use ICU messages for plural, select, selectordinal, number, date, currency, list, and relative-time formatting.","Create one runtime per SSR request when tenant, project, or user overrides are involved.","Serialize the same runtime snapshot or exported adapter resources used by the server for hydration.","Configure an ICU-capable i18next formatter plugin when rendering ContractSpec ICU messages through i18next.","Treat adapter diagnostics as release blockers in production pipelines instead of silently rendering raw keys."],f=`You are integrating ContractSpec translations into a production app.
Use @contractspec/lib.contracts-spec/translations as the canonical contract layer and @contractspec/lib.translation-runtime as the runtime layer.
Keep locale variants separate from stable bundle keys, support BCP 47 tags, preserve ICU plural/select/selectordinal messages, and use request-scoped runtime instances for SSR.
If the app already uses i18next, use @contractspec/lib.translation-runtime/i18next only as a downstream adapter. Do not make i18next the canonical translation model. Include diagnostics, fallback behavior, tenant/user override isolation, and hydration snapshot handling in the implementation and tests.`,b=[{title:"Spec layer",body:"TranslationSpec owns keys, locales, domains, versions, owners, fallback declarations, direction, and validation metadata."},{title:"Runtime layer",body:"Runtime instances negotiate locales, apply fallback chains, resolve overrides, cache compiled messages, report diagnostics, and serialize SSR snapshots."},{title:"Adapter layer",body:"The i18next adapter projects ContractSpec specs or snapshots to resources and manifests for caller-owned i18next instances."}];import{CodeBlock as s,InstallCommand as U}from"@contractspec/lib.design-system";import{HStack as y,VStack as n}from"@contractspec/lib.design-system/layout";import{List as w,ListItem as C}from"@contractspec/lib.design-system/list";import{Code as p,H1 as z,H2 as c,H3 as D,P as i,Text as o}from"@contractspec/lib.design-system/typography";import I from"@contractspec/lib.ui-link";import{ChevronRight as K}from"lucide-react";import{jsx as e,jsxs as t}from"react/jsx-runtime";function G(){return t(n,{className:"space-y-8",children:[t(n,{className:"space-y-4",children:[e(o,{className:"editorial-kicker",children:"Runtime and adapters"}),e(z,{className:"font-serif text-4xl tracking-[-0.04em] md:text-5xl",children:"Translation runtime and i18next adapter"}),e(i,{className:"max-w-3xl text-lg text-muted-foreground leading-8",children:"Use ContractSpec as the canonical translation contract layer, then resolve and format messages through a framework-independent runtime. i18next is supported as an optional downstream adapter, not as the source of truth."})]}),t(n,{className:"space-y-4",children:[e(c,{className:"font-bold text-2xl",children:"Install the runtime"}),e(U,{package:d}),t(i,{className:"text-muted-foreground",children:[e(o,{children:"Add "}),e(p,{children:"i18next"}),t(o,{children:[" ","only when an app imports the adapter subpath. Core server, React, React Native, CLI, and test code can use the runtime without loading i18next."]})]})]}),e(y,{className:"grid gap-4 md:grid-cols-3",children:b.map((a)=>t(n,{className:"card-subtle space-y-2 p-5",children:[e(D,{className:"font-semibold text-lg",children:a.title}),e(i,{className:"text-muted-foreground text-sm leading-7",children:a.body})]},a.title))}),t(n,{className:"space-y-4",children:[e(c,{className:"font-bold text-2xl",children:"Use the ContractSpec runtime"}),t(i,{className:"text-muted-foreground",children:[e(o,{children:"The runtime consumes canonical "}),e(p,{children:"TranslationSpec[]"}),t(o,{children:[" ","catalogs, supports BCP 47 tags such as en-US, ar-EG, and zh-Hans, and delegates ICU parsing/formatting to a mature formatter engine instead of a custom parser."]})]}),e(s,{language:"typescript",code:u})]}),t(n,{className:"space-y-4",children:[e(c,{className:"font-bold text-2xl",children:"Project to i18next when needed"}),t(i,{className:"text-muted-foreground",children:[e(o,{children:"Import from "}),e(p,{children:"@contractspec/lib.translation-runtime/i18next"}),t(o,{children:[" ","to export resources by locale, namespace, and message key. The namespace defaults to the stable bundle key, dotted message keys stay flat with keySeparator false, and metadata remains in a sidecar manifest."]})]}),e(s,{language:"typescript",code:m})]}),t(n,{className:"space-y-4",children:[e(c,{className:"font-bold text-2xl",children:"SSR, streaming, and hydration"}),e(i,{className:"text-muted-foreground",children:"Negotiate locale on the server, preload catalogs needed for streamed content, and hydrate the client from the same serialized state. Never let client-only language detection choose a different locale after the server has rendered."}),e(s,{language:"typescript",code:h})]}),t(n,{className:"space-y-4",children:[e(c,{className:"font-bold text-2xl",children:"Production checklist"}),e(w,{className:"list-disc space-y-2 pl-6 text-muted-foreground",children:g.map((a)=>e(C,{children:a},a))})]}),t(n,{className:"space-y-4 rounded-xl border border-border p-6",children:[e(c,{className:"font-bold text-2xl",children:"Agent implementation prompt"}),e(i,{className:"text-muted-foreground",children:"Use this prompt when asking an agent to wire translations into a web, server, or React Native surface without losing ContractSpec ownership."}),e(s,{language:"markdown",code:f})]}),t(y,{className:"flex flex-wrap items-center gap-4 pt-4",children:[e(I,{href:"/docs/libraries/contracts",className:"btn-ghost",children:e(o,{children:"Translation contracts"})}),t(I,{href:"/docs/libraries/design-system",className:"btn-primary",children:[e(o,{children:"Design-system integration"}),e(K,{size:16})]})]})]})}export{G as LibrariesTranslationRuntimePage};
