{"id":19466761,"url":"https://github.com/riot/route","last_synced_at":"2025-04-13T07:49:59.539Z","repository":{"id":33352130,"uuid":"36996935","full_name":"riot/route","owner":"riot","description":"Simple isomorphic router","archived":false,"fork":false,"pushed_at":"2025-02-21T21:55:12.000Z","size":1632,"stargazers_count":210,"open_issues_count":3,"forks_count":41,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-13T07:49:53.697Z","etag":null,"topics":["components","isomorphic","minimal","riotjs","route","router","simple"],"latest_commit_sha":null,"homepage":"","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/riot.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}},"created_at":"2015-06-06T22:20:35.000Z","updated_at":"2025-02-21T21:55:15.000Z","dependencies_parsed_at":"2023-02-13T08:45:19.667Z","dependency_job_id":"b85a3747-3fab-4bd8-abb1-faa16eb79b51","html_url":"https://github.com/riot/route","commit_stats":{"total_commits":314,"total_committers":19,"mean_commits":"16.526315789473685","dds":"0.47770700636942676","last_synced_commit":"760ee3c19601b68cda9e328c8679327d3438aec1"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riot%2Froute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riot%2Froute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riot%2Froute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riot%2Froute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/riot","download_url":"https://codeload.github.com/riot/route/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248681494,"owners_count":21144700,"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":["components","isomorphic","minimal","riotjs","route","router","simple"],"created_at":"2024-11-10T18:30:03.911Z","updated_at":"2025-04-13T07:49:59.509Z","avatar_url":"https://github.com/riot.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Riot Router\n\n[![Route logo](https://raw.githubusercontent.com/riot/branding/main/route/route-horizontal.svg)](https://github.com/riot/route/)\n\n[![Build Status][ci-image]][ci-url] [![Code Quality][codeclimate-image]][codeclimate-url] [![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Coverage Status][coverage-image]][coverage-url]\n\n\u003e Simple isomorphic router\n\nThe Riot.js Router is the minimal router implementation with such technologies:\n\n- compatible with the DOM pushState and history API\n- isomorphic functional API\n- [erre.js streams](https://github.com/GianlucaGuarini/erre) and javascript async generators\n- [rawth.js](https://github.com/GianlucaGuarini/rawth) urls parsing\n\nIt doesn't need Riot.js to work and can be used as standalone module.\n\n**For Riot.js 3 and the older route version please check the [v3 branch](https://github.com/riot/route/tree/v3)**\n\n## Table of Contents\n\n- [Install](#install)\n- [Documentation](#documentation)\n- [Demos](https://github.com/riot/examples)\n\n## Install\n\nWe have 2 editions:\n\n| edition                   | file                      |\n| :------------------------ | :------------------------ |\n| **ESM Module**            | `index.js`                |\n| **UMD Version**           | `index.umd.js`            |\n| **Standalone ESM Module** | `index.standalone.js`     |\n| **Standalone UMD Module** | `index.standalone.umd.js` |\n\n### Script injection\n\n```html\n\u003cscript src=\"https://unpkg.com/@riotjs/route@x.x.x/index.umd.js\"\u003e\u003c/script\u003e\n```\n\n_Note_: change the part `x.x.x` to the version numbers what you want to use: ex. `4.5.0` or `4.7.0`.\n\n### ESM module\n\n```js\nimport { route } from 'https://unpkg.com/@riotjs/route/index.js'\n```\n\n### npm\n\n```bash\n$ npm i -S @riotjs/route\n```\n\n### Download by yourself\n\n- [Standalone](https://unpkg.com/@riotjs/route/route.js)\n- [ESM](https://unpkg.com/@riotjs/route/route.esm.js)\n\n## Documentation\n\n### With Riot.js\n\nYou can import the `\u003crouter\u003e` and `\u003croute\u003e` components in your application and use them as it follows:\n\n```html\n\u003capp\u003e\n  \u003crouter\u003e\n    \u003c!-- These links will trigger automatically HTML5 history events --\u003e\n    \u003cnav\u003e\n      \u003ca href=\"/home\"\u003eHome\u003c/a\u003e\n      \u003ca href=\"/about\"\u003eAbout\u003c/a\u003e\n      \u003ca href=\"/team/gianluca\"\u003eGianluca\u003c/a\u003e\n    \u003c/nav\u003e\n\n    \u003c!-- Your application routes will be rendered here --\u003e\n    \u003croute path=\"/home\"\u003e Home page \u003c/route\u003e\n    \u003croute path=\"/about\"\u003e About \u003c/route\u003e\n    \u003croute path=\"/team/:person\"\u003e Hello dear { route.params.person } \u003c/route\u003e\n  \u003c/router\u003e\n\n  \u003cscript\u003e\n    import { Router, Route } from '@riotjs/route'\n\n    export default {\n      components { Router, Route }\n    }\n  \u003c/script\u003e\n\u003c/app\u003e\n```\n\nYou can also use the `riot.register` method to register them globally\n\n```js\nimport { Route, Router } from '@riotjs/route'\nimport { register } from 'riot'\n\n// now the Router and Route components are globally available\nregister('router', Router)\nregister('route', Route)\n```\n\n#### Router\n\nThe `\u003crouter\u003e` component should wrap your application markup and will detect automatically all the clicks on links that should trigger a route event.\n\n```html\n\u003crouter\u003e\n  \u003c!-- this link will trigger a riot router event --\u003e\n  \u003ca href=\"/path/somewhere\"\u003eLink\u003c/a\u003e\n\u003c/router\u003e\n\u003c!-- this link will work as normal link without triggering router events --\u003e\n\u003ca href=\"/path/to/a/page\"\u003eLink\u003c/a\u003e\n```\n\nYou can also specify the base of your application via component attributes:\n\n```html\n\u003crouter base=\"/internal/path\"\u003e\n  \u003c!-- this link is outside the base so it will work as a normal link --\u003e\n  \u003ca href=\"/somewhere\"\u003eLink\u003ca\u003e\n\u003c/router\u003e\n```\n\nThe router component has also an `onStarted` callback that will be called asynchronously after the first route event will be called\n\n```html\n\u003crouter onStarted=\"{onRouterStarted}\"\u003e\u003c/router\u003e\n```\n\n#### Route\n\nThe `\u003croute\u003e` component provides the `route` property to its children (it's simply a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object) allowing you to detect the url params and queries.\n\n```html\n\u003croute path=\"/:some/:route/:param\"\u003e {JSON.stringify(route.params)} \u003c/route\u003e\n\n\u003croute path=\"/search(.*)\"\u003e\n  \u003c!-- Assuming the URL is \"/search?q=awesome\" --\u003e\n\n  {route.searchParams.get('q')}\n\u003c/route\u003e\n```\n\nEach `\u003croute\u003e` component has its own lifecycle attributes in order to let you know when it gets mounted or unmounted.\n\n```riot\n\u003capp\u003e\n  \u003crouter\u003e\n    \u003croute path=\"/home\"\n      on-before-mount={onBeforeHomeMount}\n      on-mounted={onHomeMounted}\n      on-before-update={onBeforeHomeUpdate}\n      on-updated={onHomeUpdated}\n      on-before-unmount={onBeforeHomeUnmount}\n      on-unmounted={onHomeUnmounted}\n    /\u003e\n  \u003c/router\u003e\n\u003c/app\u003e\n```\n\n### Standalone\n\nThis module was not only designed to be used with Riot.js but also as standalone module.\nWithout importing the Riot.js components in your application you can use the core methods exported to build and customize your own router compatible with any kind of frontend setup.\n\nDepending on your project setup you might import it as follows:\n\n```js\n// in a Riot.js application\nimport { route } from '@riotjs/route'\n\n// in a standalone context\nimport { route } from '@riotjs/route/standalone'\n```\n\n#### Fundamentals\n\nThis module works on node and on any modern browser, it exports the `router` and `router` property exposed by [rawth](https://github.com/GianlucaGuarini/rawth)\n\n```js\nimport { route, router, setBase } from '@riotjs/route'\n\n// required to set base first\nsetBase('/')\n\n// create a route stream\nconst aboutStream = route('/about')\n\naboutStream.on.value((url) =\u003e {\n  console.log(url) // URL object\n})\n\naboutStream.on.value(() =\u003e {\n  console.log('just log that the about route was triggered')\n})\n\n// triggered on each route event\nrouter.on.value((path) =\u003e {\n  // path is always a string in this function\n  console.log(path)\n})\n\n// trigger a route change manually\nrouter.push('/about')\n\n// end the stream\naboutStream.end()\n```\n\n#### Base path\n\nBefore using the router in your browser you will need to set your application base path.\nThis setting can be configured simply via `setBase` method:\n\n```js\nimport { setBase } from '@riotjs/route'\n\n// in case you want to use the HTML5 history navigation\nsetBase(`/`)\n\n// in case you use the hash navigation\nsetBase(`#`)\n```\n\nSetting the base path of your application route is mandatory and is the first you probably are going to do before creating your route listeners.\n\n#### DOM binding\n\nThe example above is not really practical in case you are working in a browser environment. In that case you might want to bind your router to the DOM listening all the click events that might trigger a route change event.\nWindow history `popstate` events should be also connected to the router.\nWith the `initDomListeners` method you can automatically achieve all the features above:\n\n```js\nimport { initDomListeners } from '@riotjs/route'\n\nconst unsubscribe = initDomListeners()\n// the router is connected to the page DOM\n\n// ...tear down and disconnect the router from the DOM\nunsubscribe()\n```\n\nThe `initDomListeners` will intercept any link click on your application. However it can also receive a HTMLElement or a list of HTMLElements as argument to scope the click listener only to a specific DOM region of your application\n\n```js\nimport { initDomListeners } from '@riotjs/route'\n\ninitDomListeners(document.querySelector('.main-navigation'))\n```\n\n[ci-image]: https://img.shields.io/github/actions/workflow/status/riot/route/test.yml?style=flat-square\n[ci-url]: https://github.com/riot/route/actions\n[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square\n[license-url]: LICENSE.txt\n[npm-version-image]: http://img.shields.io/npm/v/@riotjs/route.svg?style=flat-square\n[npm-downloads-image]: http://img.shields.io/npm/dm/@riotjs/route.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/@riotjs/route\n[coverage-image]: https://img.shields.io/coveralls/riot/route/main.svg?style=flat-square\n[coverage-url]: https://coveralls.io/github/riot/route/?branch=main\n[codeclimate-image]: https://api.codeclimate.com/v1/badges/1487b171ba4409b5c302/maintainability\n[codeclimate-url]: https://codeclimate.com/github/riot/route\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friot%2Froute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Friot%2Froute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friot%2Froute/lists"}