Enable deep linking for a react-router application behind an authenticated express.js server

Jaaq Jorissen
3 min readFeb 25, 2016

When a user clicks on a URL of a react application that uses react-router for routing, you would expect them to arrive there without a problem. But what happens when this application is running on a server that requires authentication?

That’s easy enough, you say: You redirect them to the login screen and subsequently forward them to the correct route. And I would say you are correct! The only catch here is that react-router uses the hash-component of the URL (the part behind the # sign) to handle its routing, and the server has no clue what that part is. Here’s what Wikipedia has to say on the subject:

The fragment identifier functions differently than the rest of the URI: namely, its processing is exclusively client-side with no participation from the server. When an agent (such as a Web browser) requests a resource from a Web server, the agent sends the URI to the server, but does not send the fragment.

So, let me share with you one way of circumventing this problem. As the title suggests, this article presumes your application is hosted on a node.js backend running express and using passport for authentication (passport-local, more specifically).

Let’s say your user is trying to visit the following URL:

www.homepage.com/app/#/articles/123

Your react application is running on the /app/ route, and he’s trying to visit the route /articles/123. But, alas, this is a members only website and your user will have to log in. Your express app will detect an unauthorised request, and redirect the user to www.homepage.com/login

Note that when you were not using react router, this would be the place to save the user’s current route. You could get the full URL where the request came from, using the following code:

let url = req.protocol + ‘://’ + req.get(‘host’) + req.originalUrl;

You could then save this url in the request’s session object, and use it later.

As a react-router aficionado though, at this point, the only information available to you would be http://www.homepage.com/app/ for the reasons stated above. So, we redirect the user to the login page where the proverbial magic will happen.

As you redirect the user, the URL will change from homepage.com/app/ to homepage.com/login/ but the fragment identifier will remain — since the server has no control over this. This works in our advantage! Now we can use good old javascript to fetch this hash and send it to our server, along with the login details. I’m using a jade template for my login page, which would look a little something like this:

Notice the cheeky hidden input field called url. That’s where we will attach the relevant information about our react-router that’s stored in the hash. We do this by running the single line of javascript at the bottom.

Once the user hits the Sign in button, a post to your express application happens where you can then recover the url parameter. If you are using passport.js to handle your authentication, you might have to make a few changes to your Passport strategy in order for it to work. I’ve included my code samples below.

Et voila, your user will automagically be redirected to the correct route for your react-router application! I hope you found this post useful, if you did you might want to consider following me on twitter.

--

--