Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify SSR approach to work with Create React App #13242

Closed
2 tasks done
nareshbhatia opened this issue Oct 14, 2018 · 3 comments
Closed
2 tasks done

Simplify SSR approach to work with Create React App #13242

nareshbhatia opened this issue Oct 14, 2018 · 3 comments
Labels
new feature New feature or request

Comments

@nareshbhatia
Copy link
Contributor

The current approach for server-side rendering as illustrated by the SSR example is difficult to implement with popular templates like Create React App. This is primarily due to the differences between the top-level renderers on the server-side vs. the client-side. Is it possible to change this approach to simplify SSR?

  • This is not a v0.x issue.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

The server-side render should work by starting with ./build/index.html. This makes sure that we are automatically using one or more chunks created by the normal build process. Here's how I have seen it done in most SSR articles:

app.get('^/$', (req, res) => {
    // Point to the html file created by CRA's build tool
    const indexFile = path.resolve('./build/index.html');

    fs.readFile(indexFile, 'utf8', (err, indexHtml) => {
        if (err) {
            console.error('Something went wrong:', err);
            return res.status(500).send('Oops, better luck next time!');
        }

        // Render the app as an HTML string
        const appHtml = ReactDOMServer.renderToString(<App />);

        // Inject the rendered app into our html and send it
        return res.send(
            indexHtml.replace(
                '<div id="root"></div>',
                `<div id="root">${appHtml}</div>`
            )
        );
    });
});

Current Behavior

In the current example, the client and server side renders are different. Specifically, the server-side render assumes that the JavaScript bundle produced by the build process is build/bundle.js. See the code below from server.js:

function renderFullPage(html, css) {
  return `
    <!doctype html>
    <html>
      <head>
        <title>Material-UI</title>
      </head>
      <body>
        <script async src="build/bundle.js"></script>
        <div id="root">${html}</div>
        <style id="jss-server-side">${css}</style>
      </body>
    </html>
  `;
}

We cannot assume this. For example, Create React App produces multiple chunks with dynamic names like main.0705bcc6.chunk.js and 1.f5da4321.chunk.js. Hence the current SSR approach will not work. It would be much easier if we can work with the build/index.html produced by Create React App and modify it to produce the server-side render.

@KevinGrandon
Copy link

IMO if SSR is important to you, you are better using a framework geared towards SSR, as create-react-app is not. Next.js or Fusion.js would be a great option. I'm currently working with another collaborator on an implementation of MUI SSR within a single line of code for Fusion.js, using this plugin.

@oliviertassinari oliviertassinari added the new feature New feature or request label Oct 15, 2018
@oliviertassinari
Copy link
Member

@nareshbhatia The other CSS-in-JSS styling solutions have a simpler setup than what we have. I agree we have the opportunity to simplify it.

@nareshbhatia
Copy link
Contributor Author

@KevinGrandon @oliviertassinari, thanks for your inputs. @KevinGrandon, I will try out Next.js and Fusion.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants