What To Do After Installing Nuxt

Vue js

Once you have a Nuxt app up and running it's common to add styles, assets, plugins and modules. If you don't have a Nuxt project installed yet head on over to the docs and follow their installation instructions. Be sure to use the vue-cli starter template method.

Sections


nuxt.config.js

The head property

ESLint: enabling fix on save

Adding assets: style sheets, Sass, Tachyons, and Font Awesome

Adding a plugin: Google's gtag library

Adding modules

nuxt.config.js


Nuxt depends on conventional directory structure and a sensible default configuration to output an app. You can override and add to the configuration in nuxt.config.js. Getting familiar with the Nuxt config is crucial for understanding and developing with Nuxt.

The head property


The first section corresponds to the head tag in the html document. It controls the meta information for the application. We're not going to do anything fancy here but lets make an update. These are the default values with the title property being whatever was chosen during vue-cli setup:

//nuxt.config.js
 
head: {
  title: 'nuxt-demo',
  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' }
  ]
}

In the head.meta property edit the content value to the description of your site.

Save and inspect <head></head> with your browser's devtools to see the update. This is a simple example but is a nice illustration of what nuxt.config.js controls. You could set <link></link>, <style></style> and <script></script> tags in the head property. We'll set some these below in other properties but if you want to add external resources you can do so here. The documentation has a straightforward example.

The head property makes use of vue-meta so check out the vue-meta docs for a deeper dive.

Enabling Fix on Save


Linting greatly improves code quality and consistency. The tools have gotten quite good and you should use it for all js projects. In the past linting required a fair amount of setup. Now with most frameworks with a cli it requires little to no setup, maybe just a little tweaking for you or your team's code style/work flow.

Nuxt installs linting by default and uses eslint-loader. This is the relevant section in nuxt.config.js:

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

The above options will lint code on save.

I recognize linting's benefits but haven't always linted past projects or did so as a manual step. It sometimes felt like it got in the way and interrupted the flow of coding. One of the nice things about developing with javascript is its fast iteration so it can be frustrating when extra whitespace or something similar throws an error. We can set our project to fix errors on save though which clears this up.

To enable fix on save add the options property with fix : true as shown below:

// nuxt.config.js
 
/*
  ** Build configuration
  */
  build: {
    /*
    ** Run ESLint on save
    */
    extend (config, ctx) {
      if (ctx.dev && ctx.isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/,
          options: {
            fix: true
          }
        })
      }
    }
  }

Now linting occurs on save and will fix linting errors if possible(mainly white space errors). This simple change clears up a lot of linting errors that interrupt coding. I also recommend installing the eslint plugin that is available for most popular editors which will enable error highlighting.

If you'd like to add custom rules edit .eslintrc.js. The default setup is:

//eslintrc.js
 
module.exports = {
  root: true,
  parser: "babel-eslint",
  env: {
    browser: true,
    node: true,
  },
  extends: "standard",
  // required to lint *.vue files
  plugins: ["html"],
  // add your custom rules here
  rules: {},
  globals: {},
};

I find just using standardjs rules works well for me which is what's set in the config above. In the past I've used airbnb rules. I really liked standardjs better once I gave it a try. Standardjs is also widely used and required in order to contribute to many open source projects. A set up that uses standardjs, so you don't have to manually set rules, and fixing errors on save makes linting pretty painless.

See the eslint website for a more on what's possible.

A lot of developer's first impulse is to turn linting off. It only takes a bit to get use to though and you'll appreciate it the more you collaborate with others. For instance, I've often seen devs leave unused variables or import statements in code. With the use of standardjs this would emit an error and prevent it from being committed eliminating large amounts of cruft. If you've been resistant to linting in the past using it with new Vue or Nuxt projects is a great way to get started with it.

Another thing to note is adding /* eslint-disable */ to the top of a file will turn linting off for that file.

Adding assets: style sheets, Sass, Tachyons, and Font Awesome


Assets are loaded using the default Webpack config which you can extend. Adding basic assets such as styles is pretty straight forward. I usually use Sass but the process should be similar for any preprocessor.

Install the packages via npm:

npm install --save-dev node-sass sass-loader

Make a directory in assets called css and a file in that directory called styles.scss. So you should have: assets/css/styles.scss

Add a style rule to test it out:

<!-- assets/css/styles.scss -- > body {
  background: purple;
}

Now add the css property in nuxt.config.js and the style file as an array value:

//nuxt.config.js
 
css: ["~assets/css/styles.scss"];

After a browser refresh your style should be applied.

While we're at it let's add font-awesome icons and tachyons for some css helper classes.

npm install --save-dev tachyons font-awesome

Add them to the css property:

//nuxt.config.js
 
css: [
  "~assets/css/styles.scss",
  "font-awesome/scss/font-awesome.scss",
  "tachyons/css/tachyons.min.css",
];

Start the dev server or refresh the browser if needed.

Something to note here are the file paths. The ~ indicates that it is a module request an @ also could have been used. These will resolve starting at the source directory. You can also use ~~ and @@ which will resolve to the root directory. Font Awesome and Tachyons are both node modules and are resolved from the node_modules directory.

Font awesome, tachyons, and the custom style sheet should now be available to the components. The focus of this post is adding to nuxt.config.js so I'm not going to go into how to use Font Awesome and Tachyons. Please check out their docs for more information.

Briefly though Tachyons is a set of atomic css classes. I've been using it for over a year in most of the projects I've worked on and find it super useful. I highly recommend it or something similar. It's greatly improved my design and productivity. I'll devote an entire post to atomic css soon.

Adding a plugin: Google's gtag library


It's very common for people to want Google Analytics for webapps. I hadn't set it up in a while and did so last week. It turns out adding it changed a bit since the last time I added it to a site. They now are pushing users to the gtag.js(global site tag) library instead of analytics.js. I'll leave it up to you to figure out how to sign up and get a tracking id.

Here's how to add the script:

Create a new file gtag.js in the plugins directory. You should now have: plugins/gtag.js

Add the following where GA_TRACKING_ID is your tracking id:

//plugins/gtag.js
 
/* eslint-disable */
 
export default ({ app }) => {
  // Only works in production
  if (process.env.NODE_ENV !== "production") return;
 
  // Create a script element and add the url for the gtag library
  let gtagScript = document.createElement("script");
  gtagScript.setAttribute(
    "src",
    "https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID",
  );
  gtagScript.setAttribute("async", "");
  gtagScript.setAttribute("defer", "");
 
  // Append the element to the document
  document.body.appendChild(gtagScript);
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag("js", new Date());
 
  // Add a gtag config
  gtag("config", "GA_TRACKING_ID");
 
  // Track a page view when the route changes.
  app.router.afterEach((to, from) => {
    gtag("config", "GA_TRACKING_ID", {
      page_title: to.name,
      page_path: to.fullPath,
    });
  });
};

Next update the Nuxt config file:

// nuxt.config.js
 
plugins: [
  { src: '~plugins/gtag.js', ssr: true }
  ],

For testing comment out if (process.env.NODE_ENV !== 'production') return. After a browser refresh open up devtools and you should see a script element added with the gtag library. You also should be able to see some activity in your google analytics dashboard.

Plugins are useful for adding 3rd party libraries or scripts you want to run before the Vue instance is loaded among other things. It's an easy way to add functionality. There are a lot of possibilities for them so take a look at the plugins section of the documentation.

Adding modules


Nuxt maintains a list of community modules (Vue does too). The quality varies from works fine to buggy with the ones I've tried(which have only been I handful). I tend to like to make UI components myself so usually don't use UI modules. I also don't like a module hijacking my css or having to work around its styles.

A lot of modules also wrap already existing libraries. While sometimes this adds some convenience or functionality most of the time it's a little silly. I'd rather just use the library directly. For example the tachyons and font-awesome libraries we added above can be found as modules. Using libraries as modules also adds an unnecessary dependency whose upkeep is not guaranteed. Most if not all JS framework eco-systems have these same issues. The most common libraries and modules, especially ones that are recommended in documentation are usually high quality but caveat emptor for most others.

We'll add two modules. Markdownit which is a markdown module and sitemap. You can probably guess what sitemap does.

Install with npm: npm install @nuxtjs/markdownit @nuxtjs/sitemap

The @nuxtjs/ prefix denotes they are Nuxt community modules.

Add the code below to you nuxt.config.js if you wish but it will probably break your app since the routes in the sitemap config don't actually exist. Markdownit should work fine though.

// nuxt.config.js
 
modules: [ '@nuxtjs/sitemap', '@nuxtjs/markdownit' ],
 
// modules config
markdownit: {
  preset: 'default',
  linkify: true,
  breaks: true,
  langPrefix: 'language-'
},
 
// sitemap config
sitemap: {
  path: '/sitemap.xml',
  hostname: 'https://some_website.net',
  cacheTime: 1000 * 60 * 15,
  generate: false,
  routes: [
    '/',
    '/about',
    '/blog',
    '/projects',
    '/articles/most_excellent_post_1',
    '/articles/most_excellent_post_2',
    '/articles/totally_bogus_post'
  ]
},

You might see some modules in their examples setting up their options like in the markdownit section below. This can make your module section unwieldy the more modules you add. I prefer structure above where the modules are added to an array and each module has an options section below that.

// nuxt.config.js
 
modules: [
  [
    "@nuxtjs/markdownit",
    {
      preset: "default",
      linkify: true,
      breaks: true,
      langPrefix: "language-",
    },
  ],
];

I just wanted to illustrate here how to add modules rather than covering their functionality. In another post soon I'll go more in depth on working with modules particularly markdownit.


These examples are just the basics of what's possible. The nuxt.config.js is at the core of a Nuxt app. This article covered a few common things to add to a new Nuxt project. To see all available configuration properties and for more detail see the documentation. In a future post I'll focus on a specific section or two with some more advanced examples.

Links


ESLint
Markdownit
Nuxt installation
Nuxt modules
Sitemap
Tachyons
Vue modules