Material-ui: Server Render issue -- Mismatched DOM

Created on 22 Mar 2017  路  4Comments  路  Source: mui-org/material-ui

Having an issue integrating material into an isomorphic react application. I believe it may be associated to the theme not being rendered on the server side, I have it included in both renders with matching user agents. An image and code is referenced below...

screen shot 2017-03-22 at 1 52 47 pm

SERVER RENDER

// React route matching, server side rendering
  match(routerParams, (err, redirectLocation, renderProps) => {
    if (err) {
      const msg = 'Internal server error';
      if (env.NODE_ENV === 'development') {
        throw new Error(msg);
      }
      req[env.NAMESPACE].log.server(msg, 'error');
      return res.status(500).end('Internal server error');
    }
    if (!renderProps) return res.status(404).end('Not found');

    function renderView() {
      const materialStyle = React.createElement(MuiThemeProvider);
      const rootView = React.createElement(RouterContext, renderProps, materialStyle);
      const rootStyle = React.createElement(IsoStyle, {
        onInsertCss: (styles) => { css.push(styles._getCss()); },
      }, rootView);
      const rootRedux = React.createElement(Provider, { store }, rootStyle);
      const rootComponent = renderToString(rootRedux);
      const rootState = JSON.stringify(store.getState());
      const template = `
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>Astral | Demo</title>
          <script>
            window.__ROOT_STATE__ = ${rootState};
          </script>
          <style>${css.join('')}</style>
        </head>
        <body>
          <div id="app-entry">${rootComponent}</div>
          <script src="http://localhost:3001/render.bundle.js"></script>
        </body>
      </html>
      `;
      return template;
    }
    req[env.NAMESPACE].log.server('Render success', 'info');
    res.send(renderView());

CLIENT RENDER

render() {
    return (
      <div id="base-view">
        <MuiThemeProvider>
          {this.props.children}
        </MuiThemeProvider>
      </div>
    );
  }

Versions

  • Material-UI: 0.17.1
  • React: 15.4.2
  • Browser: Chrome
question

All 4 comments

Not really related to material-ui and pretty common when using server side rendering.
The solution is quite weird but just wrap your <div id="app-entry"> with another div
http://stackoverflow.com/a/33521172

Also, look here regarding the user agent that you're missing https://github.com/callemall/material-ui/issues/4437#issuecomment-255649698

@slavab89 Unfortunately the div wrapper will not fix the issue (I tried just to be sure, know of this issue)....this is not a new application, has generally be working fine up until the Material UI integration.

I'll just show you what i have on my end (dont have this error)

SSR

const createApp = (store, props, userAgent) => renderToString(
  <Provider store={store}>
    <MuiThemeProvider muiTheme={getMuiTheme({userAgent, ...muiTheme})}>
      <RouterContext {...props} />
    </MuiThemeProvider>
  </Provider>
);

const pageHtml = (store, props, userAgent) =>
`<!doctype html>
<html>
  <head>
....
  </head>
  <body>
    <div id="app"><div>${createApp(store, props, userAgent)}</div></div>
    <script>window.__INITIAL_STATE__ = ${JSON.stringify(store.getState())}</script>
    <script type="text/javascript" charset="utf-8" src="/assets/app.js"></script>
  </body>
</html>`

Client

render(
  <Provider store={store}>
    <MuiThemeProvider muiTheme={getMuiTheme(muiTheme)}>
      <Router history={history}>
        {routes}
      </Router>
    </MuiThemeProvider>
  </Provider>, document.getElementById('app'));

It seems quite similar to what you have, the only diff i see is the additional div that i've added and the userAgent.

The prefixing strategy between the client and the server needs to be the same in order to remove this warning. You have 3 options:

  • Prefix for everybody
  • Prefix for the user-agent
  • Or do like me, prefix for everybody on the server in order to maximise caching efficiency and only prefix for the user-agent on the client for faster style computation (you will get this exact same warning)

It's a matter of tradeoff, pick the option that best fit your needs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TimoRuetten picture TimoRuetten  路  3Comments

rbozan picture rbozan  路  3Comments

pola88 picture pola88  路  3Comments

FranBran picture FranBran  路  3Comments

sys13 picture sys13  路  3Comments