You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
derive instanceGenericRoute_derive instanceGenericPage_productId::RouteDuplex'ProductId
productId = int segment
routes::RouteDuplex'Route
routes =
default NotFound $
sum
{ "Page": pages
, "NotFound": "404" / noArgs
}
pages::RouteDuplex'Page
pages =
root $ end $
sum
{ "Home": noArgs
, "ProductList": "products" / noArgs
, "ProductView": "products" / productId
, "About": "about" / noArgs
, "ContactUs": "about" / noArgs
}
-- | This is the route parser we need to pass to the driver.-- | It can produce any route which allows the parser to return a value of `NotFound` instead of failing.parseRoute::forallString->EitherRouteErrorRoute
parseRoute = parse routes
-- | This is the route printer we need to pass to the driver.-- | It can only print paths to valid pages, which means a path can't be produced for the `NotFound` route.-- | With this approach routes can be seperated based on whether they should be a navigation target and have a URL.-- | Note: assymetry is not required, and a symmetrical printer works as well.printRoute::Page->String
printRoute = print pages
4. Define how your application reacts to navigation and routing events
Imports
importWeb.RouterasRouter
onNavigation::MaybeRoute->Route->Router.RouterMRoutePageRouter.RoutingRouter.ResolvedUnit
onNavigation previousRoute requestedRoute =
case requestedRoute ofNotFound->case previousRoute ofJust (Page page) ->Router.do
liftEffect showBrokenNavigationMessage
Router.redirect page -- redirect back to the previous page and show a message
_ ->Router.continue -- no previous page, so just show the "not found" page
_ ->Router.do
access <- liftAff fetchUserAccess
if userHasAccess requestedRoute access thenRouter.continue -- they have access, so resolve with the requested pageelseRouter.override NotFound-- no access, so pretend the page doesn't existonEvent::Router.RoutingEventRoute->EffectUnit
onEvent newEvent =
case newEvent ofRouter.Routing previousRoute requestedRoute ->
showNavigationSpinner
Router.Resolved previousRoute newRoute ->
hideNavigationSpinner
setCurrentRoute newRoute
mkRouter::Effect (Router.RouterRoutePage)
mkRouter = do
driver <-PushState.mkInterface parseRoute printRoute
router <-Router.mkInterface onNavigation onEvent driver
pure router
Both 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.
About
A simple pushstate router, with support for async routing logic. Bring your preferred parser, printer and state management.