Server-Side Rendering with Vue.js
Introduction
In this tutorial, we will focus on Server-Side Rendering (SSR) with Vue.js. SSR is a popular technique for rendering a client-side single page application (SPA) on the server and then sending a fully rendered page to the client. This method improves SEO and initial load time by displaying a static snapshot of your app to users until the client-side app is fully loaded. Let's dive in!
Why Server-Side Rendering?
Before diving into the how-tos, let's understand why we need SSR. The main reasons are:
- Better SEO: As some search engines may not be able to see the fully rendered asynchronous content, SSR sends a fully rendered page to the client, making it more friendly to search engine crawler.
- Faster time-to-content: Without SSR, users will see a blank page until the JavaScript is downloaded, parsed and executed. With SSR, they will see a fully rendered page much sooner.
Prerequisites
Before we begin, you need to have a basic understanding of Vue.js and Node.js. You should also have Node.js, npm, and Vue CLI installed on your computer.
Getting Started
Setting Up the Project
Let's start by creating a new Vue project. Open your terminal and run the following command:
vue create ssr-project
When prompted, choose the default preset (babel, eslint).
Navigate into the project directory:
cd ssr-project
Install Vue Server Renderer
To render our Vue app on the server, we need to install the vue-server-renderer
package. Install it by running:
npm install vue-server-renderer --save
Create an Entry File for the Server
Next, create a new file in the src folder named entry-server.js
. This will be the entry point for our server-side bundle. In this file, we need to export a function that creates a new instance of our Vue app.
import { createApp } from './main'
export default context => {
return new Promise((resolve, reject) => {
const { app, router } = createApp()
router.push(context.url)
router.onReady(() => {
resolve(app)
}, reject)
})
}
Create an Entry File for the Client
Next, create entry-client.js
in the src folder. This will be the entry point for our client-side bundle.
import { createApp } from './main'
const { app, router } = createApp()
router.onReady(() => {
app.$mount('#app')
})
Update Your Webpack Configuration
Vue SSR requires a bit of setup in the webpack configuration. This is because the server-side bundle needs to be created with Node.js in mind, while the client-side bundle is for the browser.
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const nodeExternals = require('webpack-node-externals')
const baseConfig = require('./webpack.base.config.js')
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
module.exports = merge(baseConfig, {
target: 'node',
entry: './src/entry-server.js',
output: {
filename: 'server-bundle.js',
libraryTarget: 'commonjs2'
},
externals: nodeExternals({
whitelist: /\.css$/
}),
plugins: [
new webpack.DefinePlugin({
'process.env.VUE_ENV': '"server"'
}),
new VueSSRServerPlugin()
]
})
Rendering the Application
Finally, let's create a Node.js server to render our Vue app. Create a new file named server.js
in the root of your project and add the following code:
const express = require('express')
const server = express()
const { createBundleRenderer } = require('vue-server-renderer')
const template = require('fs').readFileSync('./index.template.html', 'utf-8')
const serverBundle = require('./dist/vue-ssr-server-bundle.json')
const clientManifest = require('./dist/vue-ssr-client-manifest.json')
const renderer = createBundleRenderer(serverBundle, {
runInNewContext: false,
template,
clientManifest
})
server.get('*', (req, res) => {
const context = { url: req.url }
renderer.renderToString(context, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
server.listen(8080)
Run your server with the command:
node server
You can now access your application on http://localhost:8080
. Your Vue.js application is now server-rendered!
Conclusion
This was a basic introduction to Server-Side Rendering with Vue.js. There are more advanced topics to explore like code-splitting, using Vuex with SSR, and handling redirects and 404s. But for now, you have a good starting point to begin experimenting with SSR in your Vue.js applications.