Documentation for the MoonBooth SEO Theme for Hugo

How to use the MoonBooth SEO Theme for Hugo.

Ron Erdos • Updated May 4, 2021

About this theme

Here’s more about the MoonBooth SEO Theme for Hugo and all its SEO advantages.

Demo

This site (moonbooth.com) uses the theme, as does its sister site, Julia School, where I publish Julia language tutorials. The Julia School GitHub repo is public, if you want to see how I’ve implemented everything on this page.

Installation

Step 1

After purchase*, download the .zip of the theme folder. Extract it, then drop it into your /themes/ folder.

*If you subscribed to MoonBooth.com email updates before February 1, 2021, as promised, your theme is free. Email me at ron dot erdos at this domain and I’ll send you the theme.

Step 2

In your config file (usually /config.toml), add these lines without any indents:

theme = "moonbooth-seo-theme"
[taxonomies]
enableRobotsTXT = true

The first line will tell Hugo to go ahead and actually use the theme.

The second line tells Hugo that we’re not using any taxonomies. If you want to use this theme with Hugo taxonomies, feel free to add the relevant code to your site (including updating this part of config.toml).

The third line activates the creation and publication of a robots.txt file at the root of your site.

Step 3

Also in your config file, add these lines and fill in the values between the double quotes:

[params]
	blogFooterLinkText = ""
	# Sets anchor text of footer link to blog
	
	blogSection = ""
	# Enter your blog folder's name [1]
	
	color = ""
	# Sets theme colour [2] & Safari mask icon colour [3] 
	
	description = ""
	# Sets homepage meta description (for SEO)
	
	rssTitle = ""
	# Sets RSS feed title (for RSS readers) 
	
	seoTitle = ""
	# Sets homepage <title> (for SEO)

Notes for code above:

[1] If you haven’t renamed your blog folder, the value you should enter here is Hugo’s default of posts. I customise the name of my blog folder, making it more specific to help Google and humans infer what my content is about. For example, on my Julia language training site, I called it julia. I’ve made its GitHub repo public so you can take a look at its Hugo code if you like.

[2] Theme colour documentation

[3] Safari mask icon documentation

Using the theme’s SEO features

Before we get into the theme’s SEO features, here’s a quick primer on the most important text fields for SEO:

Homepage

To set the <title> and meta description of the homepage, fill in the value of seoTitle and description respectively in config.toml, as discussed above.

The homepage is essentially just a subscribe form, and as such there is no <h1>, only a form label. The font size of this label is the same as the <h1> headings elsewhere on the site, though.

Blog index

SEO fields for the blog index are populated using the _index.md approach outlined in the official Hugo documentation. In short, you’ll need to create a file named _index.md at the root of your blog directory. If you’re using the default posts as your blog folder, this file will live at /content/posts/_index.md.

The theme will be looking for three text fields in this _index.md file:

title
seoTitle
description

Each populates the relevant area of the blog index: title populates the <h1> heading, seoTitle populates the document <title> in the <head> section, and description populates two fields: the meta description in the <head> and an italicised summary just below the <h1>. You can see an example on my Julia language training site.

Blog posts

The way to populate the SEO (and other) fields in a blog post is with the following YAML front matter:

---
title:
date: 2021-01-19 13:04:46+11:00
seoTitle:
description:
authors: ["Firstname Lastname"]
tableOfContents: true
---

Let’s go over each.

title populates the <h1> on the blog post itself, and also the anchor text of the link from the blog index back to the post.

date populates the following: 1) the date in the byline on the blog post itself; 2) the <lastmod> date in the XML sitemap—this tells Google when the post was last modified; and 3) the <pubDate> in the RSS feed, which provides the date to RSS readers.

seoTitle populates the document <title> in the <head> section.

description populates two fields: the meta description in the <head> and an italicised summary just below the <h1>. You can see an example on my Julia language training site.

authors: ["Firstname Lastname"] populates the byline (author) field near the top of the blog post. Note that the value is an array of strings, which allows Hugo to do things such as build a page of all your authors.

tableOfContents is an optional YAML field, which, if set to true, builds a table of contents for the page, like the one at the top of this article.

Keeping pages out of Google’s index

There are likely a few pages on your site you want to keep out of Google’s index. Your “thank you for signing up” page, your unsubscribe page, and your 404 page, for example.

The reason you want to keep these pages out of Google’s index is because you don’t want to waste Google’s time crawling pages which will never bring you SEO traffic. Instead, you want to direct Google’s attention to pages that will bring you SEO traffic, such as useful blog posts and product pages.

The best way to keep necessary but non-SEO-worthy pages out of Google’s index is to put a noindex tag in the <head> section of the relevant page.

Specifically, a tag that looks like this:

<meta name="robots" content="noindex" />

That will tell Google and other reputable search engines not to index (list) the page in search results.

You can add the noindex tag easily with this theme, by adding a parameter to your YAML front matter—for posts and pages—that looks like this:

noindex: true

Sitemap for search engines

One of the parts of this theme I’m most proud of is that when you noindex a page, it also withholds it from the SEO (XML) sitemap and the RSS feed. I’ll explain why.

If you noindex a page but simultaneously list it in your XML sitemap, Google considers that an error, or at least, suboptimal. It’s kind of like driving a car with the handbrake on. One the one hand, you’re telling Google to go look at Page X (by listing it in the XML sitemap), but on the other, you’re telling it to stop by including the noindex tag. Generally speaking, you don’t want to direct Google’s attention to pages which have a noindex tag.

robots.txt

Another theme feature I’m proud of is making the location of the XML sitemap (see above section) easy for Google to discover.

To do that, I use an SEO feature called robots.txt.

This theme will automatically include the location of your XML sitemap in your robots.txt file. All you have to do is include the line:

enableRobotsTXT = true

in your config.toml file.

CSS

Broadly, there are three ways to customise styles using this theme; I cover each below. Note that you can use these methods in tandem; they’re not mutually exclusive.

Method 1: Change the value of SCSS variables

The MoonBooth SEO Theme for Hugo uses SCSS—a superset of CSS3—to generate its CSS style sheet.

I’ve designed it this way so that you can change the theme colours in just two lines, rather than doing a messy “find and replace”.

How? SCSS uses variables—something CSS really needs—to keep your styles DRY (which stands for “Don’t Repeat Yourself”).

All the style variables live in an “SCSS partial” at /themes/assets/scss/_variables.scss.

The variables in the _variables.scss partial look like this:

$color-accent: red;
$color-background: black;
$color-gray: #ccc;
$color-text: white;
$increment: 10px;
$wrapper-max-width: 700px;

Going through each in turn:

$color-accent sets the accent colour. Namely: links and buttons in hovered state, block quote decoration, form input fill, button and table borders. It defaults to red because I had to pick a colour that would stand out.

$color-background sets the background colour. It defaults to black because the theme defaults to dark mode, but you can easily change it (as all variables) by following the steps outlined below.

$color-gray specifies which shade of grey should be used when appropriate. At the moment it only sets the colour of visited links, but may be used for more elements in the future. I made it a variable mainly so that all colours can be specified in one place (the SCSS variables partial).

$color-text sets the colour of paragraphs, links, lists, headings (in non-visited, non-hovered state). It defaults to white because the theme defaults to dark mode (white text on a black background).

$increment sets the rhythm for font sizes. Its default value is 10px, but your fonts will never be that small. In the main stylesheet, paragraphs are $increment * 2 or 20px (did you know you can do maths in SCSS?), <h3> headings are $increment * 2.5 (25px), <h2> headings are $increment * 4 (40px), and <h1> headings are $increment * 6 (60px). If you want to change these multiples, you can learn how to do that in the section on adding custom styles, which is lower down on this page.

$wrapper-max-width sets the maximum width of the content column, and defaults to 700px. This theme is responsive, and uses a single column on both mobile and desktop devices. However, given most phone screens are narrower than 700px, this setting will really only affect desktop and tablet devices. I chose 700px as the default as it makes for easy reading when combined with the default paragraph font size (20px) and the default font family.

Here are all the variables in table form:

Design elementSCSS variableDefault value
Accent colour$color-accentred
Background color$color-backgroundblack
Light gray$color-gray#ccc
Text color$color-textwhite
Font size increment$increment10px
Content width$wrapper-max-width700px

To change the value of any of these variables:

Step 1

Duplicate /themes/assets/scss/_variables.scss into your repo (e.g. outside the /themes folder) at /themes/assets/scss/_variables.scss. You may need to create the /assets/ and/or /scss/ folders. Note the leading underscore in the filename of _variables.scss. The reason you want to duplicate the file into your repo is so that your changes won’t be overwritten if/when you pull theme changes.

Step 2

Copy in all six variables, not just the one(s) you want to change. The master theme.scss file will be expecting to see all six variables filled out in your copy of /assets/scss/_variables.scss (if it exists).

Step 3

Change some/all values as you desire. For example, if you wanted to switch from the default dark theme to a light theme, and from the default red accent colour to blue, the complete contents of your <YOUR_REPO>/assets/scss/_variables.scss file could look like this:

$color-accent: blue;
$color-background: white;
$color-gray: #ccc;
$color-text: black;
$increment: 10px;
$wrapper-max-width: 700px;

Method 2: Add custom CSS or SCSS

If you want to make style changes that go beyond altering the theme colours or otherwise editing the SCSS variable values, you can do that too.

For example, if you want a different hover effect on the email signup button, you would do that by using the process outlined in this section.

The way to add custom styles is to use an SCSS partial I’ve called _custom.scss. Here, you can overwrite style rules that ship with the theme and/or add your own style rules.

Your custom style rules can be in plain CSS, or you can use SCSS.

Here’s how to make CSS changes to the theme without having to clone its SCSS file.

Step 1

Duplicate /themes/assets/scss/_custom.scss into your repo (e.g. outside the /themes folder) at /themes/assets/scss/_custom.scss. You may need to create the /assets/ and/or /scss/ folders. Note the leading underscore in the filename of _custom.scss. The reason you want to duplicate the file into your repo is so that your changes won’t be overwritten if/when you pull theme changes.

Step 2

Add your CSS or SCSS style rules. That’s it!

Method 3: Major style overhaul

If you want to change a lot of styles, you’ll probably be better off duplicating the theme stylesheet into your repo and editing it there. That way, you won’t have to “swim against the tide” of the existing style rules that ship with the theme, constantly overwriting them as you would if you used Method 2, above. You’ll also have a more efficient style sheet from the browser’s perspective.

Here’s how to use this method:

Step 1

Create a blank SCSS file—don’t worry, you can use just CSS—at <YOUR_REPO>/assets/scss/theme.scss

Step 2

Add your custom CSS and/or SCSS styles. Again, you can use just plain old CSS if you like. That’s it!

JavaScript

Custom JS

To add custom JS to your Hugo site using this theme, you don’t have to create your own head.html partial.

Instead, simply create a file at /static/scripts/custom.js and put all your custom JS in that file.

The theme will notice the presence of the custom.js file and create a link to it in the <head> section. If no custom.js file exists (the default state), then no link is created. Simple!

External JS files

If you want to add third-party Javascript (from Stripe, for example) to your site with this theme, simply add the link to the script in config.toml, like this:

[params]
	scripts = ["https://js.stripe.com/v3/"]

This will appear in the <head> section of all your web pages like this:

<script src="https://js.stripe.com/v3/"></script>

Note that the theme is expecting an array—hence the square brackets surrounding the value above—even if you only have one third-party script to add.

To add more scripts, simply comma-separate them inside the array, like this:

[params]
	scripts = ["https://js.stripe.com/v3/", "https://js.example.com/v1/"]

Also note that if you want to add Google Analytics, Hugo already has built-in functionality for that.

Feedback

I’d love feedback on this theme—I’m on ron dot erdos at [the site you’re on], or on Twitter (DMs open).

"Thanks so much for your work ... I'm migrating my WordPress blog to Hugo and it's been really helpful" — Francisco S., engineer and blogger

The planets in our solar system