Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

TND SEO Hugo Module

Hugo Module to quickly add sensible -- yet highly extendable -- SEO/opengraph metatags.



  • Go 1.14
  • Hugo 0.54.0


If not already, init your project as Hugo Module:

$: hugo mod init

Configure your project's module to import this module:

# config.yaml
    - path:


Drop the following where appropriate

{{ if templates.Exists "partials/tnd-seo/tags.html" }}
  {{ partial "tnd-seo/tags.html" . }}
{{ end }}

The above partials, will look for content information and build an Data object to be printed in SEO tags (og, twitter card etc...).

Add/Modify SEO Data

The module parses some data for each page in order to produce the right SEO tags. If you need to alternate the data model, you can do so by adding to your project a layouts/partials/tnd-seo/AddSEOData.html partial and add to it as explained here.

From the partial you can access the SEO Data model with .seo.

Here is the Data model before user modification:

canonical: String (ex:
description: String
image: String
image_absolute: String (same as the above)
image_relative: String
jsonld: Map
locale: String (ex: en)
private: Boolean
site_name: String
title: String (ex: That Page | That Site)
translations: Slice
  - code: String
    permalink: String
twitter_card: summary_large_image
type: website


In this example we need to focus our efforts on the site recipes and

  1. Use a custom parameter for the SEO description
  2. Prepend a CDN url to the relative value of the SEO image
{{/* layouts/partials/AddSEOData.html */}}
{{ $s := newScratch }}
{{ $s.Set "seo" dict }}

{{ if eq .Type "recipe" }}
  {{ with .Page.Params.recipe_incentive }}
    {{ $s.SetInMap "seo" "description" . }}
  {{ end }}
  {{ with .seo.image_relative }}
    {{ $s.SetInMap "seo" "image" (print "" .) }}
  {{ end }}
{{ end }}

{{/* Merge is important here as we want to overwrite the default data model with user's edits */}}
{{ return merge .seo ($s.Get "seo") }}


Settings are added to the project's parameter under the tnd_seo map as shown below.

# config.yaml
    # overrides .Site.Title
    site_name: MyWebsite
    # Used for articles without images
    default_image: "/images/default.jpg"
    # if true will use the SEO data object to output an json+ld script tag.
    jsonld: true
    disable_title_tag: false
    # if true module will handle follow/nofollow tags for pages depending on environment and Front Matter setting.
    enable_follow: false

Title tag

Maybe website or theme handle their own <title> tag and removing it can be tricky. Even though by default the Module will handle the tag for your, you can prevent such behaviour by adding disable_title to the settings.

Private pages

If the configuration value of enable_follow is set to true, the site's meta robots tags will be set for the site to be discoverable:

<meta content="index, follow" name=robots>

This setting can be overridden on a page-by-page-basis with the following front matter:

  private: true

The page above, when in production will sport the nofollow/noindex meta tag.

<meta content="noindex, nofollow" name=robots>

Alternatively, you can set all pages to be private using Hugo's front matter cascade:

    private: true

Note: If enable_follow is set to true, the module will print a nofollow, noindex tag for every pages unless

  • The environment variable HUGO_ENV value is production
  • seo.private is not set or equals to false

Front Matter

Some values generated by the Module's logic can be overwritten using the seo Front Matter map.

title: Out of context
description: That's dull!
  title: Intersting Title
  image: /uploads/way-better-that-this-post-featured.png
  description: A catchy phrase.

Extend SEO Data

In order to customize the SEO Data consumed by Hugo to build the tags. User can create on the project level a tnd-seo/AddSEOData partial.


This project is maintained and loved by thenewDynamic.