Site / Site and the Router

What the application writes around it

The routing example, before it moved onto foldkit-site, shows what that leaves to the application. Its update answered both Messages by hand:

ts
ClickedLink: ({ request }) =>
  UrlRequest.match<UpdateReturn>(request, {
    Internal: ({ url }) => ({ model, commands: [NavigateInternal({ url: urlToString(url) })] }),
    External: ({ href }) => ({ model, commands: [LoadExternal({ href })] }),
  }),

ChangedUrl: ({ url }) => {
  const nextRoute = urlToAppRoute(url)
  if (Equal.equals(nextRoute, model.route)) return { model }
  const routeSteps = Match.value(nextRoute).pipe(
    Match.withReturnType<ReadonlyArray<Update.Step<Model, Message>>>(),
    Match.tag('People', peopleRoute => [foldPeopleRouteChanged(peopleRoute)]),
    Match.orElse(() => []),
  )
  return Update.combine(model, [setRoute(nextRoute), ...routeSteps])
},

Around those two branches it kept four more tables, each listing the routes again:

  • Nav sections: which section each route belongs to, matched route by route.
  • Section links: each section's address, built from its router.
  • Shortcuts: a literal union of shortcuts, a table from each shortcut to a URL, and a key binding for each.
  • Titles: each route's title, in the view.

Add a route and five places change. Nothing checks that they agree: a section can link to an address its own router would not build, and a shortcut can name a page that no longer exists. Every in-app link also used pushUrl, so even a link to the page already shown added a Back step.