Sync or Async

Curi can have synchronous and asynchronous routes.

When a navigation event is triggered (e.g. clicking a link or button), the router will match a route. If the route is synchronous, the response will be emitted immediately. If the route is asynchronous, the response will not be emitted until the route's async functions have finished. This is useful for code splitting and preloading data for a route.

By default, routes are synchronous. If a route has any functions in its resolve object, it becomes async.

// sync
{ name: "Home", path: "" },

// async
  name: "User",
  path: "user/:id,
  // any functions in here makes the route async
  resolve: {
    body: () => import("./components/User"),

Async Things to Think About

For the most part, it shouldn't matter to you (or your users) whether Curi is sync or async, but there are a couple of things that you should be aware of when it comes to async matching.

  1. If the initial route that matches is async and you try to render immediately, the response will be null. You can wait to render until the initial response is ready with router.oncd(). The function you pass to that will be called one time, once the initial response is ready.

    const router = curi(history, routes);
    router.once(() => {
      // the initial response is ready,
      // so it is safe to render
  2. With async routes, there is a delay between when the user clicks a link and when the new response is emitted. During this time, the navigation can be interrupted with a new navigation. Curi handles this internally, but you might want to update your UI after a link/button is clicked to indicate that the next page is loading.

    You can see an example of this in the Data Loading Example.

      params={{ id: 1 }}
      onClick={() => {
        // display a loading bar when
        // the user clicks a link.
    >User 1</Link>
    // use a side effect to finish
    // loading bar when the new response
    // is ready
    const finishLoading = () => {
    const router = curi(history, routes, {
      sideEffects: [finishLoading]