Quickstart guide for a new Nuxt.js project

Published on 2018/08/21 ‚óŹ Last updated on 2018/08

Table of contents

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 this blog, because:

  • I’m already a big fan of Vue.js.
  • I’m already fairly good at Vue.js development.
  • I want to leverage my knowledge of Vuetify and Material Design to make it pretty and usable.
  • I’m finding it difficult to write live pages that mix Vue.js, Vuetify and D3 using Hugo.
  • I really want to publish more content showcasing those technologies.

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

If you are looking for a guide on how to setup a normal vue-cli application, check this one out: Quickstart guide for a new Vue.js project.

Alternatives

If you are exploring alternatives in this space, here is a couple of links for you:

  • Ream — Universal Vue.js Applications Made Simple.
  • Saber.js — A minimalistic framework for building static website using Vue.js.
  • Peco — A future-ready static site generator for Vue.

Prerequisites

Install Node.js, Yarn and vue-cli

A new Nuxt.js app

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

vue init nuxt-community/starter-template my-nuxt-project

It’ll ask you some questions like:

? Project name (my-nuxt-project)
? Project description (Nuxt.js project)
? Author (Your Name <your@email>)

After that, install the project dependencies and start the development server:

cd my-nuxt-project/
yarn
yarn dev

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

You’ll see something like:

Default Nuxt.js page

Upgrading to nuxt-edge

Let’s upgrade to the prerelease Nuxt.js 2.0 version:

yarn remove nuxt
yarn add nuxt-edge

Now, try to start your development server:

yarn dev

You’ll be greeted with:

 ERROR  Failed to compile with 1 errors

Module build failed (from ./node_modules/eslint-loader/index.js):
TypeError: Cannot read property 'eslint' of undefined
    at Object.module.exports (.../node_modules/eslint-loader/index.js:148:18)

You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.

To get rid of that error you need to edit your nuxt.conf.js file and change it like:

- module.exports = {
+ export default {
  // ...
  build: {
    /*
    ** Run ESLint on save
    */
-    extend (config, { isDev, isClient }) {
-      if (isDev && isClient) {
+    extend (config, { isDev }) {
+      if (isDev && process.client) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}

Stop and restart your server, there should be no errors now.

If you visit http://localhost:3000/ you should see again:

Default Nuxt.js page

Adding Vuetify with Pug and Stylus support

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

yarn add vuetify
yarn add pug pug-plain-loader stylus stylus-loader --dev

Default layout

Change your layouts/default.vue file to:

<template lang="pug">
  v-app
    nuxt
</template>

Index page

Change your pages/index.vue file to:

<template lang="pug">
  v-content
    v-container

      v-card
        v-card-text.text-xs-center
          app-logo
          .display-4.mt-5 my-nuxt-project
          .display-2.mt-3 Nuxt.js project + Vuetify

          .mt-4
            v-btn(color="success" href="https://nuxtjs.org")
              span Documentation
              v-icon.ml-2 spa

            v-btn(color="secondary" href="https://github.com/nuxt/nuxt.js")
              span GitHub
              v-icon.ml-2 whatshot

            v-btn(color="primary" href="https://vuetifyjs.com")
              span Vuetify
              v-icon.ml-2 local_florist
</template>


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

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


<style lang="stylus" scoped>
.display-2
  font-weight: 300

.display-4
  font-weight: 400
</style>

Vuetify plugin

Create a new file in plugins/vuetify.js with this content:

import Vue from 'vue'
import Vuetify from 'vuetify'

import 'vuetify/dist/vuetify.min.css'


Vue.use(Vuetify)

Nuxt.js config

Change your nuxt.config.js file to:

export default {
  // Headers of the page
  head: {
    title: 'my-nuxt-project',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'Nuxt.js project' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      {
        rel: 'stylesheet',
        type: 'text/css',
        href: 'https://fonts.googleapis.com/css?family=Roboto:100:300,400,500,700,900|Material+Icons'
      }
    ]
  },

  // Customize the progress bar color
  loading: { color: '#3B8070' },

  // Build configuration
  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)/
        })
      }
    }
  },

  // Load Vuetify
  plugins: ['~/plugins/vuetify']
}

If you go to http://localhost:3000 you should see:

Vuetify Nuxt.js page

Load Vuetify’s stylus styles

We imported the minified CSS in the plugins/vuetify.js file.
That was a quick-and-dirty way of importing Vuetify’s CSS rules.

The proper way to do it is presented below.


First, get rid of the CSS import in plugins/vuetify.js:

import Vue from 'vue'
import Vuetify from 'vuetify'

// import 'vuetify/dist/vuetify.min.css'


Vue.use(Vuetify)

Then, create a new assets/css/app.styl file with this content:

@require '~vuetify/src/stylus/main'

Finally, make these changes to nuxt.config.js:

   // Load Vuetify
-  plugins: ['~/plugins/vuetify']
+  plugins: ['~/plugins/vuetify'],
+
+  // Load Vuetify styles
+  css: ['~/assets/css/app.styl']
 }

That’s it!

As you can see, the way you include JavaScript and CSS files is a bit different in Nuxt.js.


Conclusion

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

I’ll definitely keep poking around and see if it can cover all the use cases for the next iteration of my blog.


— lt

Feedback & comments

Get in touch on Twitter

Or by good ol' email at adriandcs@gmail.com