SEO With Hugo (4) - Structured Data Markup

by Samuele Lilliu | 28 January 2023

JSON-LD helps search engines understand website content, improving SEO by providing clear, structured data for search engine crawlers.

X
  • Producer: Samuele Lilliu
  • Software: Hugo, HTML, JSON

Structured data markup is a way of providing additional information about your website’s content to search engines, so they can understand the context and meaning of your site’s pages. This is done by adding specific code to your website’s HTML, called “microdata” or “schema markup”, that allows search engines to extract and process the structured data.

There are different types of structured data, such as JSON-LD, RDFa, and Microdata, and several schemas (vocabularies) like Schema.org, Open Graph, and others.

Structured data can be used to provide information about many different types of content, such as products, articles, events, and more. It can also be used to provide information about your business, such as your opening hours, phone number, and address.

There are several reasons why structured data is important for SEO:

  • Rich Snippets: Structured data can be used to create rich snippets, which are enhanced search result listings that can include additional information such as images, ratings, and prices. These can make your site’s listings more attractive and can increase click-through rates.
  • Better Understanding of Content: Structured data can help search engines understand the meaning and context of your site’s content, which can improve the relevance and authority of your site.
  • Improved Crawlability: Structured data can help search engines find and understand the important information on your site, which can improve the crawlability of your site and lead to better indexing of your pages.
  • Featured Snippets: Google uses structured data to identify content that may be featured in rich results, which include rich snippets and featured snippets. Featured snippets are the summary or answer that appears at the top of SERP and can drive a lot of traffic to your website.

Overall, structured data markup is a way to improve how search engines understand the meaning of your website’s content, which can lead to better visibility and ranking in search engine results pages.

JSON-LD

JSON-LD (JavaScript Object Notation for Linked Data) is a method of encoding linked data using the JSON format. It is a lightweight and easy-to-use format that allows you to add structured data to your website’s HTML without having to modify the existing HTML code. This makes it an ideal solution for adding structured data to your website.

JSON-LD is preferred by Google search engine because it allows them to easily extract and process the structured data. JSON-LD is also preferred over other formats like Microdata and RDFa because it allows the data to be embedded directly into the HTML document, making it easier for search engines to find and understand the structured data.

When using JSON-LD, the structured data is added in a script tag in the head of the HTML document, which makes it easy to separate from the presentation of the page. This means that the structured data is less likely to be affected by changes to the website’s design or layout.

Google's Structured Data Testing Tool can help you to check if your structured data is implemented correctly and also detect any errors or warnings in the code.

In summary, JSON-LD is a format for adding structured data to a website that is preferred by Google search engine because it is easy to extract and process and it is less likely to be affected by changes to the website’s design or layout.

Implementing JSON-LD with HUGO

Snippets of JSON-LD code are available on the Google SEO starter guide.

JSON-LD for Equipment (or Products)

Each equipment page (see full list here) includes a JSON-LD script. At the end of equipment/single.html I’ve included the following JSON-LD script:

{{ define "JSON-LD" }}
<script type="application/ld+json">
    {
      "@context": "https://schema.org/",
      "@type": "Product",
      "name": "{{.Title}}",
      {{- with .Resources.ByType "image" }}
      "image":[
        {{- range $index, $element := . -}}
        {{- if ne $index 0 -}}, {{ end }}
        {{- printf "%s" (absURL . ) -}}
        {{ end -}}
       ],
       {{- end}}
      "description": "{{.Params.description}}",
      {{- with .Params.sku}}
      "sku": "{{ . }}",
      {{- end}}
      {{- with .Params.mpn}}
      "mpn": "{{ . }}",
      {{- end}}
      {{- with .Params.brand}}
      "brand": {
        "@type": "Brand",
        "name": "{{ . }}"
      },
      {{- end}}
      "offers": {
        "@type": "Offer",
        "url": {{.Permalink}},
        "priceCurrency": "{{.Params.currency}}",
        "price": "{{.Params.rateOneDay}}",
        "itemCondition": {{.Params.itemCondition}},
        "availability": {{.Params.availability}}
      }
    }
  </script>
{{ end }}

If you want to visualise how this is rendered with the inspector, you should run the Hugo server in dev mode, rather than in production mode, because in production mode the code is minified.

In order to include this bit of code in each page we need to add it in baseof.html with {{- block "JSON-LD" . }}{{- end }}:

<!DOCTYPE html>
<html lang="{{ .Language.Lang }}" class="no-js">
  <html>
    <head>
      {{- partial "head.html" . -}}
      {{- partial "json-ld.html" . -}}
      {{- block "JSON-LD" . }}{{- end }}
    </head>

    <body>
      <header>{{- partial "header.html" . -}}</header>
      <main>{{- block "main" . }}{{- end }}</main>
      <footer>{{- partial "footer.html" . -}}</footer>
      {{ partial "script-footer" . }}
    </body>
  </html>
</html>

If we inspect the page we can find the bit of JSON-LD in the <head>:

browser inspector

This is the rendered JSON-LD script:

{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Smallrig 2056 Top Plate for Canon C200",
  "image": [
    "images/Smallrig 2056 Top Plate for Canon C200 front.jpg",
    "images/Smallrig 2056 Top Plate for Canon C200.jpg"
  ],
  "description": "SmallRig 2056 (SR2056) Top Plate for Canon C200. SmallRig Top Plate 2056 is specifically designed for Canon C200 Camera.",
  "sku": "1",
  "brand": { "@type": "Brand", "name": "SmallRig" },
  "offers": {
    "@type": "Offer",
    "url": "http://localhost:1313/equipment/accessories/smallrig-2056-top-plate-for-canon-c200/",
    "priceCurrency": "GBP",
    "price": "3",
    "itemCondition": "https://schema.org/UsedCondition",
    "availability": "https://schema.org/InStock"
  }
}

The JSON-LD code above retrieves all the information from the markdown index.md pages corresponding to each product (see folder structure):

---
title: "Smallrig 2056 Top Plate for Canon C200"
date: 2022-11-26T13:01:33Z
draft: false

description: SmallRig 2056 (SR2056) Top Plate for Canon C200. SmallRig Top Plate 2056 is specifically designed for Canon C200 Camera. 
summary: SmallRig 2056 (SR2056) Top Plate for Canon C200. SmallRig Top Plate 2056 is specifically designed for Canon C200 Camera. 

equipmentTypes : [accessories]
usesEquipmentTypes: []
compatibleWith: []
externalURL: https://fatllama.com/rentals/longstanton/hire-smallrig-2056-top-plate-for-canon-c200-36309605

currency: GBP
rateOneDay: 3
rateSevenDays: 1.71
rateMonth: 1.20
itemCondition: https://schema.org/UsedCondition
availability: https://schema.org/InStock 
sku: 1
mpn: 
brand: SmallRig
numberAvailable: 1

---
- SmallRig 2056 Top Plate For Canon C200.

This is mainly done with {{- with .Params.parameter_name}}.

This bit of code looks for all image resources inside the folder of the specific product, the folder where the current markdown file is located. {{- with .Resources.ByType "image"}} lists all images inside this folder. You can find more information on how to list page resources with Hugo here.

The code under […] takes care of listing the images with an appropriate management of comas. If we are listing the first image filename there shouldn’t be any coma. The filename is printed with {{ printf "%s" . }}.

      {{- with .Resources.ByType "image" }}
      "image":[
        {{- range $index, $element := . -}}
        {{- if ne $index 0 -}}, {{ end }}
        {{- printf "%s" (absURL . ) -}}
        {{ end -}}
       ],
       {{- end}}

Dealing with weird characters in the description

If you see weird characters in the description, use Plain in "description": "{{ . Plain }}",.