Image for post
Image for post

Server side rendering with puppeteer and headless chrome— a practical guide

Dejan Blazeski
Sep 21, 2019 · 4 min read

TL;DR — serve JS to users, server side rendered content to bots (the source code is available here — http://bit.ly/2m6HN8w)

While building Binge, my framework of choice was VueJs (and single page application). Happy with both choices.

If you (assuming a dev) view the source code — it would only show a couple of lines of code — some meta tags and an almost empty <body> tag with a root div and a bundled js file — so when people visit it, it’s a typical website, browsers download the bundle and render the page.

When Google (and other search engines or social networks) parses it, it’s that (almost) empty <body />.

Google understands JS, just needs a couple of days to index and process it (as this google’s webmaster videos says)

The solution I used: server side rendering with puppeteer and google chrome. My goal for implementing SSR was:

The setup we will use:

Let’s use the existing github repo to speed up the setup, explaining the important bits.

#clone the repo
git clone https://github.com/dblazeski/express-chrome-ssr.git
#install the dependencies
cd express-chrome-ssr
yarn install

Our entry file is ./src/index.js Importing express for our server, puppeteer for managing our headless chrome instance and rendering the url, and booting our app using express looks like this:

That’s the minimum setup we need for the server.

Let’s add a route that will accept url parameter/ssr?url=http://google.com Once we start the server, we will pass our url’s and get the rendered html as response.

Here’s the code:

Our /ssr route handled by express and passed to the ssr function we imported above

What happens?

Let’s take a look at the ssr function that actually does the render:

Our ssr function, see the github repo for the full version

What happens?

Once the render is complete, the response is passed back to our index.js file and sent back to the server #[18–20] in ssr-2.js — that’s the html we’re after!

The content can then be printed in the browser and bots can parse it 🎉

Sending the content to the browser

This final step can vary depending on your programming language / framework. I use Laravel, so the example will be in Laravel / PHP — but I’m sure it’s easy to understand.

A package for php that’s good for user agent detection is CrawlerDetect (and it has support for all popular frameworks).

Pseudo code example:

The source code with examples you can use is available on http://bit.ly/2m6HN8w. The repo also has ready server scripts (see package.json) you can use with nodemon or pm2.

Started using SSR in attempt to serve the content bots require for rich links preview. If you’re an avid movie fan, check out my latest project Binge.

Thanks for reading.

The Startup

Medium's largest active publication, followed by +731K people. Follow to join our community.

Dejan Blazeski

Written by

Founder binge.app. Curious dev. Laravel / Angular / VueJs / React Native / Docker. Love stand up shows.

The Startup

Medium's largest active publication, followed by +731K people. Follow to join our community.

Dejan Blazeski

Written by

Founder binge.app. Curious dev. Laravel / Angular / VueJs / React Native / Docker. Love stand up shows.

The Startup

Medium's largest active publication, followed by +731K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store