I have the following route code,
import React from 'react';
import { createHistory } from 'history';
import {Router, Route} from 'react-router';
import {
App,
Chat,
Home,
Widgets,
About,
Login,
Track,
RequireLogin,
LoginSuccess,
Survey,
NotFound,
} from 'containers';
const history = createHistory();
export default function() {
return (
<Router history={history}>
<Route component={App}>
<Route path="/" component={Home}/>
<Route path="/widgets" component={Widgets}/>
<Route path="/about" component={About}/>
<Route path="/login" component={Login}/>
<Route path="/track/:id" component={Track}/>
<Route component={RequireLogin}>
<Route path="/chat" component={Chat}/>
<Route path="/loginSuccess" component={LoginSuccess}/>
</Route>
<Route path="/survey" component={Survey}/>
<Route path="*" component={NotFound}/>
</Route>
</Router>
);
}
and I get this error (it did start when I added createHistory).
[1] [piping] can't execute file: /Users/bortignon/dev/ReactTracklistMe/bin/server.js
[1] [piping] error given was: Error: Invariant Violation: Browser history needs a DOM
[1] at Object.invariant [as default] (/Users/bortignon/dev/ReactTracklistMe/node_modules/history/node_modules/invariant/invariant.js:44:15)
[1] at Object.createBrowserHistory [as createHistory] (/Users/bortignon/dev/ReactTracklistMe/node_modules/history/lib/createBrowserHistory.js:39:25)
[1] at Object.<anonymous> (/Users/bortignon/dev/ReactTracklistMe/src/routes.js:18:17)
[1] at Module._compile (module.js:460:26)
[1] at normalLoader (/Users/bortignon/dev/ReactTracklistMe/node_modules/babel-core/lib/api/register/node.js:199:5)
[1] at Object.require.extensions.(anonymous function) [as .js] (/Users/bortignon/dev/ReactTracklistMe/node_modules/babel-core/lib/api/register/node.js:216:7)
[1] at Module.load (module.js:355:32)
[1] at Module._load (module.js:310:12)
[1] at Function.module._load (/Users/bortignon/dev/ReactTracklistMe/node_modules/piping/lib/launcher.js:32:16)
[1] at Module.require (module.js:365:17)
[1] at require (module.js:384:17)
@nicolabortignon You cannot use the BrowserHistory on the server. For server-side rendering you have to use createLocation and create a one-off location object which you can use with match in order to figure out what needs to be rendered on the server.
Take a look at https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md as an example.
Note: For universal application you generally need two entry/bootstrap files - one for the client and one for the server - because albeit them reusing mostly the same application, the bootstrap process is different.
@johanneslumpe thanks for the pointer! I'm still struggling in grasping how everything works, but I'll dig into that blob!
Thanks
@nicolabortignon sure no problem :) If this is solved for now feel free to close, so we know that this is taken care of.
I'm having the same problem using history, react 0.14 and react-router 1.0.0-rc3.
I'm following the server-side example from the guides, and have a front-end webpack entry at client.js. In client.js, I either have ReferenceError: document is not defined, or Browser history needs a DOM errors.
Server entry:
module.exports = function( req, res, next ) {
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
res
.status( 200 )
.set( 'Content-Type', 'text/html' )
.send( '<!doctype html>' +
renderToString(
[ <RoutingContext {...renderProps} />,
<HtmlDocument /> ]
)
);
} else {
res
.status(404)
.send('Not found');
}
})
};
client.js:
import { render } from 'react-dom';
import routes from './routes';
render( routes, document.getElementById('app') )
And my routes.jsx:
import React from 'react';
import { Router, Route, IndexRoute } from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';
import Application from './Application';
import Index from './pages/index';
import App from './pages/app';
import Auth from './pages/auth';
import Login from './pages/auth/components/Login';
import Signup from './pages/auth/components/Signup';
import NotFound from './pages/notFound';
var routes = (
<Router history={createBrowserHistory()}>
<Route path="/" component={Application}>
<IndexRoute component={Index} />
<Route path="app" component={App} onEnter={ App.requireAuth } />
<Route path="auth" component={Auth} />
<Route path="signup" component={Signup} />
<Route path="login" component={Login} />
<Route path="*" component={NotFound} />
</Route>
</Router>
);
export default routes;
@almccann For questions and support, please visit our channel on Reactiflux or Stack Overflow. The issue tracker is exclusively for bug reports and feature requests.
Cool, thanks @knowbody
For what its worth, here's my question again: http://stackoverflow.com/questions/33403549/cannot-access-dom-with-server-side-render-react-0-14-1-react-dom-0-14-1-and-r
Most helpful comment
I'm having the same problem using history, react 0.14 and react-router 1.0.0-rc3.
I'm following the server-side example from the guides, and have a front-end webpack entry at client.js. In client.js, I either have ReferenceError: document is not defined, or Browser history needs a DOM errors.
Server entry:
client.js:
And my routes.jsx: