Internationalization (i18n)
Coralite leverages standard Web Platform APIs and explicit dynamic page routing patterns for internationalization. Rather than adding custom framework abstraction layers or proprietary translation utilities, Coralite provides simple building blocks that work seamlessly with native JavaScript features like Intl and JSON imports.
1. Locale Routing #
Organize your localized pages using directory parameters such as pages/[lang]/ instead of language-prefixed filenames. This ensures every locale shares the same page template and logic structure while generating discrete localized routes at build time.
pages/
[lang]/
index.html
about.html
Use flat named exports with the paths function to enumerate supported locales and inject the active locale parameter into the page state via the server block:
const locales = ['en', 'fr', 'de', 'ar']
export function paths () {
return locales.map(lang => ({ lang }))
}
export function server ({ route }) {
return {
lang: route.params.lang,
supported: locales.includes(route.params.lang)
}
}
Using pages/[lang]/ guarantees that locale paths are statically rendered as separate pages (for example /en/, /fr/, /de/, and /ar/) without duplicating template files.
2. Message Bundles #
Translation bundles can be stored in standard JSON files and imported directly using ESM JSON import attributes. In the page's server() block, select the dictionary matching the active locale route parameter.
import messages from '../../../content/messages.json' with { type: 'json' }
export function server ({ route }) {
return {
t: messages[route.params.lang] ?? messages.en
}
}
In your HTML template, bind translation strings using flat template tokens:
<h1></h1>
Coralite template tokens must be flat tokens (e.g., or single-level ). Deep nested access such as is not supported in templates. Flatten your JSON translation structure or derive nested strings using a getters block.
3. Formatting #
For formatting dates, numbers, currencies, or lists, rely directly on browser and Node.js native Intl.* APIs inside getters or server(). Do not wrap Intl in framework-specific helper utilities—native platform APIs are already built-in and performant.
export const getters = {
formattedDate: ({ state }) =>
new Intl.DateTimeFormat(state.lang, { dateStyle: 'long' }).format(state.publishedAt),
formattedPrice: ({ state }) =>
new Intl.NumberFormat(state.lang, { style: 'currency', currency: 'EUR' }).format(state.price)
}
4. Right-to-Left (RTL) Support #
Support right-to-left languages (like Arabic or Hebrew) by determining text direction in your server() function and binding the dir attribute on the <html> element:
export function server ({ route }) {
return {
dir: route.params.lang === 'ar' ? 'rtl' : 'ltr'
}
}
<html lang="" dir="">
</html>
When writing component styles, use CSS logical properties instead of physical directions. For example, use margin-inline-start instead of margin-left, and padding-inline-end instead of padding-right. This ensures styles adapt automatically when switching between LTR and RTL directions without needing direction-specific CSS overrides.
5. What Coralite Does Not Provide #
To remain lightweight, predictable, and standards-compliant, Coralite intentionally does not ship built-in abstractions for several i18n concerns:
- No plural rule engine: Use native
Intl.PluralRulesdirectly in your getters or server functions. - No Accept-Language detection: Language detection and initial redirection should be performed by host servers (e.g., Cloudflare Workers, Nginx, Vercel Edge) or lightweight client-side scripts.
- No message extraction tooling: Use standard build-time script utilities or external tools if you need to scan source files for missing translation keys.
- No translation management: Use external localization services (TMS) or translation platforms to manage dictionary translation workflows.
Next: Explore Page Variables to learn more about routing context in pages.