Pages
Contents
Spec β @xpulse/i18n
Status: ACCEPTED Β· March 2026 Dependencies:
@xpulse/event,@xpulse/config,@xpulse/routerOptional:@xpulse/template
Principles
- URL is source of truth β
/doc/...= default language,/en/doc/...= explicit EN - No cookie, no server state β language preference is stored in
localStorage(client) - No build step β locale JSON files are loaded at runtime
- Opt-in for other packages β packages that don't need i18n are unaffected
Route wrapping
@xpulse/i18n wraps router.register() during its own init.
All subsequent route registrations (doc, controller, ...) are automatically extended
with /:lang/ variants β regardless of their init order.
| @xpulse/router:init |
| βββ router.register() = originalRegister() |
| @xpulse/i18n:init (depends: ["xpulse-router"]) |
| βββ router.register() = wrapper() |
| @xpulse/doc:init |
| βββ router.register('GET', '/doc/...', handler) |
| βββ wrapper automatically registers: |
| GET /doc/... req.lang = detect(req) |
| GET /de/doc/... req.lang = 'de' |
| GET /en/doc/... req.lang = 'en' |
FOUC redirect script
Inline script in <head>, injected into all HTML responses via http:response:before:
| (function(){try{ |
| var l=localStorage.getItem('xpulse_lang'); |
| var s=["en"]; // non-default langs |
| if(l&&s.includes(l)&&!location.pathname.startsWith('/'+l+'/')){ |
| location.replace('/'+l+location.pathname+location.search); |
| } |
| }catch(e){}})(); |
No FOUC β the browser never sees the wrong language version.
SEO
With use-seo: true, automatically injected into all HTML responses:
| <link rel="alternate" hreflang="de" href="https://xpulse.one/tool/chat/" /> |
| <link rel="alternate" hreflang="en" href="https://xpulse.one/en/tool/chat/" /> |
| <link rel="alternate" hreflang="x-default" href="https://xpulse.one/tool/chat/" /> |
Package structure
| @xpulse/i18n/ |
| src/ |
| index.js β init, lang, t, router-wrap |
| detect.js β detectLang, stripLang, langFromPath |
| middleware.js β langHandler, detectHandler, hookResponses |
| template-methods/ |
| lang-switcher.js β langSwitcher() |
| html-lang.js β htmlLang() |
| xpulse.json |
| package.json |