{"id":18611562,"url":"https://github.com/robertdp/purescript-web-router","last_synced_at":"2025-08-30T12:15:52.349Z","repository":{"id":42858882,"uuid":"260128062","full_name":"robertdp/purescript-web-router","owner":"robertdp","description":"A simple pushstate router, with support for async routing logic. Bring your preferred parser, printer and state management.","archived":false,"fork":false,"pushed_at":"2023-02-04T14:46:08.000Z","size":243,"stargazers_count":15,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-03T05:37:06.581Z","etag":null,"topics":["pushstate","pushstate-routing","router"],"latest_commit_sha":null,"homepage":"","language":"PureScript","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/robertdp.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":"2020-04-30T06:10:41.000Z","updated_at":"2023-11-06T08:16:41.000Z","dependencies_parsed_at":"2023-02-18T17:16:10.656Z","dependency_job_id":null,"html_url":"https://github.com/robertdp/purescript-web-router","commit_stats":null,"previous_names":["robertdp/purescript-react-basic-hooks-router"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/robertdp/purescript-web-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdp%2Fpurescript-web-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdp%2Fpurescript-web-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdp%2Fpurescript-web-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdp%2Fpurescript-web-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertdp","download_url":"https://codeload.github.com/robertdp/purescript-web-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdp%2Fpurescript-web-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272847310,"owners_count":25003168,"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","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["pushstate","pushstate-routing","router"],"created_at":"2024-11-07T03:14:13.202Z","updated_at":"2025-08-30T12:15:52.331Z","avatar_url":"https://github.com/robertdp.png","language":"PureScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# purescript-web-router\n\nA router for browsers that supports asynchronous routing logic. Bring your own printing and parsing (check out [routing-duplex](https://github.com/natefaubion/purescript-routing-duplex)).\n\nFor a basic React example see [here](https://github.com/robertdp/purescript-web-router-example/tree/master/src).\n\n## How to use\n\n### 1. Install with Spago\n\n`$ spago install web-router`\n\n### 2. Define your routes\n\n```purescript\ndata Route\n  = Page Page\n  | NotFound\n\ndata Page\n  = Home\n  | ProductList\n  | ProductView ProductId\n  | About\n  | ContactUs\n\ntype ProductId = Int\n```\n\n### 3. Implement parsing and printing\n\nThis example uses [routing-duplex](https://github.com/natefaubion/purescript-routing-duplex).\n\n\u003cdetails\u003e\n\u003csummary\u003eImports\u003c/summary\u003e\n\n```purescript\nimport Prelude hiding ((/))\nimport Data.Either (Either)\nimport Data.Generic.Rep (class Generic)\nimport Routing.Duplex (RouteDuplex', default, end, int, parse, print, root, segment)\nimport Routing.Duplex.Generic (noArgs, sum)\nimport Routing.Duplex.Generic.Syntax ((/))\nimport Routing.Duplex.Parser (RouteError)\n```\n\n\u003c/details\u003e\n\n```purescript\nderive instance Generic Route _\nderive instance Generic Page _\n\nproductId :: RouteDuplex' ProductId\nproductId = int segment\n\nroutes :: RouteDuplex' Route\nroutes =\n  default NotFound $\n    sum\n      { \"Page\": pages\n      , \"NotFound\": \"404\" / noArgs\n      }\n\npages :: RouteDuplex' Page\npages =\n  root $ end $\n    sum\n      { \"Home\": noArgs\n      , \"ProductList\": \"products\" / noArgs\n      , \"ProductView\": \"products\" / productId\n      , \"About\": \"about\" / noArgs\n      , \"ContactUs\": \"about\" / noArgs\n      }\n\n-- | This is the route parser we need to pass to the driver.\n-- | It can produce any route which allows the parser to return a value of `NotFound` instead of failing.\nparseRoute :: forall  String -\u003e Either RouteError Route\nparseRoute = parse routes\n\n-- | This is the route printer we need to pass to the driver.\n-- | It can only print paths to valid pages, which means a path can't be produced for the `NotFound` route.\n-- | With this approach routes can be seperated based on whether they should be a navigation target and have a URL.\n-- | Note: assymetry is not required, and a symmetrical printer works as well.\nprintRoute :: Page -\u003e String\nprintRoute = print pages\n```\n\n### 4. Define how your application reacts to navigation and routing events\n\n\u003cdetails\u003e\n\u003csummary\u003eImports\u003c/summary\u003e\n\n```purescript\nimport Web.Router as Router\n```\n\n\u003c/details\u003e\n\n```purescript\nonNavigation :: Maybe Route -\u003e Route -\u003e Router.RouterM Route Page Router.Routing Router.Resolved Unit\nonNavigation previousRoute requestedRoute =\n  case requestedRoute of\n    NotFound -\u003e\n      case previousRoute of\n        Just (Page page) -\u003e Router.do\n          liftEffect showBrokenNavigationMessage\n          Router.redirect page -- redirect back to the previous page and show a message\n        _ -\u003e\n          Router.continue -- no previous page, so just show the \"not found\" page\n    _ -\u003e Router.do\n      access \u003c- liftAff fetchUserAccess\n      if userHasAccess requestedRoute access then\n        Router.continue -- they have access, so resolve with the requested page\n      else\n        Router.override NotFound -- no access, so pretend the page doesn't exist\n\n\nonEvent :: Router.RoutingEvent Route -\u003e Effect Unit\nonEvent newEvent =\n  case newEvent of\n    Router.Routing previousRoute requestedRoute -\u003e\n      showNavigationSpinner\n    Router.Resolved previousRoute newRoute -\u003e\n      hideNavigationSpinner\n      setCurrentRoute newRoute\n```\n\n### 5. Connect up the driver and router\n\n\u003cdetails\u003e\n\u003csummary\u003eImports\u003c/summary\u003e\n\n```purescript\nimport Web.Router as Router\nimport Web.Router.PushState as PushState\n```\n\n\u003c/details\u003e\n\n```purescript\nmkRouter :: Effect (Router.Router Route Page)\nmkRouter = do\n  driver \u003c- PushState.mkInterface parseRoute printRoute\n  router \u003c- Router.mkInterface onNavigation onEvent driver\n  pure router\n```\n\nBoth pushstate and hash drivers are included, or a custom driver can be implemented. An example of a custom driver could be one that synchronises some navigation state over sockets, for an experience where one user's behaviour could be broadcast to multiple users to follow along.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertdp%2Fpurescript-web-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertdp%2Fpurescript-web-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertdp%2Fpurescript-web-router/lists"}