Learn how to easily get started rendering apps built with Vue to a server to improve your app's performance using Nuxt.js.
As one of the contemporary widely used JavaScript frameworks/libraries, Vue.js offers an awesome user experience by dynamically rendering page content without necessarily sending a request to the server each time.
However fast rendering of contents by Vue.js might be, whenever your site starts to grow, it takes a fair amount of time before the website is finally rendered, as it contains plenty of content required to construct the page.
With Nuxt.js you can easily preload content on the web server and render HTML as the response to a browser request for a page. This will ultimately improve “time to content” when loading an application.
In this post we will examine some of the basic concepts of building applications using Nuxt.js and also build a simple static site in the process.
Server-side rendering is a clever solution to improve page rendering performance in any application, especially those powered by Vue.js. It eliminates the need to send a request to server and recreate pages that don’t contain dynamic content — for example, a contact us
page. A server can create this page once and cache it for future use.
This will obviously improve the speed of page rendering, no matter how subtle it might be.
Nuxt.js simplifies the development of Vue.js applications. One of its major focuses is the creation of universal apps — by this, I mean applications that are also rendered on the server. Nuxt.js isn’t a replacement for server-side libraries like Express; it is not a server-side framework. It just allows us to pre-render views on the fly from the server.
Another point to note is the setup of routes irrespective of the scale of your application. You can simply create a file for a page, and Nuxt.js will automatically set up the route for you to navigate and view the newly created file out of the box. We will see this later in the tutorial.
Nuxt.js builds upon Vue, and you can still write and structure your applications the same way you would while building a typical Vue.js application.
A basic knowledge of JavaScript and Vue is required for this tutorial. Also ensure that you have Node.js, NPM and Vue CLI installed on your computer.
If you haven’t downloaded Vue’s CLI already, do so with this command to have it installed globally on your machine:
```bash
$ npm install -g vue-cli
```
Next, to get started with creating a Nuxt.js app, run the following command to use the CLI to scaffold a new project named fictional-store
from your terminal:
```bash
$ vue init nuxt/starter fictional-store
```
Change directory into the newly created project and install all its dependencies:
```bash
// change directory
cd fictional-store
// install dependencies
npm install
```
Launch the project with:
```bash
npm run dev
```
If you get this compiled error displayed in the console:
You can fix it by opening ./nuxt.config.js
and replace the build{}
object with:
```javaScript
// ./nuxt.config.js
module.exports = {
...
build: {
/*
** Run ESLint on save
*/
extend(config, { isDev }) {
if (isDev && process.client) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
}
}
}
```
Stop the server by pressing CTRL
+ c
and restart the server again:
```bash
npm run dev
```
This is going to be an introduction to using Nuxt.js. Before we proceed, let’s take a quick look at the folder structure of the static application that we want to build. We will basically create a few pages and navigate through them. Doing so, you will have an idea of how routing simply works without the need to configure this manually.
Our application will have the following pages:
Homepage
About page
Product page
Contact page
We will set up a reusable Navigation
component for this project, but before that, let’s pull in Bootstrap to help with some default page layout.
Open ./nuxt.config.js
and include the CDN link for Bootstrap within the link
object:
```javaScript
// ./nuxt.config.js
module.exports = {
head: {
...
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css' } // include this line
]
},
...
}
```
You will need to restart the server for Bootstrap to be successfully installed for this project. To do this, hit CTRL
+ C
from the terminal to stop the server if it currently running and restart with npm run dev
.
Next, locate the components
folder and create a new file named Navigation.vue
. Paste the code below in it:
```
// ./components/Navigation.vue
<
template
>
<
nav
class
=
"navbar navbar-expand-lg navbar-light bg-light"
>
<
a
class
=
"navbar-brand"
href
=
"#"
>Navbar</
a
>
<
div
class
=
"collapse navbar-collapse pull-right"
id
=
"navbarNavAltMarkup"
>
<
div
class
=
"navbar-nav"
>
<
nuxt-link
class
=
"nav-item nav-link active"
to
=
"/"
>Home</
nuxt-link
>
<
nuxt-link
class
=
"nav-item nav-link"
to
=
"/about"
>What we do</
nuxt-link
>
<
nuxt-link
class
=
"nav-item nav-link"
to
=
"/product"
>Products</
nuxt-link
>
<
nuxt-link
class
=
"nav-item nav-link"
to
=
"/contact"
>Contact</
nuxt-link
>
</
div
>
</
div
>
</
nav
>
</
template
>
```
Here, we created a navigation bar and set up links to the pages that we will create soon.
Now, open the default.vue
within the layouts
folder and replace the contents with:
```
// ./layouts/default.vue
<
template
>
<
div
>
<
navbar
></
navbar
>
<
nuxt
/>
</
div
>
</
template
>
<
script
>
import Navbar from "../components/Navigation";
export default {
components: {
Navbar
}
};
</
script
>
```
We have only imported the Navigation
component and included it just above <nuxt />
. This will help us create a master layout.
Once you set up a new project with Nuxt.js, a new file will automatically be generated and will set up a view for the homepage. This is what we were able to view from the browser earlier.
Update the index page by replacing the content found in ./pages/index.vue
with:
```
// ./pages/index.vue
<
template
>
<
section
>
<
div
class
=
"container h-100"
>
<
div
class
=
"row h-100 justify-content-center align-items-center"
>
<
div
>
<
p
>Fictional e-commerce store </
p
>
<
p
><
em
>Home of bespoke and modern wears</
em
></
p
>
</
div
>
</
div
>
</
div
>
</
section
>
</
template
>
<
script
>
import AppLogo from "~/components/AppLogo.vue";
export default {
components: {
AppLogo
}
};
</
script
>
<
style
>
.container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</
style
>
```
If you visit the homepage at http://localhost:3000/ now you should see this page:
Create a another file named about.vue
within the pages
folder and paste the content below in it:
```
// ./pages/about.vue
<
template
>
<
section
>
<
div
class
=
"container h-100"
>
<
div
class
=
"row h-100 justify-content-center align-items-center"
>
<
div
>
<
p
>
More Clothing & Accessories discounts - Don't miss a single chance to save.
</
p
>
</
div
>
</
div
>
</
div
>
</
section
>
</
template
>
```
Next, create a product page within the pages
folder and name it product.vue
. Open the newly created file and paste in the following content:
```
// ./pages/product.vue
<
template
>
<
div
>
<
div
class
=
"container"
>
<
div
class
=
"row"
>
<
div
class
=
"col-md-3"
>
<
div
class
=
"card"
>
<
img
class
=
"card-img-top"
src
=
"https://res.cloudinary.com/yemiwebby-com-ng/image/upload/v1537950595/symfony-listing/z1rtappih3vwlsjk1ada.jpg"
alt
=
"Card image cap"
>
<
div
class
=
"card-body"
>
<
h5
class
=
"card-title"
>Card title</
h5
>
<
p
class
=
"card-text"
>This card has supporting text below as a natural lead-in to additional content.</
p
>
<
p
class
=
"card-text"
><
small
class
=
"text-muted"
>Last updated 3 mins ago</
small
></
p
>
</
div
>
</
div
>
</
div
>
<
div
class
=
"col-md-3"
>
<
div
class
=
"card"
>
<
img
class
=
"card-img-top"
src
=
"https://res.cloudinary.com/yemiwebby-com-ng/image/upload/v1537950461/symfony-listing/w92p99ntmbawcgjjubfh.jpg"
alt
=
"Card image cap"
>
<
div
class
=
"card-body"
>
<
h5
class
=
"card-title"
>Card title</
h5
>
<
p
class
=
"card-text"
>This card has supporting text below as a natural lead-in to additional content.</
p
>
<
p
class
=
"card-text"
><
small
class
=
"text-muted"
>Last updated 3 mins ago</
small
></
p
>
</
div
>
</
div
>
</
div
>
<
div
class
=
"col-md-3"
>
<
div
class
=
"card"
>
<
img
class
=
"card-img-top"
src
=
"https://res.cloudinary.com/yemiwebby-com-ng/image/upload/v1537950595/symfony-listing/z1rtappih3vwlsjk1ada.jpg"
alt
=
"Card image cap"
>
<
div
class
=
"card-body"
>
<
h5
class
=
"card-title"
>Card title</
h5
>
<
p
class
=
"card-text"
>This card has supporting text below as a natural lead-in to additional content.</
p
>
<
p
class
=
"card-text"
><
small
class
=
"text-muted"
>Last updated 3 mins ago</
small
></
p
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
template
>
```
You can find product page here http://localhost:3000/product
If you right-click and view the page source of this application now, you will see the exact content as depicted by the image below:
This is one of the main advantages of server-side rendering brought to Vue.js application by Nuxt.js, as well as the reason it is termed as a library for building “universal Vue.js applications.” Obviously, this is an indication that our app is rendered both on the client and the server. This is really important, as it makes it easy for search engines to index our site.
Create the contact us page as contact.vue
within the pages
folder as well and add the content below:
```
// ./pages/contact.vue
<
template
>
<
section
>
<
div
class
=
"container h-100"
>
<
div
class
=
"row h-100 justify-content-center align-items-center"
>
<
div
>
<
p
>
Feel free to check out our website.
www.fictionalstore.sample
</
p
>
</
div
>
</
div
>
</
div
>
</
section
>
</
template
>
```
With Nuxt.js you can easily generate static site using a single command.
```bash
npm run generate
```
Using the command above, Nuxt.js will generate the HTML for every one of the routes and pages created and save them in a file.
Moving forward, you can easily deploy your website to the live server by simply uploading the newly generated dist
folder.
Run the application in case you haven’t done so with:
```bash
npm run dev
```
See it working on http://localhost:3000/
Effective and fast page rendering without much delay is crucial to the success of any web application. As seen in this tutorial, you can greatly simplify the development and improve the performance of Vue.js applications by using Nuxt.js for server-side rendering.
To see Nuxt.js in action, we built a simple store and later compiled it into a dist
folder.
I hope you found this tutorial helpful. Find the complete source code on GitHub.
Chris Nwamba is a Senior Developer Advocate at AWS focusing on AWS Amplify. He is also a teacher with years of experience building products and communities.