Quick Tips for NuxtJS

'Good to know's and Gotchas

Published: 4/18/2021

Pumpkin laying on my desk as I wrote this
Pumpkin laying on my desk as I wrote this

While working to create The Russo Block using NuxtJS I struggled over errors and configuration mishaps that delayed progress and took some of the fun out of developing my own website. I figured it would be worthwhile to share some solutions and tricks I discovered and if nothing else to document my solutions for my future self.

Background

This post is not intended to be a definitive guide on creating a static website using NuxtJS. I will not pretend that I could explain NuxtJS any better than the creators themselves. NuxtJS offers their own paid course Mastering Nuxt which I cannot personally attest to although it is likely the best resource if you have the money. Alternatively, I would recommended simply running through the official NuxtJS introductory guide which is entirely free.

I chose to use NuxtJS for two main reasons. First, I had prior experience using VueJS while working at CSU Bakersfield's Web Development department and found the framework to be intuitive and quick. Second, when I first began looking for framework for The Russo Block I knew I wanted an uncomplicated and lightweight solution and saw NuxtJS had announced major improvements to their static website generation which appealed to me. I have previously attempted to create The Russo Block using Drupal and a more expensive web-hosting service, but quickly realized my small blog couldn't possibly warrant such high maintenance. However, I did decide to use the BootstrapVue, Nuxt Content and Nuxt Sitemap modules (which coincide quite nicely) for their added convenience. A few of the errors you will see below concern these modules.

Now having completed my static website using Nuxt and deploying to Netlify (for free, by the way) I can safely say this approach has been incredibly versatile, resilient, and easy. I cannot recommend it enough, especially once you get past any errors like those outlined below.

Error: Can Not Read a Block Mapping Entry

Right off the bat this error is actually one I encountered while trying to add single quotes to this post's subtitle ('Good to Know's). Once I realized this was a YAML error associated with the Markdown file's front matter the solution became apparent.

Following advice from this Stack Overflow post I managed to escape the singlequote characters by wrapping the entire value in double quotes like so:

subtitle: "'Good to know's and Gotchas"

Furthermore, you can escape doublequote and backslash characters within your YAML value by using the more ubiquitous backslash \ escape character so long as the value is wrapped in double quotes.

Tip: Helper Functions

After returning to The Russo Block and NuxtJS from an extended leave I had forgotten even some fundamentals of modern Javascript like importing modules.

This tip is simple, but damning if you draw a blank looking for it. I recommend you create a utils folder in the root of your NuxtJS project then add Javascript source files containing your helper functions. Import and export said functions using standard ES6 syntax.

Here I import my formatDate function. Your end result should look something like this:

// ~/utils/formatDate.js

export default (date) => {
  const obj = new Date(date)
  const fmtd = (obj.getMonth() + 1) + '/' + obj.getDate() + '/' + obj.getFullYear()
  return fmtd
}
// ~/pages/notes/_slug.vue

<script>
import formatDate from '~/utils/formatDate'
// ...
</script>
Error: Nuxt Content Bailing Hydration

This is a rather generic error from VueJS that can mean a lot of things. In my case I started by looking for "incorrect HTML markup... nesting block-level elements inside <p>" and found an issue with my combined use of Nuxt Content and Bootstrap Vue.

By default, Nuxt Content generates <p> tags for your regular Markdown text while Bootstrap Vue's default behavior is to generate all content within a <b-card-text> element inside a <p> tag as well. The result? Nested block-level elements, thus invalid HTML, thus bailed hydration.

The solution is simple, use Bootstrap Vue's dedicated text-tag property of <b-card-text> to specify a 'div' tag instead.

Your end result should look like this:

<b-card-text :text-tag="'div'">
Tip: Delete README.mds

When you first create a new NuxtJS project using their CLI tool Nuxt likes to generate a lot of explanatory README.md files in each of the generated directories. These are useful to read through for the first couple times, however leaving them in your repository when pushing to production (while probably not noticeable) can add extra HTTP requests and appear 'unpolished' to anyone inspecting your website's network activity.

In particular be sure to delete the README.md files from your ~/static, ~/assets, and ~/pages directories since these can end up being sent to your end users. E.g. "therussoblock.com/README.md" used to try downloading a Markdown file.

Error: 404s on Dynamic Routes

After reading about NuxtJS's 'Full Static' mode I immediately switched over to leverage the faster load times and shiny new integrated crawler which promised to generate dynamic routes without having to write custom functions to find and list them. Despite this, I was met with 404 errors on my dynamic routes and struggled to uncover why.

It appears when I created my Nuxt project using the CLI tool's prompts I somehow enabled conflicting settings. To resolve this error and take advantage of the new crawler simply ensure that target: 'static' and ssr: false are set in your nuxt.config.js file. Somehow mine was set to ssr: true.

Error: Hostname Option is Mandatory

This error sounds complicated, but only requires you add a sitemap: {} object to your nuxt.config.js file and give it a hostname attribute as a string. In my case this looks like:

sitemap: {
  hostname: 'https://www.therussoblock.com',
  // the following doesn't impact this particular error
  routes () {
    return getRoutes()
  }
}

So there we have it. A handful of confusing error messages with surprisingly simple solutions.

As usual please leave any comments or feedback on my LinkedIn or my other contact methods. Catch you later! end mark