# wouter
**Repository Path**: mirrors_developit/wouter
## Basic Information
- **Project Name**: wouter
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-08-08
- **Last Updated**: 2026-05-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# wouter
[](https://www.npmjs.com/package/wouter)
[](https://travis-ci.org/molefrog/wouter) [](https://codecov.io/gh/molefrog/wouter)
A tiny routing solution for modern React and Preact apps that relies on Hooks. A router you wanted so bad in your project!
- Zero dependency, only **1151 B** gzipped vs 17KB [React Router](https://github.com/ReactTraining/react-router).
- Supports both **React** and **[Preact](https://preactjs.com/)**! Read _["Preact support" section](#preact-support)_ for more details.
- No top-level `` component, it is **fully optional**.
- Mimics [React Router](https://github.com/ReactTraining/react-router)'s best practices by providing familiar
**[`Route`](#route-pathpattern-)**, **[`Link`](#link-hrefpath-)**, **[`Switch`](#switch-)** and **[`Redirect`](#redirect-topath-)** components.
- Has hook-based API for more granular control over routing (like animations): **[`useLocation`](#uselocation-hook-working-with-the-history)**, **[`useRoute`](#useroute-the-power-of-hooks)** and **[`useRouter`](#userouter-accessing-the-router-object)**.
## How to get started?
Check out this demo app below in order to get started:
```js
import { Link, Route } from "wouter";
const App = () => (
);
};
```
All the components including the `useRoute` rely on `useLocation` hook, so normally you only need the hook to
perform the navigation using a second value `setLocation`. You can check out the source code of the [`Redirect` component](https://github.com/molefrog/wouter/blob/master/index.js#L142) as a reference.
#### Customizing the location hook
By default, **wouter** uses `useLocation` hook that reacts to `pushState` and `replaceState` navigation and observes the current pathname including the leading slash e.g. **`/users/12`**. If you do need a custom history observer, for example, for hash-based routing, you can [implement your own hook](https://github.com/molefrog/wouter/blob/master/use-location.js) and customize it in a `` component.
Here is how you can implement a router with a fixed basepath:
```js
import { useState, useEffect } from "react";
import { Router, Route } from "wouter";
// a default useLocation hook which wouter uses
import useLocation from "wouter/use-location";
const makeUseBasepathLocation = basepath => () => {
const [location, setLocation] = useLocation();
// could be done with regexp, but requires proper escaping
const normalized = location.startsWith(basepath)
? location.slice(basepath.length)
: location;
return [normalized, to => setLocation(basepath + to)];
};
const useBasepathLocation = makeUseBasepathLocation("/app");
const App = () => (
...
);
```
### `useRouter`: accessing the router object
If you're building an advanced integration, for example custom location hook, you might
want to get access to the global router object. The router is a simple object that holds
current matcher function and a custom location hook function.
Normally, router is constructed internally on demand, but it can also be customized via a top-level `Router` component (see [the section above](#uselocation-hook-working-with-the-history)). The `useRouter` hook simply returns a
current router object:
```js
import { useRouter } from "wouter";
import useLocation from "wouter/use-location";
const Custom = () => {
const router = useRouter();
// router.hook is useLocation by default
// you can also use router as a mediator object
// and store arbitrary data on it:
router.lastTransition = { path: "..." };
};
```
## Component API
### ``
`Route` represents a piece of the app that is rendered conditionally based on a pattern. Pattern is a string, which may
contain special characters to describe dynamic segments, see [**Matching Dynamic Segments** section](#matching-dynamic-segments)
below for details.
The library provides multiple ways to declare a route's body:
```js
import { Route } from "wouter";
// simple form
// render-prop style
{params => }
// the `params` prop will be passed down to
```
### ``
Link component renders an `` element that, when clicked, performs a navigation. You can customize the link appearance
by providing your own component or link element as `children`:
```js
import { Link } from "wouter";
// All of these will produce the same html:
// Hello!
// lazy form: `a` element is constructed around children
Hello!
// when using your own component or jsx the `href` prop
// will be passed down to an element
Hello!Hello!
```
### ``
There are cases when you want to have an exclusive routing: to make sure that only one route is rendered at the time, even
if the routes have patterns that overlap. That's what `Switch` does: it only renders **the first matching route**.
```js
import { Route, Switch } from "wouter";
;
```
Check out [**FAQ and Code Recipes** section](#faq-and-code-recipes) for more advanced use of `Switch`.
### ``
When mounted performs a redirect to a `path` provided. Uses `useLocation` hook internally to trigger the navigation inside of a `useEffect` block.
If you need more advanced logic for navigation, for example, to trigger
the redirect inside of an event handler, consider using [`useLocation` hook instead](#uselocation-hook-working-with-the-history):
```js
import { useLocation } from "wouter";
const [location, setLocation] = useLocation();
fetchOrders().then(orders => {
setOrders(orders);
setLocation("/app/orders");
});
```
### ``
Unlike _React Router_, routes in wouter **don't have to be wrapped in a top-level component**. An internal router object will
be constructed on demand, so you can start writing your app without polluting it with a cascade of top-level providers.
There are cases however, when the routing behaviour needs to be customized.
These cases include hash-based routing, basepath support, custom matcher function etc.
A router is a simple object that holds the routing configuration options. You can always obtain this object using a [`useRouter` hook](#userouter-accessing-the-router-object). The list of currently available options:
- **`hook: () => [location: string, setLocation: fn]`** — is a React Hook function that subscribes to location changes. It returns a pair of current `location` string e.g. `/app/users` and a `setLocation` function for navigation. You can use this hook from any component of your app by calling [`useLocation()` hook](#uselocation-hook-working-with-the-history).
Read more → [Customizing the location hook](#customizing-the-location-hook).
- **`matcher: (pattern: string, path: string) => [match: boolean, params: object]`** — a custom function used for matching the current location against the user-defined patterns like `/app/users/:id`. Should return a match result and an hash of extracted parameters.
Read more → [Matching Dynamic Segments](#matching-dynamic-segments).
### Matching Dynamic Segments
Just like in React Router, you can make dynamic matches either with `Route` component or `useRoute` hook.
`useRoute` returns a second parameter which is a hash of all dynamic segments matched. Similarily, the
`Route` component passes these parameters down to its children via a function prop.
```js
import { useRoute } from "wouter";
// /users/alex => [true, { name: "alex "}]
// /anything => [false, null]
const [match, params] = useRoute("/users/:name");
// or with Route component
{params => {
/* { name: "alex" } */
}}
;
```
**wouter** implements a limited subset of [`path-to-regexp` package](https://github.com/pillarjs/path-to-regexp)
used by React Router or Express, and it supports the following patterns:
- Named dynamic segments: `/users/:foo`.
- Dynamic segments with modifiers: `/foo/:bar*`, `/foo/baz?` or `/foo/bar+`.
The library was designed to be as small as possible, so most of the additional matching features were left out
(see [this issue](https://github.com/molefrog/wouter/issues/1) for more info).
If you do need to have `path-to-regexp`-like functionality, you can customize a matcher function:
```js
import { Router } from "wouter";
import createMatcher from "wouter/matcher";
import pathToRegexp from "path-to-regexp";
const App = () => (
{/* segment constraints aren't supported by wouter */}
}
);
```
## FAQ and Code Recipes
### How do I make a default/fallback route?
One of the common patterns in application routing is having a default route that will be shown as a fallback, in case no other route matches (for example, if you need to render 404 message). In **wouter** this can easily be done as a combination of `` component and catch-all route:
```js
import { Switch, Route } from "wouter";
...404, not found!;
```
**[▶ Demo Sandbox](https://codesandbox.io/s/oqk302k2y)**
### How do I make a link active for the current route?
There are cases when you need to highlight an active link, for example, in the navigation bar. While this functionality isn't provided out-of-the-box, you can easily write your own `` wrapper and detect if the path is active by using the `useRoute` hook. The `useRoute(pattern)` hook returns a pair of `[match, params]`, where `match` is a boolean value that tells if the pattern matches current location:
```js
const [isActive] = useRoute(props.href);
return (
{props.children}
);
```
**[▶ Demo Sandbox](https://codesandbox.io/s/5zjpj19yz4)**
### Can I use _wouter_ in my TypeScript project?
Yes! Although the project isn't written in TypeScript, the type definition files are bundled with the package.
### Preact support?
Preact exports are available through a separate package named `wouter-preact` (or within the `wouter/preact` namespace, however this method isn't recommended as it requires React as a peer dependency):
```diff
- import { useRoute, Route, Switch } from "wouter";
+ import { useRoute, Route, Switch } from "wouter-preact";
```
You might need to ensure you have the latest version of [Preact X](https://github.com/preactjs/preact/releases/tag/10.0.0-alpha.0) with support for hooks.
### Is there any support for server-side rendering (SSR)?
Yes! In order to render your app on a server, you'll need to tell the router that the current location comes from the request rather than the browser history. In **wouter**, you can achieve that by replacing the default `useLocation` hook with a static one:
```js
import { renderToString } from "react-dom/server";
import { Router, Route } from "wouter";
// note: static location has a different import path,
// this helps to keep the wouter source as small as possible
import staticLocationHook from "wouter/static-location";
import App from "./app";
const handleRequest = (req, res) => {
// The staticLocationHook function creates a hook that always
// responds with a path provided
const prerendered = renderToString(
);
// respond with prerendered html
};
```
Make sure you replace the static hook with the real one when you hydrate your app on a client.
### 1KB is too much, I can't afford it!
We've got some great news for you! If you're a minimalist bundle-size nomad and you need a damn simple
routing in your app, you can just use the [`useLocation` hook](#uselocation-hook-working-with-the-history)
which is only **265 bytes gzipped** and manually match the current location with it:
```js
import useLocation from "wouter/use-location";
const UsersRoute = () => {
const [location] = useLocation();
if (location !== "/users") return null;
// render the route
};
```
Wouter's motto is **"Minimalist-friendly"**.
## Acknowledgements
Special thanks to [Katya Vakulenko](https://katyavakulenko.com/) for creating a project logo.