- Notifications
You must be signed in to change notification settings - Fork154
preactjs/preact-router
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Warning
preact-router unfortunately no longer sees active development! It's completely stable and so you can rely upon it for all existing apps, but for newer ones, we'd recommend usingpreact-iso for your routing needs instead. It offers a very similar API while integrating a bit better Suspense and lazy loading, with potentially more useful hooks. Thanks to all the contributors and users over the years!
Connect yourPreact components up to that address bar.
preact-router provides a<Router /> component that conditionally renders its children when the URL matches theirpath. It also automatically wires up<a /> elements to the router.
💁Note: This is not a preact-compatible version of React Router.
preact-routeris a simple URL wiring and does no orchestration for you.If you're looking for more complex solutions like nested routes and view composition,react-router works great with preact as long as you alias inpreact/compat.
importRouterfrom'preact-router';import{h,render}from'preact';/**@jsx h */constMain=()=>(<Router><Homepath="/"/><Aboutpath="/about"/> // Advanced is an optional query<Searchpath="/search/:query/:advanced?"/></Router>);render(<Main/>,document.body);
If there is an error rendering the destination route, a 404 will be displayed.
Because thepath anddefault props are used by the router, it's best to avoid using those props for your component(s) as they will conflict.
💁 Pages are just regular components that get mounted when you navigate to a certain URL.Any URL parameters get passed to the component asprops.
Defining what component(s) to load for a given URL is easy and declarative.Querystring and:parameter values are passed to the matched component as props.Parameters can be made optional by adding a?, or turned into a wildcard match by adding* (zero or more characters) or+ (one or more characters):
<Router><Apath="/"/><Bpath="/b"id="42"/><Cpath="/c/:id"/><Cpath="/d/:optional?/:params?"/><Dpath="/e/:remaining_path*"/><Epath="/f/:remaining_path+"/><Fdefault/></Router>
Lazy loading (code splitting) withpreact-router can be implemented easily using theAsyncRoute module:
importAsyncRoutefrom'preact-async-route';<Router><Homepath="/"/><AsyncRoutepath="/friends"getComponent={()=>import('./friends').then(module=>module.default)}/><AsyncRoutepath="/friends/:id"getComponent={()=>import('./friend').then(module=>module.default)}loading={()=><div>loading...</div>}/></Router>;
preact-router includes an add-on module calledmatch that lets you wire your components up to Router changes.
Here's a demo of<Match>, which invokes the function you pass it (as its only child) in response to any routing:
importRouterfrom'preact-router';importMatchfrom'preact-router/match';render(<div><Matchpath="/">{({ matches, path, url})=><pre>{url}</pre>}</Match><Router><divdefault>demo fallback route</div></Router></div>);// another example: render only if at a given URL:render(<div><Matchpath="/">{({ matches})=>matches&&<h1>You are Home!</h1>}</Match><Router/></div>);
<Link> is just a normal link, but it automatically adds and removes an "active" classname to itself based on whether it matches the current URL.
import{Router}from'preact-router';import{Link}from'preact-router/match';render(<div><nav><LinkactiveClassName="active"href="/"> Home</Link><LinkactiveClassName="active"href="/foo"> Foo</Link><LinkactiveClassName="active"href="/bar"> Bar</Link></nav><Router><divdefault>this is a demo route that always matches</div></Router></div>);
Sometimes it's necessary to bypass preact-router's link handling and let the browser perform routing on its own.
This can be accomplished by adding adata-native boolean attribute to any link:
<ahref="/foo"data-native>Foo</a>
TheRouter notifies you when a change event occurs for a route with theonChange callback:
import{render,Component}from'preact';import{Router,route}from'preact-router';classAppextendsComponent{// some method that returns a promiseisAuthenticated(){}handleRoute=asynce=>{switch(e.url){case'/profile':constisAuthed=awaitthis.isAuthenticated();if(!isAuthed)route('/',true);break;}};render(){return(<RouteronChange={this.handleRoute}><Homepath="/"/><Profilepath="/profile"/></Router>);}}
Can easily be implemented with a customRedirect component;
import{Component}from'preact';import{route}from'preact-router';exportdefaultclassRedirectextendsComponent{componentWillMount(){route(this.props.to,true);}render(){returnnull;}}
Now to create a redirect within your application, you can add thisRedirect component to your router;
<Router><Barpath="/bar"/><Redirectpath="/foo"to="/bar"/></Router>
It's possible to use alternative history bindings, like/#!/hash-history:
import{h}from'preact';importRouterfrom'preact-router';import{createHashHistory}from'history';constMain=()=>(<Routerhistory={createHashHistory()}><Homepath="/"/><Aboutpath="/about"/><Searchpath="/search/:query"/></Router>);render(<Main/>,document.body);
It's possible to programmatically trigger a route to a page (likewindow.location = '/page-2')
import{route}from'preact-router';route('/page-2');// appends a history entryroute('/page-3',true);// replaces the current history entry
The<Router> is a self-contained component that renders based on the page URL. When nested a Router inside of another Router, the inner Router does not share or observe the outer's URL or matches. Instead, inner routes must include the full path to be matched against the page's URL:
import{h,render}from'preact';importRouterfrom'preact-router';functionProfile(props){// `props.rest` is the rest of the URL after "/profile/"return(<div><h1>Profile</h1><Router><MyProfilepath="/profile/me"/><UserProfilepath="/profile/:user"/></Router></div>);}constMyProfile=()=><h2>My Profile</h2>;constUserProfile=props=><h2>{props.user}</h2>;functionApp(){return(<div><Router><Homepath="/"/><Profilepath="/profile/:rest*"/></Router><nav><ahref="/">Home</a><ahref="/profile/me">My Profile</a><ahref="/profile/alice">Alice's Profile</a></nav></div>);}render(<App/>,document.body);
Alternatively to adding the router props (path,default) directly to your component, you may want to use theRoute component we provide instead. This tends to appease TypeScript, while still passing down the routing props into your component for use.
import{Router,Route}from'preact-router';functionApp(){letusers=getUsers();return(<Router><Routepath="/"component={Home}/>{/* Route will accept any props of `component` type */}<Routepath="/users"component={Users}users={users}/></Router>);}
About
🌎 URL router for Preact.
Topics
Resources
License
Code of conduct
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.