i18n API

Vue APIs come from ubean/client (auto-imported). Handler APIs come from ubean/i18n (@ubean/i18n).

Vue — ubean/client

APIDescription
useI18n()vue-i18n Composition API (t / d / n / tm / locale / …), imported from vue-i18n directly
setLocale(code)Load messages, write cookie, router.replace(switchLocalePath)
useLocalePath()(path, locale?) => localized path
useSwitchLocalePath()(locale) => current route in that locale
useLocaleRoute()Alias of useLocalePath
useLocaleHead()Reactive hreflang / canonical / og:locale tags
getI18nRuntimeConfig()Resolved { defaultLocale, locales, strategy, … }
<Link locale="zh">Localize to for a specific locale
<script setup lang="ts">
const { t, locale } = useI18n();
const localePath = useLocalePath();

await setLocale('zh');
</script>

Do not assign locale.value as the public switch API. In client code, import useI18n from vue-i18n (or rely on auto-import).

Server — ubean/i18n

APIDescription
t(key, …) / d() / n()Translate / format inside request ALS
runWithI18n(scope, fn)Run fn in an ALS scope (tests / internal)
getRequestLocale(c)Locale set by the auto middleware (c.get('locale'))
compileLocalePaths(path, cfg)Shared vue / Hono path compiler
localizePath / switchLocalePath / extractLocaleFromPathPure path helpers
createI18nMiddleware(options)Used by createUbeanApp; you rarely call this
buildLocaleHead(input)hreflang / canonical / og:locale
setLocaleMessages / getLocaleMessagesCatalog used by @intlify/core

t() throws outside ALS. There is no process-global locale.

import { defineHandler } from 'ubean/server';
import { t, getRequestLocale } from 'ubean/i18n';

export const GET = defineHandler(c => {
  return c.json({ locale: getRequestLocale(c), msg: t('hello') });
});

Config (ubean.config.ts)

i18n: false | {
  defaultLocale?: string;
  locales?: Array<string | {
    code: string;
    language?: string;
    name?: string;
    dir?: 'ltr' | 'rtl';
    files?: string[];
  }>;
  strategy?: 'prefix' | 'prefix_except_default' | 'prefix_and_default' | 'no_prefix';
  baseUrl?: string;
  detectBrowserLanguage?: false | {
    cookieName?: string;
    redirectOn?: 'root' | 'all';
    alwaysRedirect?: boolean;
  };
  vueI18n?: {
    fallbackLocale?: string;
    fallbackWarn?: boolean;
    missingWarn?: boolean;
    datetimeFormats?: object;
    numberFormats?: object;
  };
}

Defaults: strategy: 'prefix_except_default', detectBrowserLanguage.redirectOn: 'root'. Middleware is automatic.

Types

.ubean/i18n.d.ts augments vue-i18n DefineLocaleMessage from the default locale JSON so t('missing') fails typecheck. Include .ubean/*.d.ts in tsconfig.json (the default scaffold already does).

Removed (no compatibility layer): defineLocale, addLocale, mergeLocale, clearLocales, formatDate / formatNumber / formatCurrency / formatRelativeTime / formatList, process-global useI18n() from @ubean/i18n. Use vue-i18n d / n and ALS t() instead.