2018 / 08 / 21
2020 / 04 / 23
Quickstart guide for a new Nuxt.js project

Universal Vue.js applications

vue.js
vuetify
material design
nuxt.js

Introduction

If you are into Vue.js it’s hard not to bump into Nuxt.js.

But what is it? Well, on their page they say:

Nuxt — Universal Vue.js Applications
That means you can have your SPA (Single Page Application) + SSR (Server Side Rendering).

As I see it, it’s an opinionated framework for building web apps on top of Vue.js.
A convention over configuration type of framework, if you will.

Knowing your way around vue-cli apps first, will certainly help you understand what Nuxt.js does for you.

Nevertheless, what really caught my eye was the fact that it can be used as a Static Site Generator too.

Right now, I’m exploring the idea of using it as the basis for the new version of this blog, because:

  • I’m already a big fan of Vue.js.
  • I’m already pretty good at Vue.js development.
  • I want to leverage my knowledge of Vuetify and Material Design to make it usable and pretty.
  • I’m finding it difficult to write articles that mix Vue.js, Vuetify and D3 using Hugo.

So, what follows is a step-by-step guide into getting a new Nuxt.js app up and running with Vuetify, Pug and Sass support.

If you are looking for a guide on how to set up a normal vue-cli application, have a look at this: Quickstart guide for a new Vue.js project.

Alternatives

If you are exploring alternatives in this space, here are some links for you:

  • Gridsome — Build blazing fast websites for any CMS or data with Vue.js
  • Ream — Universal Vue.js Applications Made Simple
  • Saber.js — A minimalistic framework for building static website using Vue.js

Prerequisites

Install Node.js, Yarn and vue-cli

Generate a new project

To create a new Nuxt.js app, type this in your terminal:

yarn create nuxt-app my-nuxtjs-app

This is equivalent to:

yarn global add create-nuxt-app
create-nuxt-app my-nuxtjs-app

If the command create-nuxt-app is not available to you in the CLI, don’t forget to asdf reshim nodejs.

It’ll ask you some questions like:

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in my-nuxtjs-app
? Project name
my-nuxtjs-app

? Project description
My rad Nuxt.js project

? Author name
lobo_tuerto

? Choose programming language
JavaScript

? Choose the package manager
Yarn

? Choose UI framework
Vuetify.js

? Choose custom server framework
None (Recommended)

? Choose Nuxt.js modules
Axios, Progressive Web App (PWA) Support, DotEnv

? Choose linting tools
ESLint

? Choose test framework
Jest

? Choose rendering mode
Universal (SSR)

? Choose development tools
jsconfig.json (Recommended for VS Code)

An interesting use case for going with Universal without a Node.js server is for having a statically generated site.
Just use the yarn generate instead of yarn build to build your pre-rendered site and deploy to a web server like NGINX.

That’s how this blog is currently built.

Start the development server:

cd my-nuxtjs-app/
yarn dev

Now, open your browser and visit: http://localhost:3000.

You’ll see something like:

Nuxt.js + Vuetify page

Adjust ESLint rules

Add this line to the rules key in the .eslintrc.js file:

'no-multiple-empty-lines': [2, { max: 2 }]

The reason for this change, is pure personal style.
I usually leave two consecutive blank lines between some elements inside my .js and .vue component files.

For example between import sections and code for .js files.
Or between <template>, <script> and <style> sections for .vue files.

nuxt.config.js setup

If you are going to use Nuxt.js as a static site generator and you’re using Vuetify, then you should extract the CSS code to another file.

In this way you won’t have all the CSS embedded in every generated file, thus dramatically reducing file size.

--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -84,6 +84,7 @@ export default {
  build: {
     /*
     ** You can extend webpack config here
     */
     extend (config, ctx) {
-    }
+    },
+    extractCSS: true
   }
 }

Extract Vuetify opts

To extract Vuetify’s config options to their own file, make these changes on nuxt.config.js

--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -1,5 +1,3 @@
-import colors from 'vuetify/es5/util/colors'
-
 export default {
   mode: 'universal',
   /*
@@ -60,21 +58,7 @@ export default {
   ** https://github.com/nuxt-community/vuetify-module
   */
   vuetify: {
-    customVariables: ['~/assets/variables.scss'],
-    theme: {
-      dark: true,
-      themes: {
-        dark: {
-          primary: colors.blue.darken2,
-          accent: colors.grey.darken3,
-          secondary: colors.amber.darken3,
-          info: colors.teal.lighten1,
-          warning: colors.amber.base,
-          error: colors.deepOrange.accent4,
-          success: colors.green.accent3
-        }
-      }
-    }
+    optionsPath: './vuetify.config.js'
   },
   /*
   ** Build configuration

And create a vuetify.config.js file with this content:

import colors from 'vuetify/es5/util/colors'


export default {
  customVariables: ['~/assets/variables.scss'],
  theme: {
    dark: true,
    options: {
      customProperties: true
    },
    themes: {
      dark: {
        primary: colors.blue.darken2,
        accent: colors.grey.darken3,
        secondary: colors.amber.darken3,
        info: colors.teal.lighten1,
        warning: colors.amber.base,
        error: colors.deepOrange.accent4,
        success: colors.green.accent3,
        background: '#8f8ce7'
      }
    }
  }
}

The customProperties: true is so you can do stuff like:

.app
  background-color: var(--v-background-base)

Add some useful libraries

yarn add date-fns lodash-es

Utility library and date manipulation library: check and check!

Add Pug and Sass support

I like writing my Single File Components using Pug and Sass
And I recommend you do the same, betting on them is such a no-brainer.

yarn add --dev pug pug-plain-loader
# yarn add --dev sass sass-loader # included with @nuxtjs/vuetify

Pug rewrite example

Just see how concise and lean is the Pug version compared to its HTML counterpart.

From this in pages/inspire.vue:

<template>
  <v-layout>
    <v-flex class="text-center">
      <img
        src="/v.png"
        alt="Vuetify.js"
        class="mb-5"
      >
      <blockquote class="blockquote">
        &#8220;First, solve the problem. Then, write the code.&#8221;
        <footer>
          <small>
            <em>&mdash;John Johnson</em>
          </small>
        </footer>
      </blockquote>
    </v-flex>
  </v-layout>
</template>

To this:

<template lang="pug">
v-layout
  v-flex(text-center)
    img(src="/v.png" alt="Vuetify.js").mb-5

    blockquote.blockquote
      span.
        &#8220;First, solve the problem.
        Then, write the code.&#8221;

      footer
        small
          em &mdash;John Johnson
</template>


<style lang="sass" scoped>
.blockquote
  background-color: #bf0051
</style>

Point your browser to: http://localhost:3000/inspire and you’ll see:

Inspire page

That’s it!

Now, go write great Vue.js apps with Nuxt.js!

Jest + Pug errors

If you see something like this while running yarn test:

ERROR:
[vue-jest] Error: Vue template compilation failed

STACK: Error:
[vue-jest] Error: Vue template compilation failed

You might need to add this to jest.config.js:

--- a/jest.config.js
+++ b/jest.config.js
@@ -1,4 +1,11 @@
 module.exports = {
+  globals: {
+    'vue-jest': {
+      pug: {
+        doctype: 'html'
+      }
+    }
+  },
   moduleNameMapper: {
     '^@/(.*)$': '<rootDir>/$1',
     '^~/(.*)$': '<rootDir>/$1',

Conclusion

Nuxt.js offers an interesting —and opinionated— way for implementing Vue.js apps.

It covers everything I need for writing great content for this blog. :)