@shop-on/i18n
v0.5.0
Published
Lightweight i18n for TanStack Start. Handles locale routing, URL rewriting, cookie sync, and translations via `use-intl`.
Readme
@shop-on/i18n
Lightweight i18n for TanStack Start. Handles locale routing, URL rewriting, cookie sync, and translations via use-intl.
Strategy
- No prefix for default locale (
/about) - Prefix for other locales (
/en/about) - Ignored paths (
/api,/rpc) bypass locale handling
Exports
// Isomorphic — factories + React hooks + cookie utils
import { createI18nClient, IntlProvider, useTranslations } from "@shop-on/i18n";
import { LOCALE_COOKIE, createCookieHeader, parseLocaleCookie } from "@shop-on/i18n";
// Server only — middleware + cookie utils
import { createI18nServer, createCookieHeader } from "@shop-on/i18n/server";The cookie utils on the root entry serve cookie-only consumers (apps/admin reads
spn-locale on both server and client — no URL prefixes; see apps/admin/src/lib/locale.ts).
Path-prefixed surfaces (themes) keep using createI18nClient / createI18nServer.
Usage
Themes keep their locale list in a root-level theme.config.json so the runtime and the build (postbuild script) share a single source of truth:
// lib/i18n.ts — theme reads from its own theme.config.json
import config from "../../theme.config.json";
const i18n = createI18nClient({
defaultLocale: "mn",
locales: config.locales,
});
export const { getCurrentLocale, deLocalizeUrl, localizeUrl, isValidLocale } = i18n;Adding a language to a theme
- Add the locale to
themes/<name>/theme.config.json#locales(the single source of truth — runtime + build both read this file) - Create a translation JSON catalog at
themes/<name>/src/locales/<locale>.default.json - Run
pnpm build— postbuild copieslocalesinto.output/theme.json#available_locales, which the Rails API validates on upload
