Ogundipe Samuel software engineer and technical writer

Server-side rendering in Vue.js

3 min read 1073

Introduction

Vue.js is one of the simplest JavaScript frameworks to use, in fact, I call it the lightweight champion. Once you are familiar with the basics of JavaScript, it’s easy to pick up Vue.js and start building rich web apps.

But one of the downsides of using any JavaScript framework is that the page isn’t viewable until the browser has executed the app’s JavaScript bundle.

For example, if you take a look at the code below which is served when you load a Vue.js app, you notice that the element is all you see. The content isn’t filled in until the Vue.js JavaScript code runs.

<html>
  <head> … </head>
  <body>
    <div id=app></div> 
  </body>
  <script src=”dist/build.js”></script>
</html>

This means that the user has to wait longer to see anything. It can also impact SEO if crawlers can’t see the content of the page quickly.

To fix these issues, we can do server-side rendering (SSR), which is where the server runs the Vue.js code before serving the request, so that the HTML is filled in on the page as soon as it reaches the client.

In this tutorial, I’ll show you how to get up and running with SSR in your Vue.js app.

Getting started with server-side rendering

We’ll start with vue-cli’s webpack-simple template to give us a Vue template scaffolding to work with.

If you don’t have the vue-cli installed, you can do so by running the following commands:

npm install -g vue-cli

Once we have installed vue-cli we create a new project by running the following commands:

#Create the project 
vue init webpack-simple ssr-vue 
cd ssr-vue  
# Install dependencies
npm install

We’ll also need three other packages required for Server-Side Rendering, which are:

We made a custom demo for .
No really. Click here to check it out.

  • Express: For the server
  • vue-server-renderer: To render the bundle
  • webpack-merge:We will use it to merge two web-pack bundles together

We can install them by running:

npm i express vue-server-renderer webpack-merge

Now we are set and ready to configure our Vue app for SSR

Next, we need to create a file called server.js in the src folder and paste the following contents into it:

JSFiddle

Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

In the code block above, we notice that the code is very similar to the code in src/main.js . The only difference is that here, we add the context, and then return a promise.

This is because this is the script we want webpack to prepare for the server to run and return the pre-render call.

Creating the webpack server config

Next, we need to configure webpack to prepare and compile our Vue application so it can be executed by the server. In the last step, we had created the server.js file. In this step, we will configure webpack to compile the file and its dependencies, whilst returning an executable bundle.

Let us create a new file in our root folder called webpack.server.config.js and add:

JSFiddle

Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

Here we have defined the entry path to our code and also defined where the output of the file should be stored.

Next, we also asked webpack to compress and uglify the resulting bundle.

Updating our npm scripts

We have created the webpack config that creates the executable server bundle. However, we need to specify a command that enables npm run this webpack config.

To do this, let us replace the scripts section of our package.json to this:

"scripts": {
        "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
        "build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
        "build-server": "cross-env NODE_ENV=production webpack --config webpack.server.config.js --progress --hide-modules"
    },

In the code above, we will notice the addition of one extra command called build-server . This command will build up our executable server bundle by invoking webpack with the webpack.server.config.js file.

Now let’s build our normal bundle and our server bundle by running:

//build client/browser javascript bundle
npm run build
//build executable server bundle 
npm run build-server

Creating the server entry point

For the server, we will use Node js . This explains why we have installed Express earlier on.

Let us create a file called entry.js in the root folder and copy the following content:

JSFiddle

Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

In the code above, we have:

  • Required the Express library which will be the application framework
  • Required the fs library, which we will use to read files synchronously
  • Required the path library, which will come helpful while dealing with file paths.
  • Set the bundle variable to the streamed content of our server.js file (the executable server bundle) using the fs library
  • Set the rendered variable to the parsed and rendered value of our server bundle using.
  • Streamed the content of our index.html file, to a variable called index .
  • Instantiated the Express instance to a variable called app .
  • Used the /dist route as a static file route, and set it to serve form the dist folder
  • In the wildcard route, we have called the renderer.renderToString function, which will execute the javascript to a string, and return the resulting output.
  • We have now replaced the occurrence of with the resulting output.

Now, if we launch our application, and we visit the corresponding URL, it looks like nothing has changed.

However, if we take a look at our page source, we will find out that our generated HTML is:

JSFiddle

Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

We notice here that the element <div id=app> now has all it’s innerHTML populated with the full elements it needed. This is much better for SEO and web crawlers to parse. Also, it eliminates waiting time after the page has already loaded.

Conclusion

In this post, we have seen how to set up Server Side Rendering in Vue.js apps, and why it is useful. If you’d like to read the full code samples shown above, you can check out this GitHub repo with the whole project.

samuelayo/vue-ssr

You can’t perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session. We use optional third-party analytics cookies to understand how you use GitHub.com so we can build better products.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Experience your Vue apps exactly how a user does

    Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

    LogRocket is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

    The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

    Modernize how you debug your Vue apps - .

    Ogundipe Samuel software engineer and technical writer

    Leave a Reply