Changelog
[0.8.0] - 2026-09-27
Added
- File-based routing plugin (build-time dev tool, shipped inside the router package):
- Declare
defineUniPagemacros near your pages (or<route-config lang="jsonc|uts">custom blocks); the plugin generatespages.json(including tabBar / subPackages) and theroutes.gen.utsroute table at build time, eliminating duplicated manual maintenance of path / title / tabBar / isTab - Priority chain: macro > block > plugin inference (
titleFallback/tabBarconfig as fallback), with field-level merging - Automatic name normalization: last-segment camelCase → full-path camelCase fallback on collision → terminal conflicts handled by
errorStrategy(strict abort / warn skip) beforeEnterand extended meta declared via the macro (UTS expressions injected verbatim into the generated file, must be self-contained)preserveRouteChanges(default on): your modifications and custom routes in the route file survive regeneration- Hand-written non-page fields in pages.json (globalStyle, uniIdRouter, etc.) are merged and preserved
- watch: adding / removing / editing pages triggers a debounced (200 ms), serialized two-phase pipeline rerun
- Generates
route-name.gen.d.ts(WEB-sideRouteNameMapliteral types) anddefine-uni-page.d.ts(macro typing), both optional
- Declare
- New subpath export
@meng-xi/unix-router/vite-plugin: vite / webpack adapters (unplugin bundled in, zero runtime dependencies); thenode/source directory sits outside UTS compile scanning, leaving the main entry unaffected - Plugins split into three independent implementations (
node/reorganized intoroute-gen/pages-gen/routes-gen+shareddirectories), registrable independently or in combination without affecting each other:routeGen: page files →pages.json+routes.gen.utsfull pipeline (behavior unchanged)pagesGen: page files →pages.jsononly (including the macro dts), never touches route filesroutesGen:pages.json→ route table only, never touchespages.json; supports theroutes.ext.utsextension declaration file (path / name ↔ explicit name / extended meta / beforeEnter, functions injected verbatim;router.extensionschanges the path orfalsedisables it)- Options split along with the plugins: common options (
pagesJsonPath/watch/verbose/errorStrategy) + thepages/routersections
Fixed
- Android cloud-packaging compile errors (UTS strong typing):
Promise.catchcallback parameter type changed fromanytoany | null: UTS'sanycompiles to a non-null KotlinAny, which cannot match theUTSPromise.catchoverloads requiring a nullable callback parameterisNavigationFailurefirst parameter widened fromError | nulltoany | null(narrowed internally viainstanceof), fixing chained usage like.catch((e) => isNavigationFailure(e))
- Compile type warnings for
uni.*navigation APIs on H5: WEB-side navigation options are consolidated into the unified bridge functionapplyWebNavOptions(dynamic fields bridged viaas any), eliminating compile warnings foruni.navigateToetc. with runtime behavior unchanged router.pushcrash on H5:pickAnimation/toUniAnimation/pickEventschecked optional fields against=== nullthen read.length/.size; on H5 (JS runtime) the absent value isundefined, throwing aTypeErrorthat aborted navigation; normalized with?? nullbefore checking- Missing navigation animation pass-through on App:
AnimationPluginpreviously did not actually pass animation parameters on App; nowuni.navigateTo/uni.navigateBackcarryanimationType/animationDurationin their named Options (official type declarations mark App-only support: Android 4.18+ / iOS 4.25+ / HarmonyOS 4.61+); Mini Programs (animation fields not supported officially) andredirectTo/reLaunch/switchTab(no animation fields in the official Options) carry none
[0.7.0] - 2026-09-20
Breaking
- Plugins are now registered as instances: on the native (Kotlin/Swift) end
RouterPluginbecomes an abstract class (object literals cannot hold methods), and the built-in plugins extend it asclass ParamsPlugin extends RouterPlugin; registration changes fromplugins: [ParamsPlugin]toplugins: [new ParamsPlugin()](same for Interceptor / Animation / Events).
Fixed
- Full native-compilation (non-steam mode) compatibility:
- Method-carrying object literals converted to classes:
RouteState/GuardManager/RouteMatcher/ParamsManager/PluginContextare now classes instead of factory-returned object literals, eliminating the Kotlin UTSJSONObject inference that broke method calls - Explicit boolean conditions: removed all truthy checks (
if (x)→if (x != null)) to satisfy the UTS rule that conditions must be boolean - uni.* navigation options adapted per platform: App / Mini Program use animation-free object literals (matching the
NavigateToOptionsnamed parameter type), H5 uses UTSJSONObject carryinganimationType - Variadic function types made compatible: event callbacks changed from
(...args: any[]) => anyto single-arg(data: any) => any(Kotlin forbids vararg / modifiers on function-type parameters) - Iteration and type cleanup: replaced
for..in+Object.prototypewithUTSJSONObject.keys(), removedundefinedidentifiers andPromise.rejectreturn-type issues, made nullable parameters explicit - Page layer: top-level functions used in templates are wrapped by local functions (exposed as properties on Kotlin-native); ucss compound/descendant selectors replaced by dynamic classes
- Method-carrying object literals converted to classes:
[0.6.0] - 2026-09-18
Added
EventsPluginpage-to-page event communication plugin (opt-in viaplugins: [EventsPlugin]):- Aligns with the official
navigateToeventssemantics: the opener passes aneventslistener map inpush, and the opened page emits data back / receives pushes through theEventChannelfromuseOpenerEventChannel() - Backed by the built-in
eventBus($on/$once/$off/$emit, listeners removed by id), free of the officialuni.$onversion gate - The channel key is bridged across pages via the internal
__evt__URL query key and stripped during state sync (never exposed to users);useOpenerEventChannel()does not depend on route-sync timing, usable right inonShow - Navigating with
eventswithout registering the plugin throwsPLUGIN_REQUIREDfor clear guidance
- Aligns with the official
- New exports:
EventsPlugin/eventBus/useOpenerEventChannel - New type:
EventsMap;RawLocation/RouteLocationRawaccept the optionaleventsfield
[0.5.1] - 2026-09-17
Fixed
- Android base compilation error (UTS110111101): the return type of
UniHistory.currentStack()was an inline object literal{ path: string; query: Map<string, string> }, which UTS does not allow as a direct object-literal type declaration, breaking the Android base packaging compile; extracted it into the named typeCurrentStackInfo
[0.5.0] - 2026-09-16
Added
AnimationPluginnavigation window animation plugin (opt-in,plugins: [AnimationPlugin]):- App / Mini Program: passes
animationType/animationDurationthrough to theuni.*native navigation APIs (native window animation) - H5: plays enter / exit animations with the Web Animations API (
element.animate) — no CSS@keyframesneeded - Global default animation (
RouterOptions.animation) + per-navigation overrides (animationType/animationDuration)
- App / Mini Program: passes
RouterOptions.animation: global default navigation animation config{ type, duration }- Query helper functions publicly exported:
queryInt()/queryNumber()/queryBool()are now exported from the library entry — no need to import via relative paths - New types:
NavigationAnimation/AnimationType;RawLocationsupports optionalanimationType/animationDurationfields
Fixed
- H5 first-entry lag on secondary pages: when
onCompleteNavigationfires, uni-app x H5 has already swapped the new page's content intouni-page; the plugin now synchronously applies the animation start style + forces a reflow so the new page's first rendered frame is already off-screen, and the slide-in animation plays on the next frame — eliminating the jarring "content flashes in place, then jumps off-screen and slides in" effect. The inline start style is cleared after the animation ends so it cannot affect the exit animation of a laterback() - H5 back animation not playing: added
toExitType()mapping (enter-type → exit-type animations);back()now plays the exit animation to completion before the realnavigateBack
[0.4.0] - 2026-09-13
Added
RouterLinkcomponent publicly exported: a declarative navigation component based onuseLink(to/replace/relaunch), importable directly from the library entry- Plugin contract compliance:
RouterPlugin/PluginContextetc. changed frominterfacetotype, allowing direct object-literal assignment (avoids the UTS constraint that object literals cannot be assigned to interfaces)
Changed (breaking)
- Params passing unified: removed the legacy
__unixr_p_query-prefix encoding (encodeParamsToQuery/extractParamsFromQueryand related constants);paramsare now always passed across pages viaParamsPlugin(the__params__keyed store). Old-format URLs no longer restore params; navigations carrying params must registerplugins: [ParamsPlugin]
Fixed
- Eliminated all
undefinedleftovers across the library (unified== null/??narrowing), fixing Web compilation type warnings RouterLinkcss compliance (removedscoped/inline-block, switched to flex layout)
[0.3.0] - 2026-09-11
Added
RouterOptions.paramsPersistent: withParamsPlugin, params are persisted to storage by default (kept across refreshes / re-entry); defaultfalse- Plugin system polish:
PluginContextexposes the full navigation hooks (onEnrichLocation/onAfterResolve/onPrepareNavigation/onCompleteNavigation/onNavigationAbort/onRouteSync/onAppInstall) plusrouter/paramsManager/hasPlugin, supporting custom plugins Router.guardRoute()/onRouteChange: completed cold-start guard re-check and route-change listening capabilities
Fixed
- Internal
__params__key is now stripped (stripInternalKeys) before writing intocurrentRoute, so it is not exposed to users ParamsPlugin'safterResolvenow null-guards theMap.getreturn value when no__params__key exists, fixing a crash that could interrupt the navigation chain
[0.2.0] - 2026-09-09
Added
- uni API interception (opt-in): new
RouterOptions.interceptUniApioption. Intercepts direct calls touni.navigateTo/redirectTo/switchTab/reLaunch/navigateBackand reroutes them throughrouter.*so the full guard chain runs — guards are sunk down to the uni API layer. Includes internal call deduplication (counter-based) and an H5-specificswitchTabpassthrough + state-sync special case.
Fixed
- Duplicate-navigation detection now compares
path + query + params + hash; it only reportsDUPLICATEDwhen all four match, so re-entering the current page with different params is allowed (previously a params difference was ignored and misreported as a duplicate).
[0.1.0] - 2026-09-05
First runnable release.
Added
- Core: router creation, route matching (path / name dual index), strict mode
- Navigation:
push/replace/relaunch/back, with automatic TabBar detection - Guards:
beforeEach/beforeResolve/afterEach/beforeEnter/ in-component guards (onBeforeRouteLeave/onBeforeRouteUpdate/onBeforeRouteEnter) - Composition API:
useRouter/useRoute/useLink - State sync:
syncRoute, with a reactivecurrentRoutebased ongetCurrentPages() - Error system:
RouterError/NavigationFailure/isNavigationFailure/RouterErrorCode - Dual mode: UTS source distribution — web / Mini Program → JS, Android → Kotlin, iOS → Swift
