@i18n-micro/core
Core utilities for translations, formatting, and locale routing in Nuxt I18n Micro.
Entry points: @i18n-micro/core, @i18n-micro/core/devtools, @i18n-micro/core/helpers, @i18n-micro/core/render.
@i18n-micro/core
Functions
collectTranslationPaths
Adds every path of obj (objects and leaves, dotted) to paths. Arrays are leaves; a cycle is cut.
function collectTranslationPaths(
obj: Tree,
paths: Set<string>,
prefix?: string,
ancestors?: Set<object>,
): void
See Tree
convertible
What t hands back for a subtree or an array: that value, or, where String() throws on it, an equal copy that
converts. v-html and a template literal convert what they get, and a dictionary is no reason for a 500.
function convertible<T extends object>(value: T): T
createReactiveI18nStore
function createReactiveI18nStore(options: ReactiveI18nStoreOptions): ReactiveI18nStore
See ReactiveI18nStoreOptions · ReactiveI18nStore
defaultPlural
Default plural rule, see pluralForm. locale is the tag for Intl.PluralRules: an unknown
one gets the index rule, never the host's locale. Only the picked form is interpolated, with
params + {count}. Not a string: no plural.
function defaultPlural(
key: string,
count: number,
params: Params,
locale: string,
getter: Getter,
): string | null
escapeHtml
function escapeHtml(text: string): string
externalLinkHref
The href of a link that leaves the app, undefined for a route: a bare domain gets https://,
anything else already says where it goes.
function externalLinkHref(to: unknown): string | undefined
getByPath
Own flat key first, then the dotted walk: objects by own key, arrays by index (list.0, never list.length).
__proto__ is nothing, even as an own key: JSON.parse makes one, and a parsed tree is stored as it is.
function getByPath(obj: Tree | null | undefined, path: string): unknown
See Tree
hasTranslationValue
function hasTranslationValue(obj: Tree | null | undefined, key: string): boolean
See Tree
interpolate
Replaces {name} with params.name ({0} with an item of a list); a token without an own param stays as written.
function interpolate(template: string, params: TranslateParams): string
See TranslateParams
isActiveLink
Whether a link to link is active on current: the same page, or a section above it. A locale
root (/de) is above every page of that locale, so it needs the same page.
function isActiveLink(
current: string,
link: string,
localeCodes: readonly string[],
): boolean
isNoPrefixStrategy
function isNoPrefixStrategy(strategy: Strategies): strategy is 'no_prefix'
See Strategies
isPlainClick
A click the app may take over: primary button, no modifier, no target, no download. The rest are the browser's.
function isPlainClick(event: MouseEvent): boolean
isPrefixAndDefaultStrategy
function isPrefixAndDefaultStrategy(
strategy: Strategies,
): strategy is 'prefix_and_default'
See Strategies
isPrefixExceptDefaultStrategy
function isPrefixExceptDefaultStrategy(
strategy: Strategies,
): strategy is 'prefix_except_default'
See Strategies
isPrefixStrategy
function isPrefixStrategy(strategy: Strategies): strategy is 'prefix'
See Strategies
isProduction
process.env.NODE_ENV as bundlers inline it; an unbundled browser has no process and counts as development.
function isProduction(): boolean
isSamePage
Whether two URLs name one page: query, hash and a trailing slash do not count.
function isSamePage(a: string, b: string): boolean
localeIsoMap
BaseI18nOptions.localeIso of a locale list.
function localeIsoMap(
locales: readonly { code: string; iso?: string; }[],
): Record<string, string>
localizedPath
to in locale for a prefix-except-default router: a leading locale segment is replaced, or
dropped for the default locale. Query and hash stay as they are.
function localizedPath(
to: string | { path?: string; },
locale: string,
localeCodes: readonly string[],
defaultLocale: string,
): string
mergeTranslationChunk
Deep merge of two trees into a new one; neither input is changed, and the result shares
nothing with incoming. Nested objects merge, everything else (arrays, scalars, null) replaces.
Of existing, only nodes on the patch's paths are copied.
function mergeTranslationChunk(
existing: Tree,
incoming: Tree,
options?: MergeTranslationChunkOptions,
): Tree
See Tree · MergeTranslationChunkOptions
mergeTranslationLayers
Two live layers (upper wins) as one tree that answers every key t() answers through them.
A null/undefined in upper falls through. Where upper replaces an object or an array of
lower, its leaves come back as flat dotted keys (getByPath reads them first), but for the ones upper answers itself.
function mergeTranslationLayers(lower: Tree, upper: Tree): Tree
See Tree
ownValue
obj[key] if it is the object's own, in one property lookup on the hot path. Only a value
an object could have inherited (a function, or the value Object.prototype holds, e.g. after
prototype pollution) is double-checked with hasOwnProperty, as is __proto__.
function ownValue(obj: object, key: string): unknown
pathEnd
Where a URL's path ends: its first ? or #, -1 for neither.
function pathEnd(url: string): number
pathSegments
The segments of a path, as a browser reads the URL: \ is a slash and a tab or a newline is dropped, so /\host cannot pass for a path.
function pathSegments(pathname: string): string[]
pluralForm
The picked form of a raw a | b | c value, trimmed and not interpolated.
function pluralForm(translation: string, count: number, locale: string): string
resolveCachedTranslation
resolveTranslation with the same per-tree leaf cache the helper uses, for adapters that keep
their own trees (Nuxt's active dictionary). The tree must never be mutated after it is read.
function resolveCachedTranslation(
tree: Tree | null | undefined,
key: string,
): unknown | null
See Tree
resolveText
The one way from component props to text: which value, which form, which params, html escaping.
null when hideIfEmpty hides it. Every <i18n-t> goes through it, directly or through renderI18nT.
function resolveText(i18n: TextHost, options: ResolveTextOptions): ResolvedText | null
See TextHost · ResolveTextOptions · ResolvedText
resolveTranslation
getByPath, with "nothing there" (missing or undefined) as null.
function resolveTranslation(obj: Tree | null | undefined, key: string): unknown | null
See Tree
routeQuery
The query of a route from a search string, as vue-router parses it: ?tag=a&tag=b gives
{ tag: ['a', 'b'] }, ?flag gives { flag: null }. An empty pair (?a&&b) counts for nothing.
function routeQuery(
search: string | undefined,
): Record<string, string | null | (string | null)[]>
setTranslationAtKey
A copy of tree with key set to value (replaced, not merged). Only the nodes along the
path are copied; an array keeps its items when the next segment is an index (list.1, as
getByPath reads it), and any other non-object on the way becomes {}. An existing flat key is updated as is.
function setTranslationAtKey(tree: Tree, key: string, value: unknown): Tree
See Tree
textOf
String of any translation: a subtree may have a toString key, which is no method, an array may hold one. Nothing there: undefined.
function textOf(value: unknown): string | undefined
tokenize
'Hi {a}, {b}!' → ['Hi ', 'a', ', ', 'b', '!']: text at even indexes, placeholder names at odd
ones. Works on the raw template, so a param value can never be taken for a placeholder. Cached by
template: the result is shared, do not mutate it.
function tokenize(template: string): readonly string[]
translationCacheKey
Storage key of one chunk: locale:route (index when the route is empty).
function translationCacheKey(locale: string, routeName?: string): string
urlPath
The URL up to its query and hash.
function urlPath(url: string): string
withoutDots
/a/b/../c → /a/c, or a ../ would climb out of a locale prefix added later. Read as a browser reads it, \\ a slash and %2e a dot.
function withoutDots(path: string): string
withPrefixStrategy
function withPrefixStrategy(
strategy: Strategies,
): strategy is 'prefix' | 'prefix_and_default'
See Strategies
Classes
BaseI18n
Translation logic shared by every adapter (t, ts, tc, tn, td, tdr, has).
Adapters supply the current locale, fallback locale and route; lookups always read the
storage as it is now (no pinned trees; the helper's leaf cache is keyed by tree identity).
abstract class BaseI18n {
constructor(options: BaseI18nOptions = {})
}
BaseI18nOptions.localeIso: a provider knows the locale list, the instance may be built before it.iso when it has one, else the code.key, null when nothing has it. Layers, first hit wins: the route's chunk, the
locale's root (index) chunk, then the same two in the fallback locale. A route chunk holds
only its own keys: root keys are read from the root chunk, never copied into every route.key.mergeTranslationLayers; reused while both are the same objects.t() can resolve right now for the active locale and route: its layers as one tree (read-only).locale is set when one locale's chunk was written, unset when anything may have changed.console.warn, gated by missingWarn.tn(1000, 'currency').td(date, 'short').key in the active locale and route (a subtree, a string, anything):
set, not merge, so siblings under key are dropped. Visible to t() at once.merge is false. Root keys come from the root chunk (index).localizePath, …).See BaseI18nOptions
FormatService
Cached Intl formatters and Vue I18n-compatible named formats (numberFormats,
datetimeFormats) for tn(1000, 'currency') / td(date, 'short').
class FormatService {
constructor(options: FormatServiceOptions = {})
}
3 days ago / in 3 days: the largest unit that fits at least once, rounded down; Invalid Date like formatDate.TranslationHelper
Reads and writes chunks of a TranslationStorage.
Every lookup starts from the Map as it is now, so writes made straight to
storage.translations (or by another helper on the same storage) are seen at once.
Stored trees are treated as immutable: a merge copies the nodes on the patch's paths and
stores a new root. Trees handed in by callers, returned by t() / getCache, shared between
route chunks or cloned storages stay as they were. Replace a chunk instead of editing one in place.
class TranslationHelper {
constructor(storage?: TranslationStorage)
}
locale (any route) holds key.Types
BaseI18nOptions
interface BaseI18nOptions
storage: a helper of the adapter's own, such as a fork's copy-on-write one.Intl objects, which are costly to build.datetimeFormats).Europe/Berlin): set it so server and browser render one date.iso), for a code that is no language tag: ua → uk-UA.DateTimeFormatsConfig
type DateTimeFormatsConfig = Record<string, Record<string, Intl.DateTimeFormatOptions>>
FormatServiceOptions
interface FormatServiceOptions
datetimeFormats).timeZone wins. Unset: the runtime's zone.Date.now.MergeTranslationChunkOptions
interface MergeTranslationChunkOptions
NumberFormatsConfig
type NumberFormatsConfig = Record<string, Record<string, Intl.NumberFormatOptions>>
ReactiveI18nStore
interface ReactiveI18nStore
ReactiveI18nStoreOptions
Shared reactive state for framework i18n adapters (subscribe / getSnapshot / notify).
interface ReactiveI18nStoreOptions
ResolvedText
A raw template and its values. interpolate makes it a string; tokenize gives a renderer the parts.
interface ResolvedText
ResolveTextOptions
interface ResolveTextOptions
null when the text is blank.hideIfEmpty hides the text.null being empty.TextHost
What resolveText needs from an i18n instance.
interface TextHost
TranslationStorage
Chunks keyed locale:route, each a nested tree. Adapters may share one between instances.
interface TranslationStorage
Tree
Translation trees: plain JSON objects whose leaves are strings, numbers, arrays, null.
Keys are read the way t() reads them: an own flat key ('a.b': 'x') wins over the dotted
walk. __proto__ is never read through or written, so no tree can reach a prototype.
type Tree = Record<string, unknown>
@i18n-micro/core/devtools
Functions
buildInspectorState
function buildInspectorState(
snapshot: I18nDevtoolsStateSnapshot,
): Record<string, Array<{ key: string; value: unknown; editable?: boolean; }>>
buildInspectorTree
function buildInspectorTree(
options: BuildInspectorTreeOptions,
): I18nDevtoolsInspectorNode[]
See BuildInspectorTreeOptions · I18nDevtoolsInspectorNode
countTranslationKeys
Number of distinct dotted paths (objects and leaves) in a tree.
function countTranslationKeys(
translations: Translations | Record<string, unknown> | undefined,
): number
See Translations
decodeInspectorPath
function decodeInspectorPath(encoded: string): string[]
encodeInspectorPath
Encode path segments so a literal key "a.b" and the nested path a → b get distinct ids.
function encodeInspectorPath(segments: string[]): string
flattenTranslationNode
function flattenTranslationNode(
obj: Record<string, unknown>,
parentSegments?: string[],
): I18nDevtoolsInspectorNode[]
getByInspectorPath
function getByInspectorPath(obj: Record<string, unknown>, segments: string[]): unknown
parseInspectorNodeId
function parseInspectorNodeId(
nodeId: string,
): { kind: 'root' | 'active' | 'locale' | 'chunk' | 'key'; locale?: string; routeName?: string; path?: string; segments?: string[]; }
Types
BuildInspectorTreeOptions
interface BuildInspectorTreeOptions
I18nDevtoolsInspectorNode
interface I18nDevtoolsInspectorNode
I18nDevtoolsStateSnapshot
interface I18nDevtoolsStateSnapshot
@i18n-micro/core/helpers
Also exports, as @i18n-micro/core does: collectTranslationPaths · convertible · defaultPlural · escapeHtml · externalLinkHref · getByPath · hasTranslationValue · interpolate · isActiveLink · isNoPrefixStrategy · isPlainClick · isPrefixAndDefaultStrategy · isPrefixExceptDefaultStrategy · isPrefixStrategy · isProduction · isSamePage · localeIsoMap · localizedPath · mergeTranslationChunk · mergeTranslationLayers · ownValue · pathEnd · pathSegments · pluralForm · resolveText · resolveTranslation · routeQuery · setTranslationAtKey · textOf · tokenize · translationCacheKey · urlPath · withoutDots · withPrefixStrategy · MergeTranslationChunkOptions · ResolvedText · ResolveTextOptions · TextHost · Tree.
@i18n-micro/core/render
Also exports, as @i18n-micro/core does: ResolveTextOptions · TextHost.
Functions
createLocaleSwitcher
One locale switcher for both sides. Call it from setup: it owns the open state and the document
listeners, and returns the render function.
function createLocaleSwitcher(
vue: SwitcherVue,
adapter: SwitcherAdapter,
props: SwitcherProps,
slots: RenderSlots,
): () => unknown
See SwitcherVue · SwitcherAdapter · SwitcherProps · RenderSlots
foldTemplate
The template as children, one pass over its raw tokens: a slot, else a param, else the token as written. A slot's fragment is keyed by name and occurrence, so a locale that reorders placeholders moves the slot's DOM instead of rebuilding it.
function foldTemplate(
renderSlot: (slot: RenderSlot, key: string) => unknown,
template: string,
params: Record<string, unknown>,
slots: RenderSlots,
textChild?: (text: string) => unknown,
): unknown
See RenderSlot · RenderSlots
renderI18nT
One <i18n-t>: resolveText, then markup, a default slot, or the folded template.
function renderI18nT(
api: RenderApi,
i18n: TextHost,
props: I18nTRenderProps,
slots: RenderSlots,
attrs: Record<string, unknown>,
): unknown
See RenderApi · TextHost · I18nTRenderProps · RenderSlots
Constants
SWITCHER_STYLES
One look for every switcher; the React family spreads these, Solid converts the names.
const SWITCHER_STYLES: {
wrapper: object;
button: object;
dropdown: object;
item: object;
link: object;
activeLink: object;
icon: object;
openIcon: object;
}
Types
I18nTRenderProps
interface I18nTRenderProps extends ResolveTextOptions
RenderApi
Vue's own functions, handed in: @i18n-micro/vue and the Nuxt module render with one code path,
and neither core nor the module depends on the other's copy of anything.
interface RenderApi
innerHTML when unset.data-allow-mismatch when unset.RenderSlot
type RenderSlot = (props?: Record<string, unknown>) => unknown
RenderSlots
type RenderSlots = Readonly<Record<string, RenderSlot | undefined>>
See RenderSlot
SwitcherAdapter
What a side supplies: its locales, its URLs and its navigation.
interface SwitcherAdapter
locales.href is a real page and nothing here navigates. select still runs.SwitcherProps
The custom*Style props of the switcher, each merged over the part it names.
interface SwitcherProps
SwitcherVue
interface SwitcherVue extends RenderApi
See RenderApi
Generated from the TypeScript sources and their JSDoc by pnpm run docs:generate.
Back to all packages · Integration guides