Hugo migration reference for writers
GitLab Docs is migrating from Nanoc to Hugo. This guide describes the required changes you’ll need to make when writing or updating documentation to ensure it builds properly with Hugo.
These changes will be applied automatically to existing content during migration. All new or updated content must follow these formatting requirements after launch.
Formatting changes
Page titles
Page titles move from h1
tags to title
front matter attributes.
For example, on Nanoc, a title is added as an h1
, like this:
---
stage: Systems
group: Cloud Connector
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---
# Cloud Connector: Configuration
A GitLab Rails instance accesses...
For Hugo, move the title into the page’s front matter:
---
stage: Systems
group: Cloud Connector
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
title: Cloud Connector: Configuration
---
A GitLab Rails instance accesses...
Why: Hugo can generate automated listings of pages. For these to work, Hugo needs the page title to be handled more like data than regular content. We are not using these initially, but may do so in the future.
When: Prior to launch, exact timing TBD.
Testing: Error-level Vale rule (see implementation issue).
Shortcodes
Custom Markdown elements are now marked up using Hugo’s shortcode syntax.
Our custom elements are:
- Alert boxes
- History details
- Feature availability details (tier, offering, status)
- GitLab SVG icons
- Tabs
For example, before:
WARNING:
Don't delete your gitlabs!
And after:
{{< alert type="warning" >}}
Don't delete your gitlabs!
{{< /alert >}}
See the Shortcodes reference for syntax and examples.
Why: Shortcodes are the standard Hugo method for creating custom templated bits of content.
When: After launch.
Testing: Shortcodes will be validated on docs pipelines (see implementation issue).
Shortcodes in /help
Shortcodes, like our existing custom Markdown elements, will not render in /help
.
/help
is a built-in set of documentation pages available in GitLab Self-Managed instances
(learn more).
Shortcodes have more verbose syntax, so we’ve modified /help
to hide these
tags and show simplified plain text fallbacks for elements like tabs and alert boxes.
Why: /help
only renders plain Markdown. It is not a static site generator with
functionality to transform content or render templated frontend code.
When: After launch.
Kramdown
Kramdown is no longer supported on the website.
A few example Kramdown tags that exist on the site right now:
{::options parse_block_html="true" /}
{: .alert .alert-warning}
With Hugo, these will no longer have any effect. They will render as plain text.
Why: Hugo uses the Goldmark Markdown rendering engine, not Kramdown.
When: After launch.
Testing: We are running an audit job on the CI pipeline for Kramdown tags (example). These tags will be manually removed as part of launch.
Menu entries in navigation.yaml
-
We have simplified the structure of the
navigation.yaml
file. The valid property names are nowtitle
,url
, andsubmenu
rather than using different property names at each level of the hierarchy.For example, the Nanoc site menu data looks like this:
sections: - section_title: Tutorials section_url: 'ee/tutorials/' section_categories: - category_title: Find your way around GitLab category_url: 'ee/tutorials/gitlab_navigation.html' docs: - doc_title: 'Tutorial: Use the left sidebar to navigate GitLab' doc_url: 'ee/tutorials/left_sidebar/'
For Hugo, it looks like this:
- title: Tutorials url: 'tutorials/' submenu: - title: Find your way around GitLab url: 'tutorials/gitlab_navigation/' submenu: - title: 'Tutorial: Use the left sidebar to navigate GitLab' url: 'tutorials/left_sidebar/'
Why: Using the same property names at each level of the hierarchy significantly simplifies everything we do programmatically with the menu. It also simplifies menu edits for contributors.
-
As part of the change to
prettyURLs
, page paths should no longer include a.html
extension. End each URL with a trailing/
.For example:
# Before - category_title: Find your way around GitLab category_url: 'ee/tutorials/gitlab_navigation.html' # After - title: Find your way around GitLab url: 'tutorials/gitlab_navigation/'
When: Post-launch.
Testing: We various checks on navigation.yaml
in this script,
which runs as a pipeline job when the YAML file is updated.
File naming
Index file names
All files previously named index.md
need to be named _index.md
. For example:
Before:
doc/
├── user/
│ ├── index.md # Must be renamed
│ └── feature/
│ └── index.md # Must be renamed
└── admin/
└── index.md # Must be renamed
After:
doc/
├── user/
│ ├── _index.md # Renamed
│ └── feature/
│ └── _index.md # Renamed
└── admin/
└── _index.md # Renamed
Why: Hugo requires this specific naming convention for section index pages (pages that serve as the main page for a directory). See Hugo’s documentation on Page bundles for more information.
When: Prior to launch, exact timing TBD.
Testing: We will test for this on the pipeline and prevent merges that include an index.md
file (see this issue for details).
Clashing file names
Hugo is configured to use PrettyURLs, which drop the .html
extension from page URLs.
A path clash occurs when two files would render at the same URL, making one of them inaccessible.
# Example 1
- doc/development/project_templates.md
- doc/development/project_templates/index.md
# Resulting URL for both: /development/project_templates/
# Example 2
- doc/user/gitlab_duo_chat.md
- doc/user/gitlab_duo_chat/index.md
# Resulting URL for both: /user/gitlab_duo_chat/
# Example 3
- doc/administration/dedicated/configure_instance.md
- doc/administration/dedicated/configure_instance/index.md
# Resulting URL for both: /administration/dedicated/configure_instance/
Why: Hugo’s options for URL paths are prettyURLs
and uglyURLs
. Both of these produce
somewhat different paths than the Nanoc website does. We’ve opted for prettyURLs
because it’s
Hugo’s default, and Hugo’s pattern for uglyURLs
is different from most other static site generators.
When: Ideally, start avoiding these now because each one requires a manual fix: a rename and a redirect.
Testing: After launch, Hugo will throw an error on docs pipelines if it detects a new path clash.
Processes
Cutting a release
Cutting a release no longer requires updating latest.Dockerfile
. This file no longer exists in
the project, and the release template has been updated accordingly.
Why: We’ve refactored versioning to use the Parallel Deployments feature.
When: First new release after launch.
Monthly chores
The chores rotation will pause when we launch on Hugo.
Why: Some Ruby scripts need to be rewritten in Go, and the maintenance tasks are low-priority enough that we can launch without them. There may be more opportunity post-launch to share more of these scripts with the Handbook project.
Testing: Because we will pause on removing old redirects temporarily, we’ve added a test script to warn if we get near the Pages redirect limit.
When: Post-launch.
User-facing changes
These changes take effect when we launch the new site. They are viewable at https://new.docs.gitlab.com.
Page URLs
-
ee
prefix: We dropped theee
prefix from paths to pages that come from the GitLab project. The prefix was an artifact leftover from when pages were split betweence
andee
, and has been a source of confusion for site visitors. - Pretty URLs: Pages no longer have a
.html
extension in the URL. A file located at/foo/bar/baz.html
is available at/foo/bar/baz
.
We have redirects in place at Cloudflare to redirect all URLs to their new formats. See the redirects documentation in the Hugo project for more information.
Layout changes
We implemented the layout changes proposed in this issue, which aim to improve readability.
The primary changes are:
- Main content column has a maximum width.
- Main content column (which includes the table of contents) is centered, with extra space on either side of it, when the site is viewed on a large screen.
Timeline for all changes
Change | When | Action needed |
---|---|---|
Path clashes | Now | Avoid creating new clashing paths. If possible, remove and redirect existing clashing paths for pages in your groups. |
Kramdown | Now | Do not add new Kramdown tags to page content. |
Page titles1 | TBD; pre-launch | None |
Index file names1 | TBD; pre-launch | None |
Shortcodes1 | Post-launch | None |
Release process | Post-launch | None |
Chores process | Post-launch | None |
Footnotes:
- Timing for these changes on automated pages will differ from standard pages, as they require a more complex set of steps to migrate. See this issue for details.