@i18n-micro/path-strategy

Shared strategy-based path and route name builder for Nuxt I18n Micro frontend routing.
114,880 251
Install
npm install @i18n-micro/path-strategy
Latest Version:1.3.20
License:MIT
Last Updated:Oct 15, 2026
Links: GitHub  ·  npm
Maintainer: s00d

@i18n-micro/path-strategy

Runtime path and route strategies for Nuxt I18n Micro: locale resolution from URL, link generation, redirects, and SEO helpers. Use this package when you need a single routing strategy at build time so only the chosen implementation is bundled.


Overview

  • Strategies: no_prefix, prefix, prefix_except_default, prefix_and_default
  • API: resolveLocaleFromPath, getLocaleFromPath, localeRoute, switchLocaleRoute, getRedirect, getClientRedirect, shouldReturn404, getCanonicalPath, getRouteBaseName, getCurrentLocale, getPluginRouteName, formatPathForResolve
  • Framework-agnostic: Works with any router that implements the RouterAdapter interface (hasRoute, resolve); compatible with Vue Router and custom adapters.
  • Tree-shakeable: Subpath exports (/prefix, /no-prefix, etc.) let the bundler include only the selected strategy.

Package structure

Path Contents
src/types.ts All type definitions (PathStrategyContext, RouteLike, ResolvedRouteLike, RouterAdapter, PathStrategy, etc.)
src/path.ts Path utilities (normalizePath, joinUrl, buildUrl, getPathWithoutLocale, getLocaleFromPath, hasKeys, etc.)
src/resolver.ts Route analysis and resolution (analyzeRoute, getRouteBaseName, buildLocalizedName, isIndexRouteName, resolveCustomPath, etc.)
src/helpers.ts Strategy-agnostic helpers (shouldReturn404, preserveQueryAndHash, tryResolveByLocalizedName, etc.)
src/strategies/ BasePathStrategy, createPathStrategy factory, and strategy implementations: no-prefix, prefix, prefix-except-default, prefix-and-default
src/strategies/common.ts Shared strategy logic (defaultResolveLocaleRoute)

Installation

pnpm add @i18n-micro/path-strategy @i18n-micro/types

Peer dependency: @i18n-micro/types.


Setup: Using a single strategy via Nuxt alias (build-time)

To ship only the selected strategy (no factory, no other implementations), wire a Nuxt alias at build time.

1. Configure the Nuxt module

In your Nuxt module's setup() (or in nuxt.config), set the alias to the strategy entry you want:

// src/module.ts (or nuxt.config.ts)

import type { Strategies } from '@i18n-micro/types'

const strategyEntries: Record<Strategies, string> = {
  no_prefix: '@i18n-micro/path-strategy/no-prefix',
  prefix: '@i18n-micro/path-strategy/prefix',
  prefix_except_default: '@i18n-micro/path-strategy/prefix-except-default',
  prefix_and_default: '@i18n-micro/path-strategy/prefix-and-default',
}

const selectedStrategy = strategyEntries[options.strategy] ?? strategyEntries.prefix_except_default

nuxt.options.alias['#i18n-strategy'] = selectedStrategy

2. Type declarations for #i18n-strategy

So that TypeScript and your IDE understand the alias, add a generated declaration in prepare:types:

import { resolve } from 'node:path'

nuxt.hook('prepare:types', ({ references }) => {
  nuxt.addTemplate({
    filename: 'i18n-strategy.d.ts',
    getContents: () => `
      import { BasePathStrategy } from '@i18n-micro/path-strategy'
      export class Strategy extends BasePathStrategy {}
    `,
  })
  references.push({ path: resolve(nuxt.options.buildDir, 'i18n-strategy.d.ts') })
})

If your setup already resolves types for this alias, you can skip this step.

3. Use in a plugin or composable

Import the strategy only via the alias so the bundler includes just that implementation:

// runtime/plugins/01.i18n-strategy.ts

import { Strategy } from '#i18n-strategy'
import type { PathStrategyContext } from '@i18n-micro/path-strategy/types'

export default defineNuxtPlugin((nuxtApp) => {
  const context: PathStrategyContext = {
    strategy: useRuntimeConfig().public.i18n.strategy,
    defaultLocale: 'en',
    locales: [/* ... */],
    localizedRouteNamePrefix: 'localized-',
    router: { hasRoute, resolve },
    // optional: globalLocaleRoutes, routeLocales, routesLocaleLinks, noPrefixRedirect
  }

  const pathStrategy = new Strategy(context)
  return { provide: { i18nStrategy: pathStrategy } }
})

Only the selected strategy and the base class are included in the bundle; the other strategies are tree-shaken out.

4. Package exports

Entry Contents
@i18n-micro/path-strategy Main entry: types, factory, all strategies, resolver utils (getRouteBaseName, buildLocalizedName, isIndexRouteName, analyzeRoute)
@i18n-micro/path-strategy/prefix PrefixPathStrategy and Strategy alias
@i18n-micro/path-strategy/no-prefix NoPrefixPathStrategy and Strategy
@i18n-micro/path-strategy/prefix-except-default PrefixExceptDefaultPathStrategy and Strategy
@i18n-micro/path-strategy/prefix-and-default PrefixAndDefaultPathStrategy and Strategy
@i18n-micro/path-strategy/types Types only (PathStrategyContext, RouteLike, ResolvedRouteLike, RouterAdapter, etc.)

API

Factory

  • createPathStrategy(ctx: PathStrategyContext) — Returns the strategy instance for ctx.strategy. Use for tests or server-side when you don't use the alias.

Resolver utilities (from main entry)

  • getRouteBaseName(route, options?) — Returns the base route name (without localized prefix/suffix).
  • buildLocalizedName(baseName, localeCode, prefix?) — Builds a localized route name (e.g. about + de + localized- -> localized-about-de).
  • isIndexRouteName(name, options?) — Returns whether the route name is the index route (e.g. index, localized-index-en).
  • analyzeRoute(route, ctx) — Returns a RouteAnalysis object with baseName, pathWithoutLocale, localeFromPath, and isIndex for a given route and context.

Strategy interface

Each strategy implements:

Method Description
localeRoute(targetLocale, routeOrPath, currentRoute?) Localized route for the target locale. Returns RouteLike with path and fullPath set.
switchLocaleRoute(fromLocale, toLocale, route, options) Route to navigate to when switching locale. Returns RouteLike or string.
getRedirect(currentPath, targetLocale) Path to redirect to on server, or null.
getClientRedirect(currentPath, preferredLocale) Path to redirect to on client (after hydration), or null.
shouldReturn404(currentPath) Returns a 404 redirect path if the current path is invalid, or null.
getCanonicalPath(route, targetLocale) Custom path for the route in that locale (from globalLocaleRoutes), or null.
resolveLocaleFromPath(path) Locale code from path (strategy-specific; e.g. no_prefix returns null).
getLocaleFromPath(path) Parses path and returns first segment if it is a locale code.
getRouteBaseName(route) Base name for the route (delegates to resolver with context).
getCurrentLocale(route, defaultLocaleOverride?) Determines current locale from route (considers strategy, hashMode, params, path).
getPluginRouteName(route, locale) Returns the base route name for translation loading.
getCurrentLocaleName(route, defaultLocaleOverride?) Returns displayName of the current locale, or null.
setRouter(router) Replaces the router adapter at runtime.
formatPathForResolve(path, fromLocale, toLocale) Transforms a path for cross-locale resolution.
getDefaultLocale() Returns the default locale code.
getLocales() Returns the configured locales array.
getStrategy() Returns the strategy name.

Context (PathStrategyContext)

Import from @i18n-micro/path-strategy/types.

Property Description
strategy, defaultLocale, locales, localizedRouteNamePrefix, router Required.
localeCodes Pre-computed locale code strings. Set automatically in constructor from locales.
globalLocaleRoutes Record<string, Record<string, string> | false>: custom path per route/locale; false = unlocalized.
routeLocales Record<string, string[]>: route path or base name -> list of locale codes; limits hreflang entries.
routesLocaleLinks Record<string, string>: base name -> key for routeLocales lookup (e.g. 'products-id' -> 'products').
noPrefixRedirect When true (default), NoPrefixPathStrategy.getRedirect strips a leading locale segment (e.g. /en/about -> /about). Set to false to disable.
hashMode Locale stored in hash, no prefix in path.
disablePageLocales When true, all pages use only global translations (no page-specific loading).
debug Enable debug logging.

Redirect behavior per strategy

  • prefix: root / -> /{locale}; paths without prefix get prefix; wrong prefix is replaced.
  • prefix_except_default: default locale with prefix (e.g. /en/about) -> path without prefix (/about); non-default without prefix -> add prefix; root with non-default -> /{locale}.
  • prefix_and_default: same as prefix (all locales have prefix in URL).
  • no_prefix: paths that start with a locale segment (e.g. /en/about) -> path without segment (/about), unless noPrefixRedirect is false.

Using getRedirect in middleware

const redirectPath = strategy.getRedirect(to.fullPath, detectedLocale)
if (redirectPath) return navigateTo(redirectPath)

Integration with Nuxt I18n Micro

The main Nuxt module (nuxt-i18n-micro) integrates path-strategy by default: it generates the strategy from the chosen strategy option, creates the instance with runtime config and router, and provides it as nuxtApp.$i18nStrategy. The redirect plugin calls strategy.getRedirect() (server) and strategy.getClientRedirect() (client) and redirects when a path is returned.


Testing

The package is tested with Jest. Tests include unit tests for each strategy, snapshot tests, a memory-leak test suite, and performance benchmarks.

# Unit tests
pnpm test

# Performance benchmarks (Node.js)
pnpm test:perf

# Performance benchmarks (real browsers — Chromium, Firefox, WebKit)
pnpm bench:browser:ci

# Single browser
pnpm bench:browser:ci -- --browser=firefox

# Interactive browser benchmark (opens dev server)
pnpm bench:browser

Browser benchmarks

The bench/ directory contains a browser-based performance benchmark that runs the same suite as the Node.js tests but in a real browser engine via Playwright. This measures actual client-side performance across V8 (Chromium), SpiderMonkey (Firefox), and JavaScriptCore (WebKit).

Results are saved as baselines per browser engine in tests/__perf__/baseline-browser-{engine}.json.


Performance optimizations

  • Pure functions over classes — Route resolution (analyzeRoute, resolveCustomPath, etc.) uses pure functions instead of a class-based RouteResolver, enabling better tree-shaking and V8 inlining.
  • Pre-computed context flags — localeCodes, _hasGR (has global locale routes), and _hasRL (has route locales) are computed once in the constructor, avoiding Object.keys() allocations on hot paths.
  • Minimal object allocation — Route objects are constructed via direct property assignment instead of { ...spread } to reduce GC pressure.
  • Fast path utilities — normalizePath, joinUrl, and cleanDoubleSlashes use character-code checks and fast paths for common cases (e.g. simple paths without double slashes).
  • hasKeys() utility — O(1) check for whether an object has own keys, without Object.keys() array allocation.

License

MIT

Related Packages

@vintl/nuxt

Nuxt Module for VIntl integration

9,922 2
@brc-dd/nuxt-i18n

Minimal module for i18n with locale auto-imports & localized routing

898 12
@nuxtjs/i18n

Internationalization for Nuxt

23,877,608 2,085
vue-i18n-routing

The i18n routing with using vue-i18n

746,897 19
@i18n-micro/types

TypeScript definitions for the Nuxt I18n Micro ecosystem.

297,836 251

Version History

Version Released License
1.3.20 MIT
1.3.19 MIT
1.3.18 MIT
1.3.17 MIT
1.3.16 MIT