xPulse
πŸ‡¬πŸ‡§ EN

Guide β€” Making an App Multilingual

1. Install the package

npm install @xpulse/i18n --registry=https://npm.xpulse.one

2. Configure `xpulse.json` in your app

Minimal configuration (DE as default, DE + EN supported):

{
"i18n": {
"supported": ["de", "en"],
"default": "de"
}
}

Full options:

{
"i18n": {
"supported": ["de", "en"],
"default": "de",
"use-seo": true,
"exclude": ["/_theme/*", "/_logger/*", "/_debug/*", "/api/*", "/health"],
"paths": {
"translations": "src/translations/"
}
}
}

3. Service loader

@xpulse/i18n is loaded automatically via the service loader once the package is installed. The package's own xpulse.json already declares the service entry:

{
"service": {
"xpulse-i18n": { "load": true, "depends": ["xpulse-router"] }
}
}

No manual init() call needed.

4. Create translation files

Structure under src/translations/:

src/translations/
de/
platform.index.json
platform.footer.json
en/
platform.index.json
platform.footer.json

Format: flat key-value, variables as {key}:

{
"tagline": "Private Tools. No Server. No Compromises.",
"cta": "Get started",
"status.days": "{n} day{s} remaining"
}

5. Add the lang switcher to your template

On the <html> tag:

<html lang="{% htmlLang(_route) %}">

Lang switcher anywhere in the layout:

{% langSwitcher(_route.path) %}

Output:

<div class="xpulse-lang-switcher">
<a href="/tool/chat/"
onclick="localStorage.setItem('xpulse_lang','de')"
class="xpulse-lang-switcher__option">DE</a>
<a href="/en/tool/chat/"
onclick="localStorage.setItem('xpulse_lang','en')"
class="xpulse-lang-switcher__option xpulse-lang-switcher__option--active"
aria-current="true">EN</a>
</div>

6. Style the switcher

The classes xpulse-lang-switcher, xpulse-lang-switcher__option and xpulse-lang-switcher__option--active can be styled freely, e.g.:

.xpulse-lang-switcher {
display: flex;
gap: 0.5rem;
}
.xpulse-lang-switcher__option {
opacity: 0.5;
text-decoration: none;
}
.xpulse-lang-switcher__option--active {
opacity: 1;
font-weight: bold;
}

7. Read translated strings in a handler

import i18n from '@xpulse/i18n';
// Inside a route handler:
const lang = i18n.lang(req);
const tagline = i18n.t('tagline', lang);
const status = i18n.t('status.days', lang, { n: 3, s: 's' });

What happens automatically

en/guide.md 2026-04-22