Documentation for the MoonBooth SEO Theme for Hugo
How to use the MoonBooth SEO Theme for Hugo.
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 fix you up.
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 element | SCSS variable | Default value |
---|---|---|
Accent colour | $color-accent | red |
Background color | $color-background | black |
Light gray | $color-gray | #ccc |
Text color | $color-text | white |
Font size increment | $increment | 10px |
Content width | $wrapper-max-width | 700px |
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!
Third-party JS
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/"]
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, like this:
[params]
scripts = ["https://js.stripe.com/v3/", "https://js.example.com/v1/"]
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, especially around the git submodule
/ public deploy key design decision.
It may well be easier for everyone if I just provide the theme files which you can then add to your repo directly. When I start selling this theme, I may well do that.
I’d love to hear from you: I’m on ron dot erdos at [the site you’re on].