When Curi receives a location, it compares the location's pathname to each route's path to find which one matches best and uses that route to create a response object.

The Properties of a Response Object

There are two types of response properties.

The "match" properties are set based on the route that matches a location. A response always has these properties.

// match properties
  // The location object used to generate the response.
  location: { pathname: '/photos/6789/12345', ... },

  // The name of the best matching route
  name: 'Photo',

  // The name of ancestor routes that matched
  // part of the location's pathname
  partials: ['Album'],

  // An object containing the values parsed
  // from the pathname by path-to-regexp.
  // This includes params from ancestor routes.
  params: { photoID: 12345, albumID: 6789 },

The "settable" properties are ones that are added by a matched route's response function. These only exist on the response when they are returned by a route's response function.

The "settable" properties are:

bodyThe component(s) that should be rendered for a route.
statusAn http status, mostly useful for server side rendering.
dataA place to attach any data you want to the response, such as data loaded in the route's resolve function.
titleThe response's title, which can be used with @curi/side-effect-title to set the browsers tab's title.
errorA convenient place to attach any errors to the response.
redirectToAn object describing a route that Curi should automatically redirect to.
// settable properties (optional)
  body: Photo,
  // or maybe
  body: {
    menu: PhotoMenu,
    main: Photo
  // Please see below for more information
  // about this property

  status: 200,

  data: {...},

  title: 'Photo 12345',

  error: undefined,

  redirectTo: {...}

Response Body

Curi isn't strict about how you use responses, but you will most likely always want to use a route's response function to attach a body property to a response. The usual pattern is to use a route's body property to describe which component(s) to render when a route matches. This can either be a single component for basic layouts or an object with a number of components for advanced layouts.


Each route should use the same body "shape". If one route returns a single component while another route return an object, you will be making rendering more complicated for yourself.

// do NOT do this
// mixing body shapes complicates rendering
const routes = prepareRoutes([
    response() {
      return { body: One }
    response() {
      return {
        body: {
          main: Main,
          menu: Menu

Redirect Response

When a route's response function returns an object with a redirectTo property, the router will use it to generate a location object that Curi will automatically redirect to.

  // The redirectTo property provides information on
  // where you should redirect to
  redirectTo: { name: "Login" }

When creating a router, you can set the emitRedirects option to false and the response will not be sent to observers and one time functions. Redirect responses don't usually have anything to render, so setting this option is usually ideal.

const router = curi(history, routes, {
  emitRedirects: false