{"id":13525031,"url":"https://github.com/preactjs/preact-router","last_synced_at":"2025-05-14T15:08:24.587Z","repository":{"id":35177977,"uuid":"46458028","full_name":"preactjs/preact-router","owner":"preactjs","description":":earth_americas: URL router for Preact.","archived":false,"fork":false,"pushed_at":"2024-07-29T18:35:53.000Z","size":1209,"stargazers_count":1015,"open_issues_count":96,"forks_count":155,"subscribers_count":15,"default_branch":"main","last_synced_at":"2024-10-29T15:23:35.167Z","etag":null,"topics":["preact","preact-components","preact-router","router"],"latest_commit_sha":null,"homepage":"http://npm.im/preact-router","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/preactjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["preactjs"],"open_collective":"preact"}},"created_at":"2015-11-19T01:04:24.000Z","updated_at":"2024-10-18T00:21:01.000Z","dependencies_parsed_at":"2024-04-17T01:46:28.701Z","dependency_job_id":"2812fb0b-b36b-4c27-a328-5622d34d06d2","html_url":"https://github.com/preactjs/preact-router","commit_stats":{"total_commits":256,"total_committers":59,"mean_commits":4.338983050847458,"dds":0.7734375,"last_synced_commit":"ee0ba49b0d1544aaa2f898218321a7f515605164"},"previous_names":["developit/preact-router"],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/preactjs%2Fpreact-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/preactjs%2Fpreact-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/preactjs%2Fpreact-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/preactjs%2Fpreact-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/preactjs","download_url":"https://codeload.github.com/preactjs/preact-router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247338402,"owners_count":20922984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["preact","preact-components","preact-router","router"],"created_at":"2024-08-01T06:01:15.438Z","updated_at":"2025-04-09T11:03:00.524Z","avatar_url":"https://github.com/preactjs.png","language":"JavaScript","readme":"# preact-router\n\n[![NPM](https://img.shields.io/npm/v/preact-router.svg)](https://www.npmjs.com/package/preact-router)\n[![Build status](https://github.com/preactjs/preact-router/actions/workflows/node.js.yml/badge.svg)](https://github.com/preactjs/preact-router/actions/workflows/node.js.yml)\n\n\u003e [!WARNING]\n\u003e `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 using [`preact-iso`](https://github.com/preactjs/preact-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!\n\nConnect your [Preact](https://github.com/preactjs/preact) components up to that address bar.\n\n`preact-router` provides a `\u003cRouter /\u003e` component that conditionally renders its children when the URL matches their `path`. It also automatically wires up `\u003ca /\u003e` elements to the router.\n\n\u003e 💁 **Note:** This is not a preact-compatible version of React Router. `preact-router` is a simple URL wiring and does no orchestration for you.\n\u003e\n\u003e If you're looking for more complex solutions like nested routes and view composition, [react-router](https://github.com/ReactTraining/react-router) works great with preact as long as you alias in [preact/compat](https://preactjs.com/guide/v10/getting-started#aliasing-react-to-preact).\n\n#### [See a Real-world Example :arrow_right:](https://jsfiddle.net/developit/qc73v9va/)\n\n---\n\n### Usage Example\n\n```js\nimport Router from 'preact-router';\nimport { h, render } from 'preact';\n/** @jsx h */\n\nconst Main = () =\u003e (\n  \u003cRouter\u003e\n    \u003cHome path=\"/\" /\u003e\n    \u003cAbout path=\"/about\" /\u003e\n    // Advanced is an optional query\n    \u003cSearch path=\"/search/:query/:advanced?\" /\u003e\n  \u003c/Router\u003e\n);\n\nrender(\u003cMain /\u003e, document.body);\n```\n\nIf there is an error rendering the destination route, a 404 will be displayed.\n\n#### Caveats\n\nBecause the `path` and `default` props are used by the router, it's best to avoid using those props for your component(s) as they will conflict.\n\n### Handling URLS\n\n:information_desk_person: Pages are just regular components that get mounted when you navigate to a certain URL.\nAny URL parameters get passed to the component as `props`.\n\nDefining what component(s) to load for a given URL is easy and declarative.\nQuerystring and `:parameter` values are passed to the matched component as props.\nParameters can be made optional by adding a `?`, or turned into a wildcard match by adding `*` (zero or more characters) or `+` (one or more characters):\n\n```js\n\u003cRouter\u003e\n  \u003cA path=\"/\" /\u003e\n  \u003cB path=\"/b\" id=\"42\" /\u003e\n  \u003cC path=\"/c/:id\" /\u003e\n  \u003cC path=\"/d/:optional?/:params?\" /\u003e\n  \u003cD path=\"/e/:remaining_path*\" /\u003e\n  \u003cE path=\"/f/:remaining_path+\" /\u003e\n  \u003cF default /\u003e\n\u003c/Router\u003e\n```\n\n### Lazy Loading\n\nLazy loading (code splitting) with `preact-router` can be implemented easily using the [AsyncRoute](https://www.npmjs.com/package/preact-async-route) module:\n\n```js\nimport AsyncRoute from 'preact-async-route';\n\u003cRouter\u003e\n  \u003cHome path=\"/\" /\u003e\n  \u003cAsyncRoute\n    path=\"/friends\"\n    getComponent={() =\u003e import('./friends').then(module =\u003e module.default)}\n  /\u003e\n  \u003cAsyncRoute\n    path=\"/friends/:id\"\n    getComponent={() =\u003e import('./friend').then(module =\u003e module.default)}\n    loading={() =\u003e \u003cdiv\u003eloading...\u003c/div\u003e}\n  /\u003e\n\u003c/Router\u003e;\n```\n\n### Active Matching \u0026 Links\n\n`preact-router` includes an add-on module called `match` that lets you wire your components up to Router changes.\n\nHere's a demo of `\u003cMatch\u003e`, which invokes the function you pass it (as its only child) in response to any routing:\n\n```js\nimport Router from 'preact-router';\nimport Match from 'preact-router/match';\n\nrender(\n  \u003cdiv\u003e\n    \u003cMatch path=\"/\"\u003e{({ matches, path, url }) =\u003e \u003cpre\u003e{url}\u003c/pre\u003e}\u003c/Match\u003e\n    \u003cRouter\u003e\n      \u003cdiv default\u003edemo fallback route\u003c/div\u003e\n    \u003c/Router\u003e\n  \u003c/div\u003e\n);\n\n// another example: render only if at a given URL:\n\nrender(\n  \u003cdiv\u003e\n    \u003cMatch path=\"/\"\u003e{({ matches }) =\u003e matches \u0026\u0026 \u003ch1\u003eYou are Home!\u003c/h1\u003e}\u003c/Match\u003e\n    \u003cRouter /\u003e\n  \u003c/div\u003e\n);\n```\n\n`\u003cLink\u003e` is just a normal link, but it automatically adds and removes an \"active\" classname to itself based on whether it matches the current URL.\n\n```js\nimport { Router } from 'preact-router';\nimport { Link } from 'preact-router/match';\n\nrender(\n  \u003cdiv\u003e\n    \u003cnav\u003e\n      \u003cLink activeClassName=\"active\" href=\"/\"\u003e\n        Home\n      \u003c/Link\u003e\n      \u003cLink activeClassName=\"active\" href=\"/foo\"\u003e\n        Foo\n      \u003c/Link\u003e\n      \u003cLink activeClassName=\"active\" href=\"/bar\"\u003e\n        Bar\n      \u003c/Link\u003e\n    \u003c/nav\u003e\n    \u003cRouter\u003e\n      \u003cdiv default\u003ethis is a demo route that always matches\u003c/div\u003e\n    \u003c/Router\u003e\n  \u003c/div\u003e\n);\n```\n\n### Default Link Behavior\n\nSometimes it's necessary to bypass preact-router's link handling and let the browser perform routing on its own.\n\nThis can be accomplished by adding a `data-native` boolean attribute to any link:\n\n```html\n\u003ca href=\"/foo\" data-native\u003eFoo\u003c/a\u003e\n```\n\n### Detecting Route Changes\n\nThe `Router` notifies you when a change event occurs for a route with the `onChange` callback:\n\n```js\nimport { render, Component } from 'preact';\nimport { Router, route } from 'preact-router';\n\nclass App extends Component {\n  // some method that returns a promise\n  isAuthenticated() {}\n\n  handleRoute = async e =\u003e {\n    switch (e.url) {\n      case '/profile':\n        const isAuthed = await this.isAuthenticated();\n        if (!isAuthed) route('/', true);\n        break;\n    }\n  };\n\n  render() {\n    return (\n      \u003cRouter onChange={this.handleRoute}\u003e\n        \u003cHome path=\"/\" /\u003e\n        \u003cProfile path=\"/profile\" /\u003e\n      \u003c/Router\u003e\n    );\n  }\n}\n```\n\n### Redirects\n\nCan easily be implemented with a custom `Redirect` component;\n\n```js\nimport { Component } from 'preact';\nimport { route } from 'preact-router';\n\nexport default class Redirect extends Component {\n  componentWillMount() {\n    route(this.props.to, true);\n  }\n\n  render() {\n    return null;\n  }\n}\n```\n\nNow to create a redirect within your application, you can add this `Redirect` component to your router;\n\n```js\n\u003cRouter\u003e\n  \u003cBar path=\"/bar\" /\u003e\n  \u003cRedirect path=\"/foo\" to=\"/bar\" /\u003e\n\u003c/Router\u003e\n```\n\n### Custom History\n\nIt's possible to use alternative history bindings, like `/#!/hash-history`:\n\n```js\nimport { h } from 'preact';\nimport Router from 'preact-router';\nimport { createHashHistory } from 'history';\n\nconst Main = () =\u003e (\n  \u003cRouter history={createHashHistory()}\u003e\n    \u003cHome path=\"/\" /\u003e\n    \u003cAbout path=\"/about\" /\u003e\n    \u003cSearch path=\"/search/:query\" /\u003e\n  \u003c/Router\u003e\n);\n\nrender(\u003cMain /\u003e, document.body);\n```\n\n### Programmatically Triggering Route\n\nIt's possible to programmatically trigger a route to a page (like `window.location = '/page-2'`)\n\n```js\nimport { route } from 'preact-router';\n\nroute('/page-2'); // appends a history entry\n\nroute('/page-3', true); // replaces the current history entry\n```\n\n### Nested Routers\n\nThe `\u003cRouter\u003e` 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:\n\n```js\nimport { h, render } from 'preact';\nimport Router from 'preact-router';\n\nfunction Profile(props) {\n  // `props.rest` is the rest of the URL after \"/profile/\"\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eProfile\u003c/h1\u003e\n      \u003cRouter\u003e\n        \u003cMyProfile path=\"/profile/me\" /\u003e\n        \u003cUserProfile path=\"/profile/:user\" /\u003e\n      \u003c/Router\u003e\n    \u003c/div\u003e\n  );\n}\nconst MyProfile = () =\u003e \u003ch2\u003eMy Profile\u003c/h2\u003e;\nconst UserProfile = props =\u003e \u003ch2\u003e{props.user}\u003c/h2\u003e;\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003cRouter\u003e\n        \u003cHome path=\"/\" /\u003e\n        \u003cProfile path=\"/profile/:rest*\" /\u003e\n      \u003c/Router\u003e\n      \u003cnav\u003e\n        \u003ca href=\"/\"\u003eHome\u003c/a\u003e\n        \u003ca href=\"/profile/me\"\u003eMy Profile\u003c/a\u003e\n        \u003ca href=\"/profile/alice\"\u003eAlice's Profile\u003c/a\u003e\n      \u003c/nav\u003e\n    \u003c/div\u003e\n  );\n}\n\nrender(\u003cApp /\u003e, document.body);\n```\n\n### `Route` Component\n\nAlternatively to adding the router props (`path`, `default`) directly to your component, you may want to use the `Route` component we provide instead. This tends to appease TypeScript, while still passing down the routing props into your component for use.\n\n```js\nimport { Router, Route } from 'preact-router';\n\nfunction App() {\n  let users = getUsers();\n\n  return (\n    \u003cRouter\u003e\n      \u003cRoute path=\"/\" component={Home} /\u003e\n      {/* Route will accept any props of `component` type */}\n      \u003cRoute path=\"/users\" component={Users} users={users}   /\u003e\n    \u003c/Router\u003e\n  );\n}\n```\n\n### License\n\n[MIT](./LICENSE)\n","funding_links":["https://github.com/sponsors/preactjs","https://opencollective.com/preact"],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpreactjs%2Fpreact-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpreactjs%2Fpreact-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpreactjs%2Fpreact-router/lists"}