1

I am trying to build a project using an isomorphic server-side rendering react. For some reason, the project stopped starting after adding routing. The browser throws the following error:

Error: Invariant failed: Browser history needs a DOM

Maybe someone can tell me what's wrong there.

Here is server.js code:

import express from "express";
import path from "path";
import React from "react";
import { StaticRouter } from "react-router";
import ReactDOMServer from "react-dom/server";
import App from "./src/App";

const app = express();

app.get('*', (req,res) => {
  const context = {};
  const data = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context}>
      <App />
    </StaticRouter>
  );
  const html = `
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>  
  </head>
  <body>
    <div id="root">${data}</div>
    <script src="bundle.js"></script>
  </body>
  </html>
  `;
  res.send(html);
});

app.use( express.static( path.resolve( __dirname, "dist" ) ) );

app.listen(3000);

App.jsx code:

import React, { Component } from 'react';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import First from './First';
import Second from './Second';
import Home from './Home';

class App extends Component {
  render() {
    return (
      <div>
        <BrowserRouter>
          <Switch>
            <Route path="/" exact component={Home} />
            <Route path="/first" component={First} />
            <Route path="/second" component={Second} />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

export default App;

There is a lot of code and files to bring it all here, but i placed it at Github repository. Thanks if someone can help!

Here is a link to the repository: isomorphic-react

Kiten
  • 985
  • 2
  • 17
  • 35

1 Answers1

1

It's OK, I figure it out. It was necessary to place the BrowswrRouter container in index.js, not in App.jsx.

Here is corrected index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from "react-router-dom";

ReactDOM.hydrate(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

Here is corrected App.jsx:

import React, { Component } from 'react';
import { Switch, Route } from "react-router-dom";
import First from './First';
import Second from './Second';
import Home from './Home';

class App extends Component {
  render() {
    return (
      <div>
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/first" component={First} />
          <Route path="/second" component={Second} />
        </Switch>
      </div>
    );
  }
}

export default App;
Kiten
  • 985
  • 2
  • 17
  • 35