Skip to content

Commit 8971676

Browse files
committed
Document route animations.
1 parent 4c576a9 commit 8971676

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ projects that use wouter: **[Ultra](https://ultrajs.dev/)**,
8080
- [Are relative routes and links supported?](#are-relative-routes-and-links-supported)
8181
- [Can I initiate navigation from outside a component?](#can-i-initiate-navigation-from-outside-a-component)
8282
- [Can I use _wouter_ in my TypeScript project?](#can-i-use-wouter-in-my-typescript-project)
83+
- [How can add animated route transitions?](#how-can-add-animated-route-transitions)
8384
- [Preact support?](#preact-support)
8485
- [Server-side Rendering support (SSR)?](#server-side-rendering-support-ssr)
8586
- [How do I configure the router to render a specific route in tests?](#how-do-i-configure-the-router-to-render-a-specific-route-in-tests)
@@ -704,6 +705,52 @@ It's the same function that is used internally.
704705
Yes! Although the project isn't written in TypeScript, the type definition files are bundled with
705706
the package.
706707

708+
### How can add animated route transitions?
709+
710+
Let's take look at how wouter routes can be animated with [`framer-motion`](framer.com/motion).
711+
Animating enter transitions is easy, but exit transitions require a bit more work. We'll use the `AnimatePresence` component that will keep the page in the DOM until the exit animation is complete.
712+
713+
Unfortunately, `AnimatePresence` only animates its **direct children**, so this won't work:
714+
715+
```jsx
716+
import { motion, AnimatePresence } from "framer-motion";
717+
718+
export const MyComponent = () => (
719+
<AnimatePresence>
720+
{/* This will not work! `motion.div` is not a direct child */}
721+
<Route path="/">
722+
<motion.div
723+
initial={{ opacity: 0 }}
724+
animate={{ opacity: 1 }}
725+
exit={{ opacity: 0 }}
726+
/>
727+
</Route>
728+
</AnimatePresence>
729+
);
730+
```
731+
732+
The workaround is to match this route manually with `useRoute`:
733+
734+
```jsx
735+
export const MyComponent = ({ isVisible }) => {
736+
const [isMatch] = useRoute("/");
737+
738+
return (
739+
<AnimatePresence>
740+
{isMatch && (
741+
<motion.div
742+
initial={{ opacity: 0 }}
743+
animate={{ opacity: 1 }}
744+
exit={{ opacity: 0 }}
745+
/>
746+
)}
747+
</AnimatePresence>
748+
);
749+
};
750+
```
751+
752+
More complex examples involve using `useRoutes` hook (similar to how React Router does it), but wouter does not ship it out-of-the-box. Please refer to [this issue](https://github.com/molefrog/wouter/issues/414#issuecomment-1954192679) for the workaround.
753+
707754
### Preact support?
708755

709756
Preact exports are available through a separate package named `wouter-preact` (or within the

0 commit comments

Comments
 (0)