Subsections of Publishing

Deployment Scenarios

Offline Usage

The theme is usable offline. No internet connection is required to load your page. This is achieved by storing all dependencies within the theme.

No calls to 3rd party servers, no calling home, no tracking. Privacy friendly.

Server Deployment

If your server deployment has no special requirements, you can skip this section and use the standard Hugo options.

For special requirements, the theme is capable of different scenarios, requiring the following mandatory settings in your hugo.toml. All settings not mentioned in the examples below can be set to your liking.

Public Web Server from Root

hugo.
baseURL = 'https://example.com/'
baseURL: https://example.com/
{
   "baseURL": "https://example.com/"
}

Public Web Server from Subdirectory

hugo.
baseURL = 'https://example.com/mysite/'
relativeURLs = false
baseURL: https://example.com/mysite/
relativeURLs: false
{
   "baseURL": "https://example.com/mysite/",
   "relativeURLs": false
}

If you are still using Hugo’s relref shortcode (which you shouldn’t), you will need further configuration.

Warning

Don’t use a baseURL with a subdirectory and relativeURLs=true together. Hugo doesn’t apply the baseURL correctly in this case. If you need both, generate your site twice with different settings into separate directories.

Private Web Server (LAN)

The same settings as with any of the public web server scenarios or

hugo.
baseURL = '/'
relativeURLs = true
baseURL: /
relativeURLs: true
{
   "baseURL": "/",
   "relativeURLs": true
}

File System

Your generated site can be used headless without a HTTP server.

This can be achieved by using the file:// protocol in your browser’s address bar or by double click on a generated *.html file in your file navigation tool.

Use the following settings

hugo.
baseURL = '/'
relativeURLs = true
baseURL: /
relativeURLs: true
{
   "baseURL": "/",
   "relativeURLs": true
}
Note

Pages like sitemap.xml and rss.xml, and social media links will always use absolute URLs. They won’t work with relativeURLs=true.

GDPR & Cookie Consent

The theme will store information in the reader’s browser. Those are essential information and are considered to fall under the exception clause in DIRECTIVE 2002/58/EC OF THE EUROPEAN PARLIAMENT AND OF THE COUNCIL, Art. 5(3).

This shall not prevent any technical storage or access for the sole purpose of carrying out the transmission of a communication over an electronic communications network, or as strictly necessary in order for the provider of an information society service explicitly requested by the subscriber or user to provide the service.

Stored Theme Information

The theme stores the following information in localstorage or sessionstorage.

  • The scroll position of the content area to be restored on browser back navigation.

    This cannot be turned off.

  • Selected tab of a tab group to apply the selection to other tab groups on the present page and all following presented pages.

    This cannot be turned off.

  • Currently applicable search term to carry over to the following presented pages. This will be used to mark the search term in the page’s text.

    This can be turned off by disabling search.

  • Visited pages to show a check mark in the menu if the page was previously visited.

    This can be turned off by disabling the history.

  • The selected theme variant to carry over to the following presented pages.

    This can be turned off by only having one theme variant configured.

Stored Third Party Information

The theme is not responsible for stored information of third-party-dependencies (every library stored in subdirectories of assets/js/).

Because the theme stores only essential information, it does not provide a mechanism to implement stricter data protection regulations.

Nevertheless you can achieve this by using a library or implementing a storage proxy yourself.

Stable Output

Disabling the Generator Meta

Option The theme adds a meta tag with its version number to each page.

This isn’t a security risk and helps us support you better.

To turn this off, set disableGeneratorVersion=true.

hugo.
[params]
  disableGeneratorVersion = true
params:
  disableGeneratorVersion: true
{
   "params": {
      "disableGeneratorVersion": true
   }
}

If you also want to turn off Hugo’s version meta tag, use disableHugoGeneratorInject=true.

Disabling IDs for Referenced Assets

Option The theme puts a hash of each referenced asset’s content into its file name to make browsers not keep outdated cached assets.

As the hash only changes once the asset itself changes, a rebuild of unchanged content results in unchanged file names. You only need to switch this off if your setup can not deal with file names that change at all.

To disable this, set disableAssetsBusting=true.

hugo.
[params]
  disableAssetsBusting = true
params:
  disableAssetsBusting: true
{
   "params": {
      "disableAssetsBusting": true
   }
}

Disabling IDs for Interactive HTML Elements

Option Features like expanders, notices, and tabs use unique IDs to work. These IDs change with each build.

This is necessary for the theme to work properly, but it can make comparing outputs between builds difficult.

To turn this off, set disableRandomIds=true. Note, that this will result in a non-functional site!.

hugo.
[params]
  disableRandomIds = true
params:
  disableRandomIds: true
{
   "params": {
      "disableRandomIds": true
   }
}

Disabling Assets Minification

Option If minify=true, further theme assets will be minified during build. If no value is set, the theme will avoid minification if you have started with hugo server and otherwise will minify.

hugo.
[params]
  minify = false
params:
  minify: false
{
   "params": {
      "minify": false
   }
}

SBOM

The theme ships a CycloneDX 1.6 SBOM at sbom.cdx.json, listing every third-party resource it can publish with your site, each with a license, a SHA-256 digest of the files the theme ships and - where upstream publishes them - a version and a package URL.

A component vendored as a single file carries that file’s checksum in hashes. One vendored as a directory, or under several paths, has no single artifact to describe, so it carries one digest over every file it holds, across all its paths, as a relearn:treehash property instead - a directory holding only one file included, because that digest covers the names as well as the bytes and a rename inside the directory has to move the document. Some carry no version or package URL at all, because upstream publishes none.

Checksums describe the vendored file

A hashes entry is the digest of the file as this theme ships it, which for most components is a minified build rather than the artifact the purl names. Fetching the package the coordinate points at and comparing digests will therefore not match, and that is expected rather than a sign of tampering. Use the checksum to verify the copy you received from the theme; use the purl to look the component up.

Getting It

The file is part of the theme however you installed it, and is attached to each GitHub release

curl -LO https://github.com/McShelby/hugo-theme-relearn/releases/download/<version>/sbom.cdx.json
curl -LO https://github.com/McShelby/hugo-theme-relearn/releases/latest/download/sbom.cdx.json

It is not copied into your generated site. Nothing is served from your domain unless you put it there yourself.

Verifying It

Releases attach a signed build provenance attestation to the file, recording which workflow produced it and from which commit. If you have the GitHub CLI

gh attestation verify sbom.cdx.json --repo McShelby/hugo-theme-relearn

A copy that has been altered after the release, or that never came from this repository, fails the check. Attestations are looked up by the file’s digest, so an altered copy typically fails by no attestation being found at all.

Using It for Your Own Site

This document describes the theme, not your site

It lists everything the theme is able to publish, while your site publishes only what it uses - a site with no diagrams ships no Mermaid. It also says nothing about Hugo, your other modules, or your own content and assets.

Treat it as one input to your site’s SBOM rather than as the finished document. Rather than copying its components into yours, reference it by BOM-Link, built from the UUID inside the document’s own serialNumber - that is, the field with its urn:uuid: prefix stripped - plus its version

{
  "type": "bom",
  "url": "urn:cdx:<uuid>/<version>"
}

Stability

The serial number and timestamp are derived rather than taken from a random number generator and the clock, so regenerating a given release produces the same bytes and a BOM-Link keeps naming what it named.

The serial number is a UUIDv5 over a digest of the document itself, so it names this exact document: it moves as soon as any component, version or checksum in it moves, and stays put when nothing does. Two documents that differ can therefore never share one BOM-Link.

To recompute it from the file alone, put urn:uuid:00000000-0000-0000-0000-000000000000 back in place of the published serial, serialize the document as JSON without insignificant whitespace, in the key order the file has and with non-ASCII characters written as they are rather than escaped - which is what JavaScript’s JSON.stringify produces - take the SHA-256 of its UTF-8 bytes, and derive the UUIDv5 over pkg:github/mcshelby/hugo-theme-relearn@<theme version>?content=<digest> with the digest in lowercase hex, in the standard URL namespace, where <theme version> is the document’s own metadata.component.version.

The timestamp is the release date recorded in the changelog. The version in the BOM-Link is a different number again: it is CycloneDX’s own revision counter, stays at 1, because a changed document receives a new serial number rather than a new revision of the old one.

What It Covers

Only what a site using the theme publishes. The resources used to build the documentation, develop the theme or run its releases are listed on the credits page but deliberately left out of the SBOM, because your readers never receive them.

Bundles that compile or ship their own dependencies in are listed as single components marked with a relearn:bundled property, and what they contain is not enumerated. Those are the ones to look into if you are auditing licenses: the document does not say what they carry, and a bundle can carry something that is itself a bundle.

Components carrying local modifications record that as CycloneDX pedigree, so a vulnerability match against the upstream coordinate can account for the copy not being pristine.

Content Security Policy

The theme writes no inline JavaScript. Its settings travel as JSON data blocks and all of its code comes from script files, so your site can be served with a strict Content Security Policy.

Policy

This policy covers every feature of the theme except Mermaid

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:

style-src-attr 'unsafe-inline' allows style attributes: the theme writes colors and image sizes given in your content as such, and Hugo colors highlighted code this way unless you set markup.highlight.noClasses=false. If none of this applies, you use no Mermaid and your math output is mathml, you can leave it out: Mermaid and the other math outputs write style attributes as well. Inline <style> elements stay forbidden; the theme writes none.

What Needs More

  • Mermaid: Mermaid writes its styles into inline <style> elements. Add style-src-elem 'self' 'unsafe-inline' - with 'self' repeated, as it replaces style-src for all style elements.
  • Inlined SVGs: an SVG shown with the inlinecontent image effect brings its own <style> elements into the page, if it has any, and needs the same style-src-elem.
  • Libraries from elsewhere: if you set customMermaidURL or customOpenapiURL, add their origin to script-src, and for Swagger UI to style-src as well.
  • Your own inline JavaScript: a javascript: URL as the href of a button, card or topbar button is blocked. Give it an action instead and handle that in a script file.

Subresource Integrity

Set enableSubresourceIntegrity=true to have the theme add an integrity hash to each script and stylesheet it links, including the search index and the stylesheets of the OpenAPI shortcode. A browser then refuses a file that changed after the build.

hugo.
[params]
  enableSubresourceIntegrity = true
params:
  enableSubresourceIntegrity: true
{
   "params": {
      "enableSubresourceIntegrity": true
   }
}
Not for the file system

A browser can not check an integrity hash for a page opened from the file system and refuses the file instead, which leaves the page without any script or style. Keep this off if your site must work that way.