Update: Content is updated for the latest cra-universal 3.0.0 release, read it here!.
Server-side rendering and Code-splitting with React
So firstly I’ve the following tech stacks:
Actually I’ve been reading article on how to do server-side rendering (SSR) with create-react-app without ejecting it, and it’s great.
After reading the article, I decided to fork the repo to add some customization like Webpack for production build, code-splitting, and separate client and server packages installation, so that it’s portable and reusable for other existing projects.
Well, turned out it worked well. Now you can copy
./server into your create-react-app project and it’s done! Now you have a server-side rendering server with Code-splitting support. I also made the cra-universal out of it to ease the copying stuff and build task.
For starter, you can try:
npx create-react-app my-app
npm i -D cra-universal
npx cra-universal start --both
http://localhost:3001 in your browser and your create-react-app with SSR is ready!
Now, we have SSR-ready server, but since Firebase hosting can only host static assets, you can’t really start a node server there.
I looked up on how to do SSR with Firebase, and then I found this cool repo:
So actually you can host your server with Firebase functions and it’s free! Unless you do outbound networking (Google services are free) within your function.
Firstly you need to change the rewrite on your firebase.json:
Change the “destination” key to “function”.
“app” is the export name from
Now you need to build the bundle for client and server.
Run the following command:
npx cra-universal build
This command will build both your client and server and produces
Don’t forget to remove
./build/index.html from client build, because it’ll make server-side rendering not working on root path.
crau-dist folder inside
./functions then copy
./dist contents into
Here is my function index.js:
const functions = require('firebase-functions');const app = require('./crau-dist/server/bundle');exports.app = functions.https.onRequest(app);
So you need to grab the server bundle and then pass
app (which is an express instance) into Firebase function.
Finally, you run
firebase deploy to deploy all your Firebase database, hosting, and functions.
To test it, you can use
curl https://your-domain.com and check whether your app container (<div id=”root”>) is already populated with pre-rendered markup from server.
For the complete code, you can find it here:
- Need to copy the server bundle and client index.html (needed for SSR) into the functions folder manually (for now I used npm script)
- Firebase function is still in Beta, it might not be stable and the API may change in the future
Feel free to ask or discuss. Thank you for reading!