{"id":15485789,"url":"https://github.com/codediodeio/hotroute","last_synced_at":"2025-07-19T03:37:49.071Z","repository":{"id":57266959,"uuid":"162467424","full_name":"codediodeio/hotroute","owner":"codediodeio","description":null,"archived":false,"fork":false,"pushed_at":"2020-07-08T17:37:48.000Z","size":60,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-26T14:53:12.806Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codediodeio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-19T17:05:29.000Z","updated_at":"2025-04-01T17:18:20.000Z","dependencies_parsed_at":"2022-08-25T03:41:17.377Z","dependency_job_id":null,"html_url":"https://github.com/codediodeio/hotroute","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/codediodeio/hotroute","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codediodeio%2Fhotroute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codediodeio%2Fhotroute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codediodeio%2Fhotroute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codediodeio%2Fhotroute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codediodeio","download_url":"https://codeload.github.com/codediodeio/hotroute/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codediodeio%2Fhotroute/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265883713,"owners_count":23843800,"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":[],"created_at":"2024-10-02T06:03:17.218Z","updated_at":"2025-07-19T03:37:49.049Z","avatar_url":"https://github.com/codediodeio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hotroute ⚡\n\nStatus: Experimental 🧫\n\nAn 2.5kB zero-config router and prefetcher for static or server-rendered sites.\n\n## Why?\n\nHTTP is stateless. What if you could maintain state between full page changes without building an SPA? \n\nIdeal for static or server-rendered web apps using web components that want super fast page changes without losing stateful data in JavaScript. Expect page transitions **under 50ms** for an average blog post on an average network. \n\n## How?\n\n(1) It prefetches visible links in the page with intersection observer, thanks to [quicklink](https://github.com/GoogleChromeLabs/quicklink). (2) Intercepts click and popstate events, then updates the HTML5 history on qualifed route changes.  (3) Swaps the body out, while preserving most of the head (will change title and meta tags automatically).\n\nThis means if you use a global state management system, i.e. Angular DI or React Context or just plain old JS, your static content will change, but your web components will maintain state across HTTP requests. \n\nIt will fallback to standard naviation if `window.history` does not exist. \n\n## QuickStart\n\n```\nnpm i hotroute\n```\n\n```js\nimport hotroute from hotroute;\nconst router = hotroute();\n```\n\nThat's it. Magic (maybe too much).\n\n\n## Advanced Usage\n\n```js\n// with opts \nconst router = hotroute({ log: true, prefetch: true });\n\n// Navigate manually\nrouter.go('/somewhere');\n\n// Listen to events\nwindow.addEventListener('router:fetch', showLoader);\nwindow.addEventListener('router:end', hideLoader);\n```\n\n### What is happening in the DOM?\n\nHere's how things change in the DOM on a navigation event. \n\n```html\n\u003chead\u003e\n    \u003c!-- meta tags change --\u003e\n    \u003cmeta name=\"description\" content=\"my cool page\"\u003e\n\n    \u003c!-- title changes --\u003e\n    \u003ctitle\u003eDocument\u003c/title\u003e \n\n    \u003c!-- everything else does NOT change --\u003e\n    \u003cscript src=\"my-bundle.js\"\u003e\u003c/script\u003e \n\n    \u003c!-- head scripts or nodes can be re-evaluated with data-reload --\u003e\n    \u003cscript data-reload src=\"my-other-bundle.js\"\u003e\u003c/script\u003e \n\u003c/head\u003e\n\u003cbody\u003e\n    \u003c!-- ALL body content changes --\u003e\n    \n    \u003c!-- nodes can be cloned with data-stateful --\u003e\n    \u003cnav data-stateful\u003e\u003c/nav\u003e \n\u003c/body\u003e\n```\n\n### Caveats\n\n- Body scripts will never run (but you should be using defer anyway)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodediodeio%2Fhotroute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodediodeio%2Fhotroute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodediodeio%2Fhotroute/lists"}