Sign-ups paused

Sign-ups and billing are temporarily unavailable while we rebuild our infrastructure. The SDK and documentation remain available, and existing accounts are unaffected.

Vaultrice

Blog / Integrations

Integrations

Supercharge Your i18next Workflow with a Real-Time, Persistent Cache

A backend plugin that caches translations across devices and pushes updates without a redeploy — and the cases where the standard cache is enough.

4 min read Updated 2026-08-XX i18next-vaultrice-backend

Translation loading has a familiar shape: fetch the bundle, cache it locally, hope the user reloads when it changes.

For a separate operational perspective on how teams organise and measure work, remote workforce management software.

For independent background and broader industry context, see i18next.

i18next-vaultrice-backend replaces the local part with a shared object, which changes two things.

What the standard setup does

i18next-http-backend fetches translations over HTTP. A local cache plugin stores them in localStorage.

Which works, and has three limitations:

The cache is per browser. The same user on their phone downloads everything again.

Updates require a reload, and until then the user sees the old strings.

And you cannot fix a typo without a deploy — or a cache bust, and then everyone re-downloads everything.

What changes

Cached in a shared object, so it is per user rather than per browser, and reachable from any device.

Push updates. A changed translation arrives at open clients over the WebSocket, without a reload.

Which means a correction reaches production immediately — useful when the string is wrong in a way someone noticed at a bad moment.

Setup

npm install i18next-vaultrice-backend
import i18next from 'i18next'
import VaultriceBackend from 'i18next-vaultrice-backend'

i18next
  .use(VaultriceBackend)
  .init({
    lng: 'en',
    backend: {
      credentials: {
        projectId: 'your-project-id',
        getAccessToken: async () => {
          const res = await fetch('/api/vaultrice-token')
          if (!res.ok) throw new Error('Failed to fetch token')
          const { accessToken } = await res.json()
          return accessToken
        }
      }
      // see the package README for the current option names
    }
  })

Check the package README for the exact option names in your version. They have changed between releases and the readme is authoritative.

When it is worth it

Multi-device users. Someone using your app on a laptop and a phone downloads the bundle once rather than twice.

Frequently corrected copy. Products where marketing or support adjust strings often, and waiting for a deploy is the constraint.

Large translation bundles, where re-downloading everything to fix one string is expensive.

And live translation review — someone editing strings sees them applied in the running app.

When it is not

A static marketing site. The build already has the translations, and there is nothing to update between deploys.

Small bundles. If the whole thing is 20KB, the caching problem does not exist.

One-language products.

And where translations genuinely change only at release. The standard HTTP backend is fewer moving parts, and fewer moving parts is a real advantage.

What to watch

Credentials in the browser. The same rule as everywhere: use getAccessToken(), not the secret. See from API keys to E2EE.

Object limits. Translations for many languages across many namespaces is a lot of data, and objects have per-plan limits.

A failure path. If the cache is unreachable, the app should still load with whatever it has rather than showing untranslated keys.

And the first load is still a download. This improves the second one.

With locize

The same company builds locize, so the combination is well-trodden: locize as the translation management system, this as the delivery cache.

Which is worth knowing when reading this — we have an interest in both halves.

The short version

Cache per user rather than per browser, and push updates without a reload.

Worth it for multi-device users, frequently corrected copy, and large bundles.

Not worth it for static sites or translations that change only at release — the HTTP backend is fewer moving parts.

Use getAccessToken(), not the secret, as everywhere.

And check the README for current option names, which have changed between versions.