React Router v4 is coming up fast. The first beta was released this week which includes support for hooking into route changes. I needed the ability to run a couple things any time a route changed, so I came up with a simple component that runs as many things as I want when the url is updated.

A couple ideas of what to run on route changes:

  • We have a referral system that needs to check if there's a certain query parameter in the url.
  • setting a canonical url
  • Send a page view to google analytics on every page change.
  • Redirect users if they are not allowed on certain pages (ex a regular user hitting /admin)

Since the referral system came up, I decided it might be better to have a way to hook into these changes in a more general way.

Yes, I came up with this today, and yes it's a very easy thing to do!

After doing this I realized many people new to react router may be confused as to how this is done, so here's a quick guide on hooking into route changes!

Here's the component:

import { withRouter } from 'react-router'

export default class RouteChange extends React.Component {

  componentDidMount () {

  componentDidUpdate (prevProps) {
    let { location: { pathname } } = this.props

    if (prevProps.location.pathname === pathname) return

  routeChanged () {
    let { location, push, replace, actions } = this.props

    actions.forEach(action => {
      action(location, { push, replace })

  render () {
    return null

Now create an actions file and register as many functions as you'd like that will be ran on route changes:

import referral from './referral'
import redirectWrongUser from './redirect-wrong-user'

export default [

An example function might look like the referral code I made:

import qs from 'qs'
import ReferralRequest from './referral-request'

export default ({ pathname, search }) => {
  const requestParams = qs.parse(search)
  if (!requestParams.referrer) return

And there you have it, a simple way to add in hooks on route changes! Let's add it right inside our top-level Router component:

import routeActions from './route-actions'

export default () => (
      <Container />