+1
-1
| { | ||
| "name": "wouter", | ||
| "version": "3.8.1", | ||
| "version": "3.9.0", | ||
| "description": "Minimalist-friendly ~1.5KB router for React", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+69
-0
@@ -83,2 +83,3 @@ <div align="center"> | ||
| - [How can add animated route transitions?](#how-can-add-animated-route-transitions) | ||
| - [How do I add view transitions to my app?](#how-do-i-add-view-transitions-to-my-app) | ||
| - [Preact support?](#preact-support) | ||
@@ -634,2 +635,12 @@ - [Server-side Rendering support (SSR)?](#server-side-rendering-support-ssr) | ||
| - **`aroundNav: (navigate, to, options) => void`** — a handler that wraps all navigation calls. Use this to intercept navigation and perform custom logic before and after the navigation occurs. You can modify navigation parameters, add side effects, or prevent navigation entirely. This is particularly useful for implementing [view transitions](#how-do-i-add-view-transitions-to-my-app). By default, it simply calls `navigate(to, options)`. | ||
| ```js | ||
| const aroundNav = (navigate, to, options) => { | ||
| // do something before navigation | ||
| navigate(to, options); // perform navigation | ||
| // do something after navigation | ||
| }; | ||
| ``` | ||
| ## FAQ and Code Recipes | ||
@@ -842,2 +853,60 @@ | ||
| ### How do I use wouter with View Transitions API? | ||
| Wouter works seamlessly with the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API), but you'll need to manually activate it. This is because view transitions require synchronous DOM rendering and must be wrapped in `flushSync` from `react-dom`. Following wouter's philosophy of staying lightweight and avoiding unnecessary dependencies, view transitions aren't built-in. However, there's a simple escape hatch to enable them: the `aroundNav` prop. | ||
| ```jsx | ||
| import { flushSync } from "react-dom"; | ||
| import { Router, type AroundNavHandler } from "wouter"; | ||
| const aroundNav: AroundNavHandler = (navigate, to, options) => { | ||
| // Check if View Transitions API is supported | ||
| if (!document.startViewTransition) { | ||
| navigate(to, options); | ||
| return; | ||
| } | ||
| document.startViewTransition(() => { | ||
| flushSync(() => { | ||
| navigate(to, options); | ||
| }); | ||
| }); | ||
| }; | ||
| const App = () => ( | ||
| <Router aroundNav={aroundNav}> | ||
| {/* Your routes here */} | ||
| </Router> | ||
| ); | ||
| ``` | ||
| You can also enable transitions selectively using the `transition` prop, which will be available in the `options` parameter: | ||
| ```jsx | ||
| // Enable transition for a specific link | ||
| <Link to="/about" transition>About</Link> | ||
| // Or programmatically | ||
| const [location, navigate] = useLocation(); | ||
| navigate("/about", { transition: true }); | ||
| // Then check for it in your handler | ||
| const aroundNav: AroundNavHandler = (navigate, to, options) => { | ||
| if (!document.startViewTransition) { | ||
| navigate(to, options); | ||
| return; | ||
| } | ||
| if (options?.transition) { | ||
| document.startViewTransition(() => { | ||
| flushSync(() => { | ||
| navigate(to, options); | ||
| }); | ||
| }); | ||
| } else { | ||
| navigate(to, options); | ||
| } | ||
| }; | ||
| ``` | ||
| ### Preact support? | ||
@@ -844,0 +913,0 @@ |
+9
-3
@@ -43,2 +43,4 @@ import { parse as parsePattern } from "regexparam"; | ||
| hrefs: (x) => x, | ||
| // wraps navigate calls, useful for view transitions | ||
| aroundNav: (n, t, o) => n(t, o), | ||
| }; | ||
@@ -75,3 +77,5 @@ | ||
| relativePath(router.base, location), | ||
| useEvent((to, navOpts) => navigate(absolutePath(to, router.base), navOpts)), | ||
| useEvent((to, opts) => | ||
| router.aroundNav(navigate, absolutePath(to, router.base), opts) | ||
| ), | ||
| ]; | ||
@@ -155,4 +159,5 @@ }; | ||
| // renders <Router> without props after server rendered with ssrPath/ssrSearch) | ||
| const [path, search = props.ssrSearch ?? ""] = props.ssrPath?.split("?") ?? []; | ||
| if (path) props.ssrSearch = search, props.ssrPath = path; | ||
| const [path, search = props.ssrSearch ?? ""] = | ||
| props.ssrPath?.split("?") ?? []; | ||
| if (path) (props.ssrSearch = search), (props.ssrPath = path); | ||
@@ -275,2 +280,3 @@ // hooks can define their own `href` formatter (e.g. for hash location) | ||
| state /* ignore nav props */, | ||
| transition /* ignore nav props */, | ||
| /* eslint-enable no-unused-vars */ | ||
@@ -277,0 +283,0 @@ |
@@ -10,3 +10,3 @@ import { | ||
| to: Path, | ||
| options?: { replace?: boolean; state?: S } | ||
| options?: { replace?: boolean; state?: S; transition?: boolean } | ||
| ) => void; | ||
@@ -13,0 +13,0 @@ |
+20
-0
@@ -14,2 +14,17 @@ import { | ||
| // Standard navigation options supported by all built-in location hooks | ||
| export type NavigateOptions<S = any> = { | ||
| replace?: boolean; | ||
| state?: S; | ||
| /** Enable view transitions for this navigation (used with aroundNav) */ | ||
| transition?: boolean; | ||
| }; | ||
| // Function that wraps navigate calls, useful for view transitions | ||
| export type AroundNavHandler = ( | ||
| navigate: (to: Path, options?: NavigateOptions) => void, | ||
| to: Path, | ||
| options?: NavigateOptions | ||
| ) => void; | ||
| // the object returned from `useRouter` | ||
@@ -24,3 +39,5 @@ export interface RouterObject { | ||
| readonly ssrSearch?: SearchString; | ||
| readonly ssrContext?: SsrContext; | ||
| readonly hrefs: HrefsFormatter; | ||
| readonly aroundNav: AroundNavHandler; | ||
| } | ||
@@ -32,2 +49,4 @@ | ||
| redirectTo?: Path; | ||
| // HTTP status code to set for SSR response | ||
| statusCode?: number; | ||
| }; | ||
@@ -45,2 +64,3 @@ | ||
| hrefs?: HrefsFormatter; | ||
| aroundNav?: AroundNavHandler; | ||
| }; |
@@ -21,3 +21,3 @@ import { Path, SearchString } from "./location-hook.js"; | ||
| to: string | URL, | ||
| options?: { replace?: boolean; state?: S } | ||
| options?: { replace?: boolean; state?: S; transition?: boolean } | ||
| ) => void; | ||
@@ -24,0 +24,0 @@ |
@@ -5,3 +5,3 @@ import { Path } from "./location-hook.js"; | ||
| to: Path, | ||
| options?: { state?: S; replace?: boolean } | ||
| options?: { state?: S; replace?: boolean; transition?: boolean } | ||
| ): void; | ||
@@ -8,0 +8,0 @@ |
74847
4.69%915
2.69%1088
6.77%