Localization
Keep your block's language in sync with the portal, live.
The portal knows the user's language; your block should follow it. Read the
initial language from the session and subscribe to
onLocaleUpdate so switching language in the portal updates the block instantly,
no iframe reload.
session.lang: the initial language
After initialize(), session.lang holds the user's
language code (e.g. 'en', 'de'). Use it to set your initial locale:
import { initialize } from '@epilot/spark-sdk'
const session = await initialize()
i18n.changeLanguage(session.lang ?? 'en')onLocaleUpdate(handler)
Subscribe to language changes pushed by the portal. The SDK keeps the cached
session's lang in sync internally; this hook lets your i18n layer react. Returns
an Unsubscribe function.
import { onLocaleUpdate } from '@epilot/spark-sdk'
const unsubscribe = onLocaleUpdate((lang) => {
i18n.changeLanguage(lang)
})
// later
unsubscribe()Full React pattern
A HEMS's i18n-provider.tsx combines both: one effect tracks the session
language, another subscribes to live updates and cleans up on unmount.
import { onLocaleUpdate } from '@epilot/spark-sdk'
import { useEffect, type ReactNode } from 'react'
import { I18nextProvider } from 'react-i18next'
import { DEFAULT_LANGUAGE, i18n } from '@/i18n/config'
import { useSparkSession } from './spark-session-context'
export function I18nProvider({ children }: { children: ReactNode }) {
const session = useSparkSession()
const sessionLang = session.lang
// Initial language + reacts if the session object changes
useEffect(() => {
void i18n.changeLanguage(sessionLang ?? DEFAULT_LANGUAGE)
}, [sessionLang])
// Live updates pushed by the portal
useEffect(() => {
return onLocaleUpdate((lang) => {
void i18n.changeLanguage(lang)
})
}, [])
return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>
}Returning the result of
onLocaleUpdatedirectly fromuseEffectwires the unsubscribe to the cleanup phase, so no extra bookkeeping is needed.