Runtime SDKs

i18next backend

@transglot/i18next-backend: an i18next backend plugin that loads your published bundles from the CDN, so existing t() and Trans call sites keep working.

@transglot/i18next-backend is a backend plugin for i18next 23 or later. i18next keeps doing interpolation, plurals and lookups; the plugin changes where the resources come from. It uses @transglot/runtime for the request, so it shares its authentication, ETag revalidation, rate-limit retries and error types.

Use it instead of @transglot/react-i18n, not with it: this package feeds i18next (and react-i18next on top of it), while @transglot/react-i18n is transglot's own React adapter.

Install

npm install @transglot/i18next-backend

i18next is a peer dependency. @transglot/runtime is installed with the plugin.

Minimal setup

src/i18n.ts
import { createTransglotBackend } from '@transglot/i18next-backend';
import i18next from 'i18next';

await i18next
  .use(
    createTransglotBackend({
      baseUrl: 'https://api.transglot.ai',
      project: 42,
      cdnKey: 'taicdn_your_key',
      authIn: 'query',
    }),
  )
  .init({
    lng: 'en',
    fallbackLng: 'en',
    ns: ['translation'],
    defaultNS: 'translation',
  });

i18next.t('home.title');

The plugin is also the package's default export, so you can register the class and pass its options through i18next's backend setting:

src/i18n.ts
import TransglotBackend from '@transglot/i18next-backend';
import i18next from 'i18next';

await i18next.use(TransglotBackend).init({
  lng: 'en',
  ns: ['translation'],
  backend: {
    baseUrl: 'https://api.transglot.ai',
    project: 42,
    cdnKey: 'taicdn_your_key',
    authIn: 'query',
  },
});

When you pass options both ways, they are merged and the backend values win.

In the browser

Pass authIn: 'query' when i18next runs in a browser. The plugin fetches each locale once and revalidates it on later reads, and the CDN does not answer the CORS preflight that revalidation needs, so in a browser a later read of a locale already loaded (for example a namespace loaded on demand) fails. See In a browser.

How bundles map to i18next

The CDN serves one bundle per locale. i18next asks for one language and one namespace at a time, and namespaceMode decides what each request gets:

  • single (default): every namespace gets the whole bundle. Use it when your app has one namespace, such as i18next's default translation.
  • perNamespace: the bundle's top-level keys are the namespaces, and a request for common gets the common object. Use it when you keep several namespaces in one project and call t('common:save'). A namespace with no matching top-level object gets an empty resource, so its keys fall back the way i18next normally handles missing keys.
createTransglotBackend({
  baseUrl: 'https://api.transglot.ai',
  project: 42,
  cdnKey: 'taicdn_your_key',
  namespaceMode: 'perNamespace',
});

The values reach i18next unchanged, with their nesting kept. The plugin does not flatten keys or rewrite placeholders, and it removes top-level @-prefixed members (ARB metadata). So:

  • Interpolation is i18next's: {{name}} placeholders in your strings work as they did in your files.
  • Plurals are i18next's suffix keys (items_one, items_other), which transglot stores and publishes as ordinary keys. ICU plural messages such as {count, plural, one {...} other {...}} are not interpreted by i18next and render as written; use @transglot/react-intl for ICU.
  • Delivery format: use json_nested, which matches i18next's default keySeparator, or json_flat with keySeparator: false in your i18next options. Set it in Delivery format on the project's Runtime delivery (CDN) card.

Options

Prop

Type

API

ExportDescription
createTransglotBackend(options)Returns a configured TransglotI18nextBackend to pass to i18next.use().
TransglotI18nextBackendThe plugin class (also the default export). new TransglotI18nextBackend(options?); options can come from i18next's backend setting instead.
bundleToResources(rawBody, namespace, mode?)Turns a bundle body into the resources for one namespace, as the plugin does. Throws RuntimeError (unsupported-format) for a body that is not a JSON object.
RuntimeErrorThe error type, re-exported from the runtime.

Types: TransglotBackendOptions, NamespaceMode, I18nextResources.

Errors

The plugin never throws from a read. A failed load is passed to i18next's read callback as a RuntimeError, so i18next's own retry and logging apply. The slugs are those of the JavaScript runtime, plus:

slugWhen
backend-misconfiguredbaseUrl, project or cdnKey is missing after merging both option sources. Thrown when i18next initializes the plugin.
backend-uninitializedi18next asked for resources before it initialized the plugin.
unsupported-formatThe bundle is not a JSON object. Set a JSON-family delivery format.

On this page