Skip to content

SSR Hydration

Problem

You need server-rendered translation output and matching client state without shipping catalog loaders in page data. Use serialize() on the server and the state option on the client.

Solution

Create server state from loaded catalogs, then build a client instance from the payload.

ts
import { createI18n } from '@vielzeug/lingua';

const serverI18n = createI18n({
  catalogs: { en: { title: 'Server title' } },
  locale: 'en',
});

try {
  const state = serverI18n.serialize();
  const payload = JSON.stringify(state);
  const clientI18n = createI18n({ state: JSON.parse(payload) as typeof state });

  try {
    console.log(clientI18n.translate('title'));
  } finally {
    clientI18n.dispose();
  }
} finally {
  serverI18n.dispose();
}

Pitfalls

  • Serialize after each needed lazy catalog resolves.
  • Do not expect loader functions in hydrated state; state contains raw catalogs only.
  • The client restores the serialized locale unless you pass an explicit override.
  • Pass fallback and missing-message options when client behavior differs from defaults.