Subsections of Site Management
Directory Structure
If you’ve followed the Getting Started guide, your directory layout will look similar to this:
βββ content
β βββ log
β β βββ first-day
| | | βββ _index.md
β β βββ second-day
| | | βββ index.md
β β βββ third-day.md
β β βββ _index.md
β βββ _index.md
βββ themes
β βββ hugo-theme-relearn
β βββ ...
βββ hugo.toml
Hugo uses a union file system, which lets you combine multiple directories.
By default, it puts your root directory on top of the Relearn theme directory. Files in your root directory will replace theme files in the same location.
For example, if you create a file at layouts/partials/heading.html
, it will override the theme’s themes/hugo-theme-relearn/layouts/partials/heading.html
.
See this list, to learn which files are allowed to be overridden by you.
This makes it easy to customize the theme without changing files in the themes
directory, making future theme updates simpler.
Warning
Don’t edit files inside the themes/hugo-theme-relearn
directory. That’s not the recommended way to customize! Refer to the explanation above.
Don’t clone the theme repository and edit files there for your site. That’s not the recommended way to customize! Instead, follow the Getting Started guide.
Multilingual
The Relearn theme works with Hugo’s multilingual mode.
It supports many languages, including right-to-left languages.
Supported languages
- Arabic
- Simplified Chinese
- Traditional Chinese
- Czech
- Dutch
- English
- Finnish
- French
- German
- Hindi
- Hungarian
- Indonesian
- Italian
- Japanese
- Korean
- Persian
- Polish
- Portuguese
- Romanian
- Russian
- Spanish
- Swahili
- Turkish
- Ukrainian
- Vietnamese
Translation by File Name
Here’s how to make your site multilingual using translations by file name:
-
Set up languages in your hugo.toml
file:
defaultContentLanguage = 'en'
[languages]
[languages.en]
languageCode = 'en'
languageName = 'English'
title = 'My Website'
weight = 1
[languages.pir]
languageCode = 'art-x-pir'
languageDirection = 'rtl'
languageName = 'Pirrratish'
title = 'Arrr, my Website'
weight = 2
defaultContentLanguage: en
languages:
en:
languageCode: en
languageName: English
title: My Website
weight: 1
pir:
languageCode: art-x-pir
languageDirection: rtl
languageName: Pirrratish
title: Arrr, my Website
weight: 2
{
"defaultContentLanguage": "en",
"languages": {
"en": {
"languageCode": "en",
"languageName": "English",
"title": "My Website",
"weight": 1
},
"pir": {
"languageCode": "art-x-pir",
"languageDirection": "rtl",
"languageName": "Pirrratish",
"title": "Arrr, my Website",
"weight": 2
}
}
}
-
Duplicate your content files and add language codes to their file names:
βββ content
β βββ log
β β βββ first-day
| | | βββ _index.en.md
| | | βββ _index.pir.md
β β βββ second-day
| | | βββ index.en.md
| | | βββ index.pir.md
β β βββ third-day.en.md
β β βββ third-day.pir.md
β β βββ _index.en.md
β β βββ _index.pir.md
β βββ _index.en.md
β βββ _index.pir.md
βββ themes
β βββ hugo-theme-relearn
β βββ ...
βββ hugo.toml
Translation by Content Directory
The theme also support translations by content directory which can be configured in a similar way.
-
Set up languages in your hugo.toml
file:
defaultContentLanguage = 'en'
[languages]
[languages.en]
contentDir = 'content/en'
languageCode = 'en'
languageName = 'English'
title = 'My Website'
weight = 1
[languages.pir]
contentDir = 'content/pir'
languageCode = 'art-x-pir'
languageDirection = 'rtl'
languageName = 'Pirrratish'
title = 'Arrr, my Website'
weight = 2
defaultContentLanguage: en
languages:
en:
contentDir: content/en
languageCode: en
languageName: English
title: My Website
weight: 1
pir:
contentDir: content/pir
languageCode: art-x-pir
languageDirection: rtl
languageName: Pirrratish
title: Arrr, my Website
weight: 2
{
"defaultContentLanguage": "en",
"languages": {
"en": {
"contentDir": "content/en",
"languageCode": "en",
"languageName": "English",
"title": "My Website",
"weight": 1
},
"pir": {
"contentDir": "content/pir",
"languageCode": "art-x-pir",
"languageDirection": "rtl",
"languageName": "Pirrratish",
"title": "Arrr, my Website",
"weight": 2
}
}
}
-
Duplicate your content files into separate directories named by their language code:
βββ content
β βββ en
| β βββ log
| β β βββ first-day
| | | | βββ _index.md
| β β βββ second-day
| | | | βββ index.md
| β β βββ third-day.md
| β β βββ _index.md
| β βββ _index.md
β βββ pir
| β βββ log
| β β βββ first-day
| | | | βββ _index.md
| β β βββ second-day
| | | | βββ index.md
| β β βββ third-day.md
| β β βββ _index.md
| β βββ _index.md
| βββ themes
| β βββ hugo-theme-relearn
| β βββ ...
| βββ hugo.toml
Search Settings
Check the search configuration for multilingual options.
Turn Off Language Switching
Option By default the theme shows a language switcher in the lower part of the menu.
If you want to have more control, where the language switcher is positioned or you want to configure a different icon, see the chapter on sidebar configuration.
To disable the language switcher set disableLanguageSwitchingButton=true
[params]
disableLanguageSwitchingButton = true
params:
disableLanguageSwitchingButton: true
{
"params": {
"disableLanguageSwitchingButton": true
}
}
Versioning
Option The theme offers a way to version your site. This is useful if you want to keep older versions of your site available while also providing links to the current version. Each site version needs to be created separately and is functional independent of each other.
A version switcher will be displayed at the top of the sidebar if versioning is configured. If the user selects a different version, the theme will navigate to the actual page location but in the selected version. If this page does not exist in the selected version, the 404 page will be displayed.
If you want to have more control, where the version switcher is positioned or you want to configure a different icon, see the chapter on sidebar configuration.
Example: Versioning an Existing Site
Assume, you are writing a documentation for an app. At some point you are a releasing a new major version. This new version requires enhanced documentation while the older documentation must still be available for users of the older app version.
This is your intial hugo.toml
file:
baseURL = 'https://example.com/'
baseURL: https://example.com/
{
"baseURL": "https://example.com/"
}
To setup versioning, you have to do the following steps:
- Prepare your old site for versioning.
- add an array of all available
versions
to your hugo.toml
- add information, which of these versions is the latest by setting the
isLatest
option on one item in the versions
array
- add information, which of these versions your site actually is, by setting the
version
option
- change your
baseURL
to the version specific URL
baseURL = 'https://example.com/v1.0/'
[params]
version = 'v1.0'
[[params.versions]]
baseURL = 'https://example.com/'
identifier = 'v2.0'
isLatest = true
title = 'Latest'
[[params.versions]]
baseURL = 'https://example.com/v1.0/'
identifier = 'v1.0'
title = 'v1.0'
baseURL: https://example.com/v1.0/
params:
version: v1.0
versions:
- baseURL: https://example.com/
identifier: v2.0
isLatest: true
title: Latest
- baseURL: https://example.com/v1.0/
identifier: v1.0
title: v1.0
{
"baseURL": "https://example.com/v1.0/",
"params": {
"version": "v1.0",
"versions": [
{
"baseURL": "https://example.com/",
"identifier": "v2.0",
"isLatest": true,
"title": "Latest"
},
{
"baseURL": "https://example.com/v1.0/",
"identifier": "v1.0",
"title": "v1.0"
}
]
}
}
- Generate your old site into the
baseURL
(in our case https://example.com/v1.0/
)
- Copy you Hugo project into a new directory
- Make changes to the documentation for the new version
- Prepare your new site for release.
- leave the previously set array of available
versions
as is
- change the information, which of the versions your site actually is, by setting the
version
option
- change your
baseURL
back to the original URL
baseURL = 'https://example.com/'
[params]
version = 'v2.0'
[[params.versions]]
baseURL = 'https://example.com/'
identifier = 'v2.0'
isLatest = true
title = 'Latest'
[[params.versions]]
baseURL = 'https://example.com/v1.0/'
identifier = 'v1.0'
title = 'v1.0'
baseURL: https://example.com/
params:
version: v2.0
versions:
- baseURL: https://example.com/
identifier: v2.0
isLatest: true
title: Latest
- baseURL: https://example.com/v1.0/
identifier: v1.0
title: v1.0
{
"baseURL": "https://example.com/",
"params": {
"version": "v2.0",
"versions": [
{
"baseURL": "https://example.com/",
"identifier": "v2.0",
"isLatest": true,
"title": "Latest"
},
{
"baseURL": "https://example.com/v1.0/",
"identifier": "v1.0",
"title": "v1.0"
}
]
}
}
- Generate your new site to the chosen location (in our case
https://example.com/
)
A few things to note here:
version
must be an identifier
of one of the entries in the versions
array
- you are not limited with the
baseURL
, these can be absolute or relative to your server root
- you can generate your old versions into the directory of the new version
Example: Add New Versions to a Versioned Site
At some point, your version 2 of the app may be deprecated, too, as you’ve released a new version 3.
You only need to create two versions of your site, the former current one and the new current one.
- Prepare your old site.
- add the new version to the array of available
versions
in your hugo.toml
- revise information, which of these versions is the latest by setting the
isLatest
option on one item in the versions
array
- change your
baseURL
to the version specific URL
baseURL = 'https://example.com/v2.0/'
[params]
version = 'v2.0'
[[params.versions]]
baseURL = 'https://example.com/'
identifier = 'v3.0'
isLatest = true
title = 'Latest'
[[params.versions]]
baseURL = 'https://example.com/v2.0/'
identifier = 'v2.0'
title = 'v2.0'
[[params.versions]]
baseURL = 'https://example.com/v1.0/'
identifier = 'v1.0'
title = 'v1.0'
baseURL: https://example.com/v2.0/
params:
version: v2.0
versions:
- baseURL: https://example.com/
identifier: v3.0
isLatest: true
title: Latest
- baseURL: https://example.com/v2.0/
identifier: v2.0
title: v2.0
- baseURL: https://example.com/v1.0/
identifier: v1.0
title: v1.0
{
"baseURL": "https://example.com/v2.0/",
"params": {
"version": "v2.0",
"versions": [
{
"baseURL": "https://example.com/",
"identifier": "v3.0",
"isLatest": true,
"title": "Latest"
},
{
"baseURL": "https://example.com/v2.0/",
"identifier": "v2.0",
"title": "v2.0"
},
{
"baseURL": "https://example.com/v1.0/",
"identifier": "v1.0",
"title": "v1.0"
}
]
}
}
- Generate your old site into the
baseURL
(in our case https://example.com/v2.0/
)
- Copy you Hugo project into a new directory
- Make changes to the documentation for the new version
- Prepare your new site for release.
- leave the previously set array of available
versions
as is
- change the information, which of the versions your site actually is, by setting the
version
option
- change your
baseURL
back to the original URL
baseURL = 'https://example.com/'
[params]
version = 'v3.0'
[[params.versions]]
baseURL = 'https://example.com/'
identifier = 'v3.0'
isLatest = true
title = 'Latest'
[[params.versions]]
baseURL = 'https://example.com/v2.0/'
identifier = 'v2.0'
title = 'v2.0'
[[params.versions]]
baseURL = 'https://example.com/v1.0/'
identifier = 'v1.0'
title = 'v1.0'
baseURL: https://example.com/
params:
version: v3.0
versions:
- baseURL: https://example.com/
identifier: v3.0
isLatest: true
title: Latest
- baseURL: https://example.com/v2.0/
identifier: v2.0
title: v2.0
- baseURL: https://example.com/v1.0/
identifier: v1.0
title: v1.0
{
"baseURL": "https://example.com/",
"params": {
"version": "v3.0",
"versions": [
{
"baseURL": "https://example.com/",
"identifier": "v3.0",
"isLatest": true,
"title": "Latest"
},
{
"baseURL": "https://example.com/v2.0/",
"identifier": "v2.0",
"title": "v2.0"
},
{
"baseURL": "https://example.com/v1.0/",
"identifier": "v1.0",
"title": "v1.0"
}
]
}
}
- Generate your new site to the chosen location (in our case
https://example.com/
)
A few things to note here:
- you don’t need to recreate version 1 of your site as long as the
baseURL
for the entry marked with isLatest=true
hasn’t changed. The old versions will access the version index of the latest site to display all available versions in the version switcher
Hiding the Deprecation Warning
Option If visitors navigate to an old version of your site, they will see a deprecation warning at the top of each page.
You can disable it be setting the disableVersionWarning
option to true
in your hugo.toml
.
[params]
disableVersionWarning = true
params:
disableVersionWarning: true
{
"params": {
"disableVersionWarning": true
}
}
Change URL of the Version Index
Option The default URL for the version index can be changed with the versionIndexURL
parameter
[params]
versionIndexURL = 'myversionindex.js'
params:
versionIndexURL: myversionindex.js
{
"params": {
"versionIndexURL": "myversionindex.js"
}
}
Note
You only need to change these if you have other own content created for those URLs.
Check for duplicate URLs by running hugo --printPathWarnings
.
Option The theme uses author details in various parts of your site, like RSS feeds and meta tags.
[params]
[params.author]
email = 'santa@example.com'
name = 'Santa Claus'
params:
author:
email: santa@example.com
name: Santa Claus
{
"params": {
"author": {
"email": "santa@example.com",
"name": "Santa Claus"
}
}
}
Site Title
The title
will be used in meta information of your HTML.
title = 'Hugo Relearn Theme'
title: Hugo Relearn Theme
{
"title": "Hugo Relearn Theme"
}
Site Description
Front Matter The theme shows a site description in various places, such as RSS feeds and meta tags. For this, it uses the description
field from your home page’s front matter.
When your page is shared on social media, you can set a site-wide image to display with the link
images = ['images/hero.png']
images:
- images/hero.png
{
"images": [
"images/hero.png"
]
}
The theme adheres to Hugo’s official documentation for Open Graph and Twitter Cards configuration.
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
baseURL = 'https://example.com/'
baseURL: https://example.com/
{
"baseURL": "https://example.com/"
}
Public Web Server from Subdirectory
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
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
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
.
The Relearn theme by default comes with templates for HTML and RSS for each page.
In addition you can configure the below formats.
If this is not enough, learn how to create your own output formats.
Print Support
Enable print support to print entire chapters or the whole site. Add the print
output format to your home, section, and page in hugo.toml
:
[outputs]
home = ['html', 'rss', 'print']
page = ['html', 'rss', 'print']
section = ['html', 'rss', 'print']
outputs:
home:
- html
- rss
- print
page:
- html
- rss
- print
section:
- html
- rss
- print
{
"outputs": {
"home": [
"html",
"rss",
"print"
],
"page": [
"html",
"rss",
"print"
],
"section": [
"html",
"rss",
"print"
]
}
}
By default this adds a printer icon in the topbar but can be deactived. Clicking it switches to print preview, showing the page and its visible subpages in a printer-friendly format. Use your browser’s print function to print or save as PDF.
The URL won’t be configured ugly for Hugo’s URL handling, even with uglyURLs=true
in hugo.toml
. This is because each mime type can only have one suffix.
If you don’t like the URLs, you can reconfigure outputFormats.print
in your hugo.toml
to something other than the default of:
[outputFormats]
[outputFormats.print]
baseName = 'index.print'
isHTML = true
mediaType = 'text/html'
name = 'print'
noUgly = true
permalinkable = false
outputFormats:
print:
baseName: index.print
isHTML: true
mediaType: text/html
name: print
noUgly: true
permalinkable: false
{
"outputFormats": {
"print": {
"baseName": "index.print",
"isHTML": true,
"mediaType": "text/html",
"name": "print",
"noUgly": true,
"permalinkable": false
}
}
}
Markdown Support
Enable support to show the Markdown source of a page. Add the markdown
output format to your home, section, and page in hugo.toml
:
[outputs]
home = ['html', 'rss', 'markdown']
page = ['html', 'rss', 'markdown']
section = ['html', 'rss', 'markdown']
outputs:
home:
- html
- rss
- markdown
page:
- html
- rss
- markdown
section:
- html
- rss
- markdown
{
"outputs": {
"home": [
"html",
"rss",
"markdown"
],
"page": [
"html",
"rss",
"markdown"
],
"section": [
"html",
"rss",
"markdown"
]
}
}
By default this adds a Markdown icon in the topbar but can be deactived. Clicking it switches to the Markdown source including the title of the page.
The markdown
output format configuration is provided by Hugo.
Source Support
Enable support to show the source code of a page if it was generated from a file. Add the source
output format to your home, section, and page in hugo.toml
:
[outputs]
home = ['html', 'rss', 'source']
page = ['html', 'rss', 'source']
section = ['html', 'rss', 'source']
outputs:
home:
- html
- rss
- source
page:
- html
- rss
- source
section:
- html
- rss
- source
{
"outputs": {
"home": [
"html",
"rss",
"source"
],
"page": [
"html",
"rss",
"source"
],
"section": [
"html",
"rss",
"source"
]
}
}
By default this adds a Source icon in the topbar but can be deactived. Clicking it switches to the source code of the page.
The Source output format differs from the Markdown format, as it prints the source code as is including the front matter.
The URL won’t be configured ugly for Hugo’s URL handling, even with uglyURLs=true
in hugo.toml
. This is because each mime type can only have one suffix.
If you don’t like the URLs, you can reconfigure outputFormats.source
in your hugo.toml
to something other than the default of:
[outputFormats]
[outputFormats.source]
baseName = 'index.source'
isHTML = false
mediaType = 'text/markdown'
name = 'source'
noUgly = true
permalinkable = false
outputFormats:
source:
baseName: index.source
isHTML: false
mediaType: text/markdown
name: source
noUgly: true
permalinkable: false
{
"outputFormats": {
"source": {
"baseName": "index.source",
"isHTML": false,
"mediaType": "text/markdown",
"name": "source",
"noUgly": true,
"permalinkable": false
}
}
}
Stable Output
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
.
[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 creates a unique ID for each build and adds it to each referenced asset’s URL to make browsers not keep outdated cached assets.
This is good for production sites but can be problematic during development. It makes comparing outputs difficult as each build has new IDs.
To disable this, set disableAssetsBusting=true
.
[params]
disableAssetsBusting = true
params:
disableAssetsBusting: true
{
"params": {
"disableAssetsBusting": true
}
}
Disabling IDs for Interactive HTML Elements
Option Features like expanders, callouts, 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!.
[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.
{
"params": {
"minify": false
}
}