Build a Server-Side Rendered Vue App with Nuxt.js

Build a Server-Side Rendered Vue App with Nuxt.js

In this tutorial, I will be showing how to build a static website with Nuxt.js. For the purpose of demonstration, we’ll be building a personal portfolio website.

In this tutorial, I will be showing how to build a static website with Nuxt.js. For the purpose of demonstration, we’ll be building a personal portfolio website.

Usage of static websites are increasing in popularity recently. It’s not a surprise as static site generators seem to have been gaining more popular recently too. There are various static site generators which you can use to build websites. Some of these generators include Jekyll, Hugo, Gatsby, Nuxt.js to mention but a few. Gatsby and Nuxt.js are pretty new to the collection.

Table of Contents

  • What is a Static Site
  • Why Static Site
  • What is Nuxt.js
  • How it Works
  • Create a Nuxt.js Project
  • Creating Master Layout
  • Creating Navbar Component
  • Creating The Homepage
  • Creating The About Page
  • Creating The Projects Page
  • Creating The Contact Page
  • Generating Static Site
  • Deploying Our Static Site]
  • Conclusion
What is a Static Site

A static site is the simplest kind of website you can build. Static sites are written in HTML, CSS and sometimes little JavaScript. A static site contains little or no user interactions. They are stored in the filesystem of a server and are delivered to the user exactly as stored. The same information is displayed for all users. Static sites are suitable for the contents that never or rarely need to be updated, though modern static site generators are changing this.

Why Static Site

You might ask yourself why static site? Well, there are lot of benefits with using static site. These benefits includes and are not limited to the following:

Speed: This is the most obvious benefit of a static site as it is just HTML, CSS and JS files and some assets. There is no back and forth between the client and a server, hence it speed. Static sites can be served from a CDN.

Less Resources: Static sites uses less resources as things like servers and databases are not necessarily needed.

Security: You don’t have to worry of your servers been hacked or database vulnerabilities.

In addition to the above, there are various platforms that can help you with hosting your static site. These platforms includes: GitHub Pages, Netlify, Surge etc.

What is Nuxt.js

Nuxt.js is a framework for creating server-rendered Vue.js Applications. It was inspired by Next.js. Its main scope is UI rendering while abstracting away the client/server distribution. Nuxt.js comes with a lot of features to help you in your development between the client side and the server side such as asynchronous data, middleware, layouts, etc.

In addition to building server rendered applications, Nuxt.js can also be used to build static generated Vue.js applications (which will be our focus in this tutorial).

How it Works

In addition to using Vue.js, Nuxt.js uses the following libraries to create a rich web application development:

  • What is a Static Site
  • Why Static Site
  • What is Nuxt.js
  • How it Works
  • Create a Nuxt.js Project
  • Creating Master Layout
  • Creating Navbar Component
  • Creating The Homepage
  • Creating The About Page
  • Creating The Projects Page
  • Creating The Contact Page
  • Generating Static Site
  • Deploying Our Static Site]
  • Conclusion

All configured for you, so you don’t have to spend time installing and setting up these libraries yourself. Under the hood it uses Webpack with vue-loader and babel-loader to bundle, code-split and minify your code.

Nuxt.js tries to remain minimal as possible by keeping a total size of only 28kb min+gzip (31kb with vuex).

The image below shows a broad overview of how Nuxt.js works:

Let’s now build ourselves a static portfolio website with Nuxt.js.

Create a Nuxt.js Project

We’ll be using the starter template provided by the Nuxt.js team. We’ll install it using the Vue CLI, so you need to first install the Vue CLI in case you don’t have it installed already:

npm install -g vue-cli

Once installed, you can move on to creating Nuxt.js project with it:

vue init nuxt/starter portfolio

We can the project portfolio, you can name it whatever you like. Next, we need to install the dependencies:

cd portfolio
npm install

With the dependencies installed, we can now lauch our project:

npm run dev

The application is now running on http://localhost:3000. If everything went well, you should see a screen as the image below:

Before we dive in to code, let’s take a moment to define what our portfolio website will entail. The portfolio website will contain four (4) pages:

  • What is a Static Site
  • Why Static Site
  • What is Nuxt.js
  • How it Works
  • Create a Nuxt.js Project
  • Creating Master Layout
  • Creating Navbar Component
  • Creating The Homepage
  • Creating The About Page
  • Creating The Projects Page
  • Creating The Contact Page
  • Generating Static Site
  • Deploying Our Static Site]
  • Conclusion
Creating Master Layout

We’ll start by creating a master layout which all our pages will inherit. We’ll be using Bulma as our CSS framework. So we need to pull it into our project. To do so, open nuxt.config.js which is Nuxt.js config file and paste the code below within the link object that is inside the head object:

// nuxt.config.js

{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.0/css/bulma.min.css' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700' },

In addition to pulling in Bulma, we also pull in a Google font.

Within the layouts folder, there is a default.vue file. Open it and replace it content with:

<!-- layouts/default.vue -->

<template>
  <div>
    <nuxt/>
  </div>
</template>

<style>
  html {
    font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
  }
</style>

<nuxt/> will be replaced with the actual content of the page rendered.

Creating Navbar Component

Let’s create a navbar component, so we can add it to the master layout. Within the components folder, create a new Navbar.vue file and paste the code below into it:

<!-- components/Navbar.vue -->

<template>
  <div class="container">
    <nav class="navbar" role="navigation" aria-label="main navigation">
      <div class="navbar-brand">
        <a class="navbar-item" href="/">Portfolio</a>
        <button class="button navbar-burger">
          <span></span>
          <span></span>
          <span></span>
        </button>
      </div>
      <div class="navbar-menu">
        <div class="navbar-end">
          <nuxt-link class="navbar-item" to="/">Home</nuxt-link>
          <nuxt-link class="navbar-item" to="/about">About</nuxt-link>
          <nuxt-link class="navbar-item" to="/projects">Projects</nuxt-link>
          <nuxt-link class="navbar-item" to="/contact">Contact</nuxt-link>
        </div>
      </div>
    </nav>
  </div>
</template>

We can now add the navbar to the master layout. Open layouts/default.vue and update as below:

<!-- layouts/default.vue -->

<template>
  <div>
    <navbar></navbar>
    <nuxt/>
  </div>
</template>

<script>
  import Navbar from '../components/Navbar'

  export default {
    components: {
      Navbar
    }
  }
</script>

<style>
  html {
    font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
  }
</style>

Creating The Homepage

Within the pages folder, you will see an index.vue file. This file is what rendered when we navigate to the home route of our application. What Nuxt.js does is, generate routes based on the files in the pages folder. For instance, if we have index.vue, about.vue and contact.vue files within the pages folder, Nuxt.js will form the routes for the application as /, /about and /contact respectively.

Having said that, open pages/index.vue it and replace it content with the code below:

<!-- pages/index.vue -->

<template>
  <section class="section is-large">
    <div class="container has-text-centered">
      <h1 class="title">Hi, I'm Chimezie Enyinnaya</h1>
      <h2 class="subtitle">a Software Developer based in Lagos, Nigeria.</h2>
    </div>
  </section>
</template>

If we visit the home route again, we should see the new homepage in action:

Creating The About Page

Let’s now create the about page. Within the pages folder, create a new about.vue file and paste the code below into it:

<!-- pages/about.vue -->

<template>
  <section class="section is-medium">
    <div class="container has-text-centered">
      <h1 class="title">About Me</h1>
      <p>
        My name is Chimezie Enyinnaya (AKA mezie), I’m a self taught software developer based in Lagos, Nigeria. I build modern applications for the web! I'm a technical writer, I write technical articles and tutorials for various platforms including <a href="https://scotch.io/@mezie">Scotch.io</a>.
      </p>
    </div>
  </section>
</template>

Navigate to http://localhost:3000/about to see the about page in action:

Creating The Projects Page

In the same vein, let’s create the projects page. Within the pages folder, create a new projects.vue file and paste the code below into it:

<!-- pages/projects.vue -->

<template>
  <section class="section is-medium">
    <div class="container has-text-centered">
      <h1 class="title">My Projects</h1>
      <p>
        Some of my projects can be found on <a href="https://github.com/ammezie" target="_blank">GitHub</a>.
      </p>
    </div>
  </section>
</template>

Navigate to http://localhost:3000/projects to see the projects page in action:

Creating The Contact Page

Finally, we create the contact page. Within the pages folder, create a new contact.vue file and paste the code below into it:

<!-- pages/contact.vue -->

<template>
  <section class="section is-medium">
    <div class="container has-text-centered">
      <h1 class="title">Contact Me</h1>
      <p>
        You can follow me on Twitter: <a href="https://twitter.com/ammezie" target="_blank">@ammezie</a>
      </p>
    </div>
  </section>
</template>

Navigate to http://localhost:3000/contact to see the contact page in action:

We now have a functional portfolio website.

Generating Static Site

Now, we are going to generate a static site for the portfolio website which so far contains bunch of Vue files. To do this, we’ll make use of the nuxt generate command:

npm run generate

The command above will run nuxt generate which will in turn start building the application and generate the static files. Once the it done, you should now have a dist folder which contains the generated static files.

The nuxt generate command works by generating HTML files off the Vue files files within the pages folder for all the application’s routes.

Deploying Our Static Site

The final thing we’ll do is deploy the static site to a live server. For this we’ll be using Netlify, though you can use GitHub Pages or any other static site hosting. So head over to Netlify and sign up if you don’t have an account with them yet.

Once logged in, click the New site from Git button:

Then select your Git provider, I’ll be using GitHub. You will be directed to authorize with GitHub (in my case):

Once authorized, you will be redirected back and you will see a list of your GitHub projects which you can choose the one you want to deploy from:

Next, we need to specify a build command and a publish directory. For the build command we enter npm run generate which is the same command we used to build our files locally. Then we enter dist as the publish directory. Again, this is the same directory the generated files will be be.

Finally, click the Deploy site button to start the deployment.

Once the deployment is complete, Netlify will generate a random name with a URL for your application with which you can access the application. Mine is https://programmer-badger-66651.netlify.com

Conclusion

So in this tutorial, we looked at an overview of Nuxt.js. We also looked at why we might want to create static sites. Finally, we built a static website with Nuxt.js. As pointed out, Nuxt.js does more than just static site generation. You might want to go take a look at the docs to explore it more.

Thanks for reading ❤

If you liked this post, share it with all of your programming buddies!

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.

Nuxt.js: a Minimalist Framework for Creating Universal Vue.js Apps

Nuxt.js: a Minimalist Framework for Creating Universal Vue.js Apps

In this article, you'll learn how we can take advantage of Nuxt.js to build server-rendered JavaScript applications with Vue.js. Learn how to use its generate command to generate static files for our pages, and deploy them quickly via a service like Firebase Hosting.

In this article, you'll learn how we can take advantage of Nuxt.js to build server-rendered JavaScript applications with Vue.js. Learn how to use its generate command to generate static files for our pages, and deploy them quickly via a service like Firebase Hosting.

Universal (or Isomorphic) JavaScript is a term that has become very common in the JavaScript community. It’s used to describe JavaScript code that can execute both on the client and the server.

Many modern JavaScript frameworks, like Vue.js, are aimed at building single-page applications (SPAs). This is done to improve the user experience and make the app seem faster, since users can see updates to pages instantaneously. While this has a lot of advantages, it also has a couple of disadvantages, such as long “time to content” when initially loading the app as the browser retrieves the JavaScript bundle, and some search engine web crawlers or social network robots won’t see the entire loaded app when they crawl your web pages.

Server-side rendering of JavaScript is about preloading JavaScript applications on a web server and sending rendered HTML as the response to a browser request for a page.

Building server-side rendered JavaScript apps can be a bit tedious, as a lot of configuration needs to be done before you even start coding. This is the problem Nuxt.js aims to solve for Vue.js applications.

What Nuxt.js Is

Simply put, Nuxt.js is a framework that helps you build server-rendered Vue.js applications easily. It abstracts most of the complex configuration involved in managing things like asynchronous data, middleware, and routing. It’s similar to Angular Universal for Angular, and Next.js for React.

According to the Nuxt.js docs, “its main scope is UI rendering while abstracting away the client/server distribution.”

Static Generation

Another great feature of Nuxt.js is its ability to generate static websites with the generate command. It’s pretty cool, and provides features similar to popular static generation tools like Jekyll.

Under the Hood of Nuxt.js

In addition to Vue.js 2.0, Nuxt.js includes the following: Vue-Router, Vuex (only included when using the store option), Vue Server Renderer and vue-meta. This is great, as it takes away the burden of manually including and configuring different libraries needed for developing a server-rendered Vue.js application. Nuxt.js does all this out of the box, while still maintaining a total size of 57kB min+gzip (60KB with vuex).

Nuxt.js also uses webpack with vue-loader and babel-loader to bundle, code-split and minify code.

How it works

This is what happens when a user visits a Nuxt.js app or navigates to one of its pages via <nuxt-link>:

  1. When the user initially visits the app, if the [nuxtServerInit](https://nuxtjs.org/guide/vuex-store/#the-nuxtserverinit-action "nuxtServerInit") action is defined in the store, Nuxt.js will call it and update the store.
  2. Next, it executes any existing middleware for the page being visited. Nuxt checks the nuxt.config.js file first for global middleware, then checks the matching layout file (for the requested page), and finally checks the page and its children for middleware. Middleware are prioritized in that order.
  3. If the route being visited is a dynamic route, and a validate() method exists for it, the route is validated.
  4. Then, Nuxt.js calls the asyncData() and fetch() methods to load data before rendering the page. The [asyncData()](https://nuxtjs.org/guide/async-data/ "asyncData()") method is used for fetching data and rendering it on the server-side, while the [fetch()](https://nuxtjs.org/api/pages-fetch/ "fetch()") method is used to fill the store before rendering the page.
  5. At the final step, the page (containing all the proper data) is rendered.

These actions are portrayed properly in this schema, gotten from the Nuxt docs:

Creating A Serverless Static Site With Nuxt.js

Let’s get our hands dirty with some code and create a simple static generated blog with Nuxt.js. We’ll assume our posts are fetched from an API and will mock the response with a static JSON file.

To follow along properly, a working knowledge of Vue.js is needed. You can check out Jack Franklin’s great getting started guide for Vue.js 2.0 if you’re new to the framework. I’ll also be using ES6 Syntax, and you can get a refresher on that here: sitepoint.com/tag/es6/.

Our final app will look like this:

The entire code for this article can be seen here on GitHub, and you can check out the demo here.

Application Setup and Configuration

The easiest way to get started with Nuxt.js is to use the template created by the Nuxt team. We can install it to our project (ssr-blog) quickly using the vue-cli:

vue init nuxt/starter ssr-blog


Once you’ve run this command, a prompt will open and ask you a couple of questions. You can press Return to accept the default answers, or enter values of your own.

Note: If you don’t have vue-cli installed, you have to run *npm install -g @vue/cli* first, to install it.

Next, we install the project’s dependencies:

cd ssr-blog
npm install


Now we can launch the app:

npm run dev


If all goes well, you should be able to visit http://localhost:3000 to see the Nuxt.js template starter page. You can even view the page’s source, to see that all content generated on the page was rendered on the server and sent as HTML to the browser.

Next, we can make some simple configurations in the nuxt.config.js file. We’ll add a few options:

// ./nuxt.config.js

module.exports = {
  /*
   * Headers of the page
   */
  head: {
    titleTemplate: '%s | Awesome JS SSR Blog',
    // ...
    link: [
      // ...
      {
        rel: 'stylesheet',
        href: 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css'
      }
    ]
  },
  // ...
}


In the above config file, we simply specify the title template to be used for the application via the titleTemplate option. Setting the title option in the individual pages or layouts will inject the title value into the %s placeholder in titleTemplate before being rendered.

We also pulled in my current CSS framework of choice, Bulma, to take advantage of some preset styling. This was done via the link option.

Note: Nuxt.js uses vue-meta to update the headers and HTML attributes of our apps. So you can take a look at it for a better understanding of how the headers are being set.

Now we can take the next couple of steps by adding our blog’s pages and functionalities.

Working with Page Layouts

First, we’ll define a custom base layout for all our pages. We can extend the main Nuxt.js layout by updating the layouts/default.vue file:

<!-- ./layouts/default.vue -->

<template>
  <div>
    <!-- navigation -->
    <nav class="navbar has-shadow" role="navigation" aria-label="main navigation">
      <div class="container">
        <div class="navbar-start">
          <nuxt-link to="/" class="navbar-item">
            Awesome JS SSR Blog!
          </nuxt-link>
          <nuxt-link active-class="is-active" to="/" class="navbar-item is-tab" exact>Home</nuxt-link>
          <nuxt-link active-class="is-active" to="/about" class="navbar-item is-tab" exact>About</nuxt-link>
        </div>
      </div>
    </nav>
    <!-- /navigation -->

    <!-- displays the page component -->
    <nuxt/>

  </div>
</template>

<style>
  .main-content {
    margin: 30px 0;
  }
</style>


In our custom base layout, we add the site’s navigation header. We use the <nuxt-link> component to generate links to the routes we want to have on our blog. You can check out the docs on [<nuxt-link>](https://nuxtjs.org/api/components-nuxt-link "<nuxt-link>") to see how it works.

The <nuxt> component is really important when creating a layout, as it displays the page component.

It’s also possible to do a couple of more things — like define custom document templates and error layouts — but we don’t need those for our simple blog. I urge you to check out the Nuxt.js documentation on views to see all the possibilities.

Simple Pages and Routes

Pages in Nuxt.js are created as single file components in the pages directory. Nuxt.js automatically transforms every .vue file in this directory into an application route.

Building the Blog Homepage

We can add our blog homepage by updating the index.vue file generated by the Nuxt.js template in the pages directory:

<!-- ./pages/index.vue -->
<template>
  <div>
    <section class="hero is-medium is-primary is-bold">
      <div class="hero-body">
        <div class="container">
          <h1 class="title">
            Welcome to the JavaScript SSR Blog.
          </h1>
          <h2 class="subtitle">
            Hope you find something you like.
          </h2>
        </div>
      </div>
    </section>
  </div>
</template>

<script>
  export default {
    head: {
      title: 'Home'
    }
  }
</script>

<!-- Remove the CSS styles -->


As stated earlier, specifying the title option here automatically injects its value into the titleTemplate value before rendering the page.

We can now reload our app to see the changes to the homepage.

Building the About page

Another great thing about Nuxt.js is that it will listen to file changes inside the pages directory, so there’s no need to restart the application when adding new pages.

We can test this, by adding a simple about.vue page:

<!-- ./pages/about.vue -->
<template>
  <div class="main-content">
    <div class="container">
      <h2 class="title is-2">About this website.</h2>
      <p>Curabitur accumsan turpis pharetra <strong>augue tincidunt</strong> blandit. Quisque condimentum maximus mi, sit amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl.</p>
      <br>
      <h4 class="title is-4">What we hope to achieve:</h4>
      <ul>
        <li>In fermentum leo eu lectus mollis, quis dictum mi aliquet.</li>
        <li>Morbi eu nulla lobortis, lobortis est in, fringilla felis.</li>
        <li>Aliquam nec felis in sapien venenatis viverra fermentum nec lectus.</li>
        <li>Ut non enim metus.</li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  head: {
    title: 'About'
  }
}
</script>


Now, we can visit http://localhost:3000/about to see the about page, without having to restart the app, which is awesome.

Showing Blog Posts on the Homepage

Our current homepage is pretty bare as it is, so we can make it better by showing the recent blog posts from the blog. We’ll do this by creating a <posts> component and displaying it in the index.vue page.

But first, we have to get our saved JSON blog posts and place them in a file in the app root folder. The file can be downloaded from here, or you can just copy the JSON below and save in the root folder as posts.json:

[
    {
        "id": 4,
        "title": "Building universal JS apps with Nuxt.js",
        "summary": "Get introduced to Nuxt.js, and build great SSR Apps with Vue.js.",
        "content": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
        "author": "Jane Doe",
        "published": "08:00 - 07/06/2017"
    },
    {
        "id": 3,
        "title": "Great SSR Use cases",
        "summary": "See simple and rich server-rendered JavaScript apps.",
        "content": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
        "author": "Jane Doe",
        "published": "17:00 - 06/06/2017"
    },
    {
        "id": 2,
        "title": "SSR in Vue.js",
        "summary": "Learn about SSR in Vue.js, and where Nuxt.js can make it all faster.",
        "content": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
        "author": "Jane Doe",
        "published": "13:00 - 06/06/2017"
    },
    {
        "id": 1,
        "title": "Introduction to SSR",
        "summary": "Learn about SSR in JavaScript and how it can be super cool.",
        "content": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
        "author": "John Doe",
        "published": "11:00 - 06/06/2017"
    }
]


Note: Ideally the posts should be retrieved from an API or resource. For example, Contentful is a service that can be used for this.

Components live in the components directory. We’ll create the <posts> single file component in there:

<!-- ./components/Posts.vue -->
<template>
  <section class="main-content">
    <div class="container">
      <h1 class="title has-text-centered">
        Recent Posts.
      </h1>
      <div class="columns is-multiline">
        <div class="column is-half" v-for="post in posts" :key="post.id">
          <div class="card">
           <header class="card-header">
            <p class="card-header-title">
              {{ post.title }}
            </p>
          </header>
          <div class="card-content">
            <div class="content">
              {{ post.summary }}
              <br>
              <small>
                by <strong>{{ post.author}}</strong>
                \\ {{ post.published }}
              </small>
            </div>
          </div>
          <footer class="card-footer">
            <nuxt-link :to="`/post/${post.id}`"
              class="card-footer-item">
              Read More
            </nuxt-link>
          </footer>
        </div>
      </div>
    </div>
  </div>
</section>
</template>

<script>
  import posts from '~/posts.json'

  export default {
    name: 'posts',
    data () {
      return { posts }
    }
  }
</script>


We import the posts data from the saved JSON file and assign it to the posts value in our component. We then loop through all the posts in the component template with the v-for directive and display the post attributes we want.

Note: The *~* symbol is an alias for the */* directory. You can check out the docs here to see the different aliases Nuxt.js provides, and what directories they’re linked to.

Next, we add the <posts> component to the homepage:

<!-- ./pages/index.vue -->
<template>
<div>
    <!-- ... -->
    <posts />
</div>
</template>

<script>
import Posts from '~/components/Posts.vue'

export default {
  components: {
    Posts
  },
  // ...
}
</script>


Adding Dynamic Routes

Now we’ll add dynamic routes for the posts, so we can access a post for example with this URL: /post/1.

To achieve this, we add the post directory to the pages directory and structure it like this:

pages
└── post
    └── _id
        └── index.vue


This generates the corresponding dynamic routes for the application like this:

router: {
  routes: [
    // ...
    {
      name: 'post-id',
      path: '/post/:id',
      component: 'pages/post/_id/index.vue'
    }
  ]
}


Updating the single post file:

<!-- ./pages/post/_id/index.vue -->
<template>
  <div class="main-content">
    <div class="container">
      <h2 class="title is-2">{{ post.title }}</h2>
      <div v-html="post.content"></div>
      <br>
      <h4 class="title is-5 is-marginless">by <strong>{{ post.author }}</strong> at <strong>{{ post.published }}</strong></h4>
    </div>
  </div>
</template>

<script>
  // import posts saved JSON data
  import posts from '~/posts.json'

  export default {
    validate ({ params }) {
      return /^\d+$/.test(params.id)
    },
    asyncData ({ params }, callback) {
      let post = posts.find(post => post.id === parseInt(params.id))
      if (post) {
        callback(null, { post })
      } else {
        callback({ statusCode: 404, message: 'Post not found' })
      }
    },
    head () {
      return {
        title: this.post.title,
        meta: [
          {
            hid: 'description',
            name: 'description',
            content: this.post.summary
          }
        ]
      }
    }
  }
</script>


Nuxt.js adds some custom methods to our page components to help make the development process easier. See how we use some of them on the single post page:

  • Validate the route parameter with the validate method. Our validate method checks if the route parameter passed is a number. If it returns false, Nuxt.js will automatically load the 404 error page. You can read more on it here.
  • The asyncData method is used to fetch data and render it on the server side before sending a response to the browser. It can return data via different methods. In our case, we use a callback function to return the post that has the same id attribute as the route id parameter. You can see the various ways of using this function here.
  • As we’ve seen before, we use the head method to set the page’s headers. In this case, we’re changing the page title to the title of the post, and adding the post summary as a meta description for the page.

Great, now we can visit our blog again to see all routes and pages working properly, and also view the page source to see the HTML being generated. We have a functional server-rendered JavaScript application.

Generating Static Files

Next, we can generate the static HTML files for our pages.

We’ll need to make a minor tweak though, as by default Nuxt.js ignores dynamic routes. To generate the static files for dynamic routes, we need to specify them explicitly in the ./nuxt.config.js file.

We’ll use a callback function to return the list of our dynamic routes:

// ./nuxt.config.js

module.exports = {
  // ...
  generate: {
    routes(callback) {
      const posts = require('./posts.json')
      let routes = posts.map(post => `/post/${post.id}`)
      callback(null, routes)
    }
  }
}


You can check here for the full documentation on using the generate property.

To generate all the routes, we can now run this command:

npm run generate


Nuxt saves all generated static files to a dist folder.

Deployment on Firebase Hosting

As a final step, we can take advantage of hosting by Firebase to make our static website live in a couple of minutes. This step assumes that you have a Google account.

First, install the Firebase CLI, if you don’t already have it:

npm install -g firebase-tools


To connect your local machine to your Firebase account and obtain access to your Firebase projects, run the following command:

firebase login


This should open a browser window and prompt you to sign in. Once you’re signed in, visit https://console.firebase.google.com and click Add project. Make the relevant choices in the wizard that opens.

Once the project is created, go to the project’s hosting page at [https://console.firebase.google.com/project/<project](https://console.firebase.google.com/project/<project "https://console.firebase.google.com/project/<project") name>/hosting and complete the Get started wizard.

Then, on your PC, from the root of your project directory, run the following command:

firebase init


In the wizard that appears, select “Hosting”. Then select your newly created project from the list of options. Next choose the dist directory as the public directory. Select to configure the page as a single-page app and finally select “No” when asked if you want to overwrite dist/index.html.

Firebase will write a couple of configuration files to your project, then put the website live at [https://<project](https://<project "https://<project") name>.firebaseapp.com. The demo app for this article can be seen at nuxt-ssr-blog.firebaseapp.com.

If you run into problems, you can find full instructions on Firebase’s quickstart page.

Conclusion

In this article, we’ve learned how we can take advantage of Nuxt.js to build server-rendered JavaScript applications with Vue.js. We also learned how to use its generate command to generate static files for our pages, and deploy them quickly via a service like Firebase Hosting.

The Nuxt.js framework is really great. It’s even recommended in the official Vue.js SSR GitBook. I really look forward to using it in more SSR projects and exploring all of its capabilities.