Side Effects

Curi side effects are permanent router response handlers that are run after those registered using router.observe and router.once.

Whenever a new response is generated, all of the side effect functions will be called. They will be given an object with the new response object, a navigation object with some extra routing data (the navigation action the previous response), and the router object.

function logResponse({ response }) {
  // call your logging API to record the response

Adding Side Effects

Side effects are provided to your router with the sideEffects property of the options object. This is an array of observer functions.

const router = createRouter(browser, routes, {
  sideEffects: [logResponse, updateTitle]

Side effects are always run after observers registered using router.observe and router.once. Because those forms of response handler registration are primarily used for rendering the application, this means that the side effects will be called after the application has re-rendered.

const router = createRouter(browser, routes, {
  sideEffects: [logResponse]

const render = () => {
  // render the app


// whenever there is a response, render will be
// called before logResponse

Official Side Effects

Curi has two "official" side effect packages:

import titleEffect from "@curi/side-effect-title";
import scrollEffect from "@curi/side-effect-scroll";

const router = createRouter(browser, routes, {
  sideEffect: [titleEffect(), scrollEffect()]

Creating Side Effects

When creating your own side effect, you can write a regular function or a side effect "factory".

function mySideEffect({ response, navigation }) {
  console.log('Navigating to', response.location);
  console.log('Navigation action:', navigation.action);

const router = createRouter(browser, routes, {
  sideEffects: [mySideEffect]

A side effect factory lets create a more customizable side effect.

function AnalyticsLogger(options) {
  // do some setup with the provided options
  const logger = setupMyLogger(options);

  // and return the actual side effect function
  return sideEffect({ response }) {

You may want to review the response properties to know which properties you should expect a response to have.