An initial server rendering for my homepage route ( / ) works fine.
Also, subsequent client side navigation to ( /#/page2 ) works fine.
However, if I load /#/page2 directly from the address bar, the server rendered homepage loads in the browser first and then visibly transitions to /#/page2, which is not what I want. I want only /#/page2 to show up without first flashing the homepage.
What's happening is that node is serving up the homepage for the request to /, and then when the response hits the client, the client is running the route handler for /#/page2. Both are behaving correctly. But it's not what I want.
How do I avoid this behavior?
I think what I need is a way to for both the server and client to be aware of the different routes and both be able to handle them (isomorphically), however, the fragment part of the url is not known to the server.
Anyone else have this problem?
This problem isn't react specific. It is specific to SSR to a deep link.
My node router handles "/" as follows
router.get('/', function(req, res) {
var React = require('react');
var Router = require('react-router');
var Routes = require("../app/clapi-routes.jsx");
var router = Router.create({location: req.url, routes: Routes});
router.run(function(Handler, state) {
var html = React.renderToString(<Handler/>);
return res.render('index.ejs', {html:html});
})
});
index.ejs is just:
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/css/json-inspector.css"/>
</head>
<body style="margin:0">
<%- html %>
<script src="/build/bundle.js"></script>
</body>
</html>
Stop using hash powered navigation. Everything that comes after
#
is client-side only and useless for something like this. So/#/page2
needs to become/page2
.I'm not sure about react, but the same issue exists with other routing systems and there it's really easy to turn off the
#
in urls.In angular's ui-router is done like this
$locationProvider.html5Mode(true);
Your server-side would need to know to react to all the URLs your client-side knows, but that's how robustness is achieved - doesn't matter how navigation happens (client-side event or link click), both client and server can both handle the scenario end-to-end.