diff --git a/docs/.cspell.json b/docs/.cspell.json
index f1b2b9b55..a69f88c82 100644
--- a/docs/.cspell.json
+++ b/docs/.cspell.json
@@ -77,7 +77,7 @@
"unmarshaling",
"unmarshals",
// ------------------------------------------------------------------------
- // cspell: ignore hugo terminology",
+ // cspell: ignore hugo terminology
// ------------------------------------------------------------------------
"alignx",
"aligny",
@@ -102,7 +102,7 @@
"unpublishdate",
"zgotmplz",
// ------------------------------------------------------------------------
- // cspell: ignore foreign language words",
+ // cspell: ignore foreign language words
// ------------------------------------------------------------------------
"bezpieczeństwo",
"blatt",
@@ -130,7 +130,7 @@
"referenz",
"régime",
// ------------------------------------------------------------------------
- // cspell: ignore names",
+ // cspell: ignore names
// ------------------------------------------------------------------------
"Atishay",
"Cosette",
@@ -149,8 +149,9 @@
"Vitter",
"WASI",
// ------------------------------------------------------------------------
- // cspell: ignore operating systems and software packages",
+ // cspell: ignore operating systems and software packages
// ------------------------------------------------------------------------
+ "ananke",
"asciidoctor",
"brotli",
"cifs",
@@ -173,7 +174,7 @@
"rclone",
"xubuntu",
// ------------------------------------------------------------------------
- // cspell: ignore miscellaneous",
+ // cspell: ignore miscellaneous
// ------------------------------------------------------------------------
"achristie",
"ccpa",
diff --git a/docs/.github/workflows/lint.yml b/docs/.github/workflows/lint.yml
new file mode 100644
index 000000000..00800ab9f
--- /dev/null
+++ b/docs/.github/workflows/lint.yml
@@ -0,0 +1,61 @@
+name: Lint
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ markdownlint:
+ name: Lint Markdown
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Run Markdown linter
+ uses: DavidAnson/markdownlint-cli2-action@ded1f9488f68a970bc66ea5619e13e9b52e601cd # v23.2.0
+ with:
+ globs: # set to null to override default of *.{md,markdown}
+
+ spellcheck:
+ name: Check spelling
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Check spelling with cspell
+ uses: streetsidesoftware/cspell-action@de2a73e963e7443969755b648a1008f77033c5b2 # v8.4.0
+ with:
+ incremental_files_only: true
+ strict: true
+ # cspell uses the .cspell.json configuration file
+ - name: Check spelling with codespell
+ uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 # v2.2
+ with:
+ check_filenames: true
+ check_hidden: true
+ # codespell uses the .codespellrc file
+
+ template-formatting:
+ name: Check template formatting
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Install Go
+ uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
+ with:
+ go-version: "1.26"
+ check-latest: true
+ cache: true
+ cache-dependency-path: |
+ **/go.sum
+ **/go.mod
+ - name: Install gotmplfmt
+ run: go install github.com/gohugoio/gotmplfmt@623175f49b3d07a11da381ff85228d0d03101880 # v0.4.1
+ - name: Check template formatting
+ run: "diff <(gotmplfmt -d layouts) <(printf '')"
diff --git a/docs/.github/workflows/markdownlint.yml b/docs/.github/workflows/markdownlint.yml
deleted file mode 100644
index ee8bfd4e7..000000000
--- a/docs/.github/workflows/markdownlint.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Lint markdown
-on:
- workflow_dispatch:
- pull_request:
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout repository
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- - name: Run Markdown linter
- uses: DavidAnson/markdownlint-cli2-action@30a0e04f1870d58f8d717450cc6134995f993c63 # v21.0.0
- with:
- globs: # set to null to override default of *.{md,markdown}
- continue-on-error: false
diff --git a/docs/.github/workflows/spellcheck.yml b/docs/.github/workflows/spellcheck.yml
deleted file mode 100644
index 3f402fe78..000000000
--- a/docs/.github/workflows/spellcheck.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: "Check spelling"
-on:
- push:
- pull_request:
- branches-ignore:
- - "dependabot/**"
-
-permissions:
- contents: read
-
-jobs:
- spellcheck:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- - uses: streetsidesoftware/cspell-action@3294df585d3d639e30f3bc019cb11940b9866e95 # v8.0.0
- with:
- incremental_files_only: true
- strict: true
- # cspell uses the .cspell.json configuration file
- - uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 # v2.2
- with:
- check_filenames: true
- check_hidden: true
- # codespell uses the .codespellrc file
diff --git a/docs/.prettierignore b/docs/.prettierignore
index 56e7b90fb..bd712bea1 100644
--- a/docs/.prettierignore
+++ b/docs/.prettierignore
@@ -1,18 +1,3 @@
-# Ignore all SVG icons.
-**/icons.html
-
-# These are whitespace sensitive.
-layouts/_markup/render-code*
-layouts/_markup/render-table*
-layouts/_shortcodes/glossary-term.html
-layouts/_shortcodes/glossary.html
-layouts/_shortcodes/highlighting-styles.html
-layouts/_shortcodes/list-pages-in-section.html
-layouts/_shortcodes/quick-reference.html
-
-# No root node.
-layouts/_partials/layouts/head/head.html
-
# Auto generated.
assets/css/components/chroma*.css
assets/jsconfig.json
diff --git a/docs/.prettierrc b/docs/.prettierrc
index 395ae39af..11c748a86 100644
--- a/docs/.prettierrc
+++ b/docs/.prettierrc
@@ -1,17 +1,5 @@
{
- "plugins": [
- "prettier-plugin-go-template",
- "@awmottaz/prettier-plugin-void-html"
- ],
"overrides": [
- {
- "files": ["*.html"],
- "options": {
- "parser": "go-template",
- "goTemplateBracketSpacing": true,
- "bracketSameLine": true
- }
- },
{
"files": ["*.js", "*.ts"],
"options": {
diff --git a/docs/content/en/_common/configuration/locale.md b/docs/content/en/_common/configuration/locale.md
new file mode 100644
index 000000000..54db1a263
--- /dev/null
+++ b/docs/content/en/_common/configuration/locale.md
@@ -0,0 +1,22 @@
+---
+_comment: Do not remove front matter.
+---
+
+locale
+: (`string`) The language tag as described in [RFC 5646][]. This is the primary value used by the [`language.Translate`][] function to select a translation table, and for localization of dates, currencies, numbers, and percentages, falling back to the [language key][] in both cases.
+
+ Hugo also uses this value to populate:
+
+ - The `lang` attribute of the `html` element in the [embedded alias template][]
+ - The `language` element in the [embedded RSS template][]
+ - The `locale` property in the [embedded Open Graph template][]
+
+ Access this value from a template using the [`Language.Locale`][] method on a `Site` or `Page` object.
+
+ [RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
+ [`Language.Locale`]: /methods/site/language/#locale
+ [`language.Translate`]: /functions/lang/translate/
+ [embedded Open Graph template]: <{{% eturl opengraph %}}>
+ [embedded RSS template]: <{{% eturl rss %}}>
+ [embedded alias template]: <{{% eturl alias %}}>
+ [language key]: /configuration/languages/#language-keys
diff --git a/docs/content/en/_common/configuration/page-matcher.md b/docs/content/en/_common/configuration/page-matcher.md
new file mode 100644
index 000000000..5aa44db8c
--- /dev/null
+++ b/docs/content/en/_common/configuration/page-matcher.md
@@ -0,0 +1,22 @@
+---
+_comment: Do not remove front matter.
+---
+
+A _page matcher_ filters pages by logical path, page kind, environment, or site. Specify filtering criteria using any combination of the following keywords.
+
+environment
+: (`string`) A [glob pattern](g) matching the build [environment](g). For example: `{staging,production}`.
+
+kind
+: (`string`) A [glob pattern](g) matching the [page kind](g). For example: `{taxonomy,term}`.
+
+lang
+: {{< deprecated-in 0.153.0 />}}
+: Use [`sites`](#sites) instead.
+
+path
+: (`string`) A [glob pattern](g) matching the page's [logical path](g). For example: `{/books,/books/**}`.
+
+sites
+: {{< new-in 0.153.0 />}}
+: (`map`) A [sites matrix](g) matching any combination of [content dimensions](g) including language, version, and role.
diff --git a/docs/content/en/_common/functions/fmt/format-string.md b/docs/content/en/_common/functions/fmt/format-string.md
index 09a9ee867..556f378a5 100644
--- a/docs/content/en/_common/functions/fmt/format-string.md
+++ b/docs/content/en/_common/functions/fmt/format-string.md
@@ -2,6 +2,6 @@
_comment: Do not remove front matter.
---
-The documentation for Go's [fmt] package describes the structure and content of the format string.
+The documentation for Go's [`fmt`][] package describes the structure and content of the format string.
-[fmt]: https://pkg.go.dev/fmt
+[`fmt`]: https://pkg.go.dev/fmt
diff --git a/docs/content/en/_common/functions/js/options.md b/docs/content/en/_common/functions/js/options.md
index 837855da3..c0223ef51 100644
--- a/docs/content/en/_common/functions/js/options.md
+++ b/docs/content/en/_common/functions/js/options.md
@@ -18,7 +18,7 @@ params
Note that this is meant for small data sets, e.g., configuration settings. For larger data sets, please put/mount the files into `assets` and import them directly.
minify
-: (`bool`) Whether to minify the generated CSS code. Default is `false`.
+: (`bool`) Whether to minify the generated JS code. Default is `false`.
loaders
: {{< new-in 0.140.0 />}}
diff --git a/docs/content/en/_common/functions/locales.md b/docs/content/en/_common/functions/locales.md
index 1cfd7a1e6..5f7317250 100644
--- a/docs/content/en/_common/functions/locales.md
+++ b/docs/content/en/_common/functions/locales.md
@@ -3,6 +3,7 @@ _comment: Do not remove front matter.
---
> [!note]
-> Localization of dates, currencies, numbers, and percentages is performed by the [gohugoio/locales] package. The language tag of the current site must match one of the listed locales.
+> Localization of dates, currencies, numbers, and percentages is performed by the [`bep/golocales`][] package. Hugo determines the locale using the [`locale`][] configuration setting, falling back to the language key itself. The resolved value must be a locale supported by the package.
-[gohugoio/locales]: https://github.com/gohugoio/locales
+[`bep/golocales`]: https://github.com/bep/golocales
+[`locale`]: /configuration/all/#locale
diff --git a/docs/content/en/_common/installation/01-editions.md b/docs/content/en/_common/installation/01-editions.md
index b68c89975..7bb3db367 100644
--- a/docs/content/en/_common/installation/01-editions.md
+++ b/docs/content/en/_common/installation/01-editions.md
@@ -4,14 +4,19 @@ _comment: Do not remove front matter.
## Editions
-Hugo offers a standard edition with core features, plus extended and extended/deploy editions with more. Use the standard edition unless you need the features below.
+Hugo is available in several editions. Use the standard edition unless you need additional features.
-
+Feature|standard|deploy (1)|extended|extended/deploy
+:--|:-:|:-:|:-:|:-:
+Core features|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
+Direct cloud deployment (2)|:x:|:heavy_check_mark:|:x:|:heavy_check_mark:
+LibSass support (3)|:x:|:x:|:heavy_check_mark:|:heavy_check_mark:
-Feature|extended edition|extended/deploy edition
-:--|:-:|:-:
-[Transpile Sass to CSS] via embedded LibSass. Note that embedded LibSass was deprecated in v0.153.0 and will be removed in a future release. Use the [Dart Sass] transpiler instead, which is compatible with any edition.|:heavy_check_mark:|:heavy_check_mark:
-Deploy your site directly to a Google Cloud Storage bucket, an AWS S3 bucket, or an Azure Storage container. See [details].|:x:|:heavy_check_mark:
+(1) {{< new-in v0.159.2 />}}
+
+(2) Deploy your site directly to a Google Cloud Storage bucket, an AWS S3 bucket, or an Azure Storage container. See [details].
+
+(3) [Transpile Sass to CSS] via embedded LibSass. Note that embedded LibSass was deprecated in v0.153.0 and will be removed in a future release. Use the [Dart Sass] transpiler instead, which is compatible with any edition.
[dart sass]: /functions/css/sass/#dart-sass
[transpile sass to css]: /functions/css/sass/
diff --git a/docs/content/en/_common/installation/04-build-from-source.md b/docs/content/en/_common/installation/04-build-from-source.md
index 47dcd9028..93f1d3a2c 100644
--- a/docs/content/en/_common/installation/04-build-from-source.md
+++ b/docs/content/en/_common/installation/04-build-from-source.md
@@ -4,28 +4,40 @@ _comment: Do not remove front matter.
## Build from source
-To build the extended or extended/deploy edition from source you must:
+To build Hugo from source you must install:
-1. Install [Git]
-1. Install [Go] version 1.25.0 or later
-1. Install a C compiler, either [GCC] or [Clang]
-1. Update your `PATH` environment variable as described in the [Go documentation]
+1. [Git]
+1. [Go] version 1.25.0 or later
-> The install directory is controlled by the `GOPATH` and `GOBIN` environment variables. If `GOBIN` is set, binaries are installed to that directory. If `GOPATH` is set, binaries are installed to the bin subdirectory of the first directory in the `GOPATH` list. Otherwise, binaries are installed to the bin subdirectory of the default `GOPATH` (`$HOME/go` or `%USERPROFILE%\go`).
+### Standard edition
-To build the standard edition:
+To build and install the standard edition:
```sh
-go install github.com/gohugoio/hugo@latest
+CGO_ENABLED=0 go install github.com/gohugoio/hugo@latest
```
-To build the extended edition:
+### Deploy edition
+
+{{< new-in v0.159.2 />}}
+
+To build and install the deploy edition:
+
+```sh
+CGO_ENABLED=0 go install -tags withdeploy github.com/gohugoio/hugo@latest
+```
+
+### Extended edition
+
+To build and install the extended edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
```sh
CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
```
-To build the extended/deploy edition:
+### Extended/deploy edition
+
+To build and install the extended/deploy edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
```sh
CGO_ENABLED=1 go install -tags extended,withdeploy github.com/gohugoio/hugo@latest
@@ -34,5 +46,4 @@ CGO_ENABLED=1 go install -tags extended,withdeploy github.com/gohugoio/hugo@late
[Clang]: https://clang.llvm.org/
[GCC]: https://gcc.gnu.org/
[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
-[Go documentation]: https://go.dev/doc/code#Command
[Go]: https://go.dev/doc/install
diff --git a/docs/content/en/_common/permalink-tokens.md b/docs/content/en/_common/permalink-tokens.md
index fa8308a70..70dee0bca 100644
--- a/docs/content/en/_common/permalink-tokens.md
+++ b/docs/content/en/_common/permalink-tokens.md
@@ -45,11 +45,11 @@ _comment: Do not remove front matter.
`:filename`
: {{< deprecated-in v0.144.0 />}}
-: Use `:contentbasename` instead.
+: Use `:contentbasename` instead.
`:slugorfilename`
: {{< deprecated-in v0.144.0 />}}
-: Use `:slugorcontentbasename` instead.
+: Use `:slugorcontentbasename` instead.
`:contentbasename`
: {{< new-in 0.144.0 />}}
diff --git a/docs/content/en/_common/syntax-highlighting-options.md b/docs/content/en/_common/syntax-highlighting-options.md
index 11348f661..8c390f271 100644
--- a/docs/content/en/_common/syntax-highlighting-options.md
+++ b/docs/content/en/_common/syntax-highlighting-options.md
@@ -12,7 +12,7 @@ guessSyntax
: (`bool`) Whether to automatically detect the language if the `LANG` argument is blank or set to a language for which there is no corresponding [lexer](g). Falls back to a plain text lexer if unable to automatically detect the language. Default is `false`.
> [!note]
- > The Chroma syntax highlighter includes lexers for approximately 250 languages, but only 5 of these have implemented automatic language detection.
+ > The syntax highlighter includes lexers for approximately 300 languages, but only 5 of these have implemented automatic language detection.
hl_Lines
: (`string`) A space-delimited list of lines to emphasize within the highlighted code. To emphasize lines 2, 3, 4, and 7, set this value to `2-4 7`. This option is independent of the `lineNoStart` option.
@@ -45,7 +45,7 @@ noClasses
```
style
-: (`string`) The CSS styles to apply to the highlighted code. Case-sensitive. Default is `monokai`. See [syntax highlighting styles].
+: (`string`) The CSS styles to apply to the highlighted code. This value is case-insensitive. Default is `monokai`. See [syntax highlighting styles][].
tabWidth
: (`int`) Substitute this number of spaces for each tab character in your highlighted code. Irrelevant if `noClasses` is `false`. Default is `4`.
diff --git a/docs/content/en/about/features.md b/docs/content/en/about/features.md
index 4c190eee2..2c75eddf1 100644
--- a/docs/content/en/about/features.md
+++ b/docs/content/en/about/features.md
@@ -80,6 +80,9 @@ weight: 20
## Asset pipelines
+[CSS Processing]
+: Bundle, transform, minify, create source maps, perform SRI hashing, and integrate with PostCSS.
+
[Image processing]
: Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract metadata.
@@ -130,9 +133,10 @@ weight: 20
[Menus]: /content-management/menus/
[URL management]: /content-management/urls/
+[CSS processing]: /functions/css/build/
[Image processing]: /content-management/image-processing/
[JavaScript bundling]: /functions/js/build/
-[Sass processing]: /functions/css/Sass/
+[Sass processing]: /functions/css/sass/
[Tailwind CSS processing]: /functions/css/tailwindcss/
[Caching]: /functions/partials/includecached/
diff --git a/docs/content/en/about/security.md b/docs/content/en/about/security.md
index 509ca6a75..b242bce50 100644
--- a/docs/content/en/about/security.md
+++ b/docs/content/en/about/security.md
@@ -8,6 +8,13 @@ weight: 30
aliases: [/about/security-model/]
---
+## Security Boundaries
+
+- The templates inside `layouts` are trusted.
+- The assets inside `archetypes`, `assets`, `resources`, `data`, `i18n` and `static` are trusted.
+- The content and the content produced by [content adapters][] inside `content` is not trusted. The one exception here is if [inline shortcodes][] is enabled. Note that for content adapters, this is scoped to the result of the adapter.
+- The development server, `hugo server`, and its livereload script is trusted and meant for _local_ development only.
+
## Runtime security
Hugo generates static websites, meaning the final output runs directly in the browser and interacts with any integrated APIs. However, during development and site building, the `hugo` executable itself is the runtime environment.
@@ -16,43 +23,40 @@ Securing a runtime is a complex task. Hugo addresses this through a robust sandb
- Virtual file system: Hugo employs a virtual file system, limiting file access. Only the main project, not external components, can access files or directories outside the project root.
- Read-Only access: User-defined components have read-only access to the file system, preventing unintended modifications.
-- Controlled external binaries: While Hugo utilizes external binaries for features like Asciidoctor support, these are strictly predefined with specific flags and are disabled by default. The [security policy] details these limitations.
+- Controlled external binaries: While Hugo utilizes external binaries for features like Asciidoctor support, these are strictly predefined with specific flags and are disabled by default. The [security policy][] details these limitations.
- No arbitrary commands: To mitigate risks, Hugo intentionally avoids implementing general functions that would allow users to execute arbitrary operating system commands.
+- Pragmatic defaults: The default [security policy][] aims to balance security and usability, enabling common workflows out of the box while keeping more sensitive capabilities opt-in. These defaults may be tightened in future releases, but each project is ultimately responsible for reviewing the policy and adjusting it to match its own trust model and requirements.
This combination of sandboxing and strict defaults effectively minimizes potential security vulnerabilities during the Hugo build process.
-[security policy]: /configuration/security/
-
## Dependency security
-Hugo utilizes [Go Modules] to manage its dependencies, compiling as a static binary. Go Modules create a `go.sum` file, a critical security feature. This file acts as a database, storing the expected cryptographic checksums of all dependencies, including those required indirectly (transitive dependencies).
+Hugo utilizes [Go Modules][] to manage its dependencies, compiling as a static binary. Go Modules create a `go.sum` file, a critical security feature. This file acts as a database, storing the expected cryptographic checksums of all dependencies, including those required indirectly (transitive dependencies).
-[Hugo Modules], which extend Go Modules' functionality, also produce a `go.sum` file. To ensure dependency integrity, commit this `go.sum` file to your version control. If Hugo detects a checksum mismatch during the build process, it will fail, indicating a possible attempt to [tamper with your project's dependencies].
-
-[Go Modules]: https://go.dev/wiki/Modules#modules
-[Hugo Modules]: /hugo-modules/
-[tamper with your project's dependencies]: https://julienrenaux.fr/2019/12/20/github-actions-security-risk/
+[Hugo Modules][], which extend Go Modules' functionality, also produce a `go.sum` file. To ensure dependency integrity, commit this `go.sum` file to your version control. If Hugo detects a checksum mismatch during the build process, it will fail, indicating a possible attempt to [tamper with your project's dependencies][].
## Web application security
-Hugo's security philosophy is rooted in established security standards, primarily aligning with the threats defined by [OWASP]. For HTML output, Hugo operates under a clear trust model. This model assumes that template and configuration authors, the developers, are trustworthy. However, the data supplied to these templates is inherently considered untrusted. This distinction is crucial for understanding how Hugo handles potential security risks.
+Hugo's security philosophy is rooted in established security standards, primarily aligning with the threats defined by [OWASP][]. For HTML output, Hugo operates under a clear trust model. This model assumes that template and configuration authors, the developers, are trustworthy. However, the data supplied to these templates is inherently considered untrusted. This distinction is crucial for understanding how Hugo handles potential security risks.
-[OWASP]: https://en.wikipedia.org/wiki/OWASP
+To prevent unintended escaping of data that developers know is safe, Hugo provides [`safe`][] functions, such as [`safeHTML`][]. These functions allow developers to explicitly mark data as trusted, bypassing the default escaping mechanisms. This is essential for scenarios where data is generated or sourced from reliable sources. However, an exception exists: enabling [inline shortcodes][]. By activating this feature, you are implicitly trusting the logic within the shortcodes and the data contained within your content files.
-To prevent unintended escaping of data that developers know is safe, Hugo provides [`safe`] functions, such as [`safeHTML`]. These functions allow developers to explicitly mark data as trusted, bypassing the default escaping mechanisms. This is essential for scenarios where data is generated or sourced from reliable sources. However, an exception exists: enabling [inline shortcodes]. By activating this feature, you are implicitly trusting the logic within the shortcodes and the data contained within your content files.
+It's vital to remember that Hugo is a static site generator. This architectural choice significantly reduces the attack surface by eliminating the complexities and vulnerabilities associated with dynamic user input. Unlike dynamic websites, Hugo generates static HTML files, minimizing the risk of real-time attacks. Regarding content, Hugo's default Markdown renderer is [configured to sanitize][] potentially unsafe content. This default behavior ensures that potentially malicious code or scripts are removed or escaped. However, this setting can be reconfigured if you have a high degree of confidence in the safety of your content sources.
-[`safeHTML`]: /functions/safe/html/
-[inline shortcodes]: /content-management/shortcodes/#inline
-
-It's vital to remember that Hugo is a static site generator. This architectural choice significantly reduces the attack surface by eliminating the complexities and vulnerabilities associated with dynamic user input. Unlike dynamic websites, Hugo generates static HTML files, minimizing the risk of real-time attacks. Regarding content, Hugo's default Markdown renderer is [configured to sanitize] potentially unsafe content. This default behavior ensures that potentially malicious code or scripts are removed or escaped. However, this setting can be reconfigured if you have a high degree of confidence in the safety of your content sources.
-
-[configured to sanitize]: /configuration/markup/#rendererunsafe
-
-In essence, Hugo prioritizes secure output by establishing a clear trust boundary between developers and data. By default, it errs on the side of caution, sanitizing potentially unsafe content and escaping data. Developers have the flexibility to adjust these defaults through [`safe`] functions and [configuration options], but they must do so with a clear understanding of the security implications. Hugo's static site generation model further strengthens its security posture by minimizing dynamic vulnerabilities.
-
-[`safe`]: /functions/safe
-[configuration options]: /configuration/security
+In essence, Hugo prioritizes secure output by establishing a clear trust boundary between developers and data. By default, it errs on the side of caution, sanitizing potentially unsafe content and escaping data. Developers have the flexibility to adjust these defaults through [`safe`][] functions and [configuration options][], but they must do so with a clear understanding of the security implications. Hugo's static site generation model further strengthens its security posture by minimizing dynamic vulnerabilities.
## Configuration
See [configure security](/configuration/security/).
+
+[`safe`]: /functions/safe
+[`safeHTML`]: /functions/safe/html/
+[content adapters]: /content-management/content-adapters/
+[configuration options]: /configuration/security
+[configured to sanitize]: /configuration/markup/#rendererunsafe
+[Go Modules]: https://go.dev/wiki/Modules#modules
+[Hugo Modules]: /hugo-modules/
+[inline shortcodes]: /content-management/shortcodes/#inline
+[OWASP]: https://en.wikipedia.org/wiki/OWASP
+[security policy]: /configuration/security/
+[tamper with your project's dependencies]: https://julienrenaux.fr/2019/12/20/github-actions-security-risk/
diff --git a/docs/content/en/commands/hugo.md b/docs/content/en/commands/hugo.md
index ad06ecab3..5d3a3499b 100644
--- a/docs/content/en/commands/hugo.md
+++ b/docs/content/en/commands/hugo.md
@@ -40,7 +40,7 @@ hugo [flags]
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
-h, --help help for hugo
- --ignoreCache ignores the cache directory
+ --ignoreCache ignore the configured file caches
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
-l, --layoutDir string filesystem path to layout directory
--logLevel string log level (debug|info|warn|error)
diff --git a/docs/content/en/commands/hugo_build.md b/docs/content/en/commands/hugo_build.md
index 173cb095e..b9311aa69 100644
--- a/docs/content/en/commands/hugo_build.md
+++ b/docs/content/en/commands/hugo_build.md
@@ -40,7 +40,7 @@ hugo build [flags]
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
-h, --help help for build
- --ignoreCache ignores the cache directory
+ --ignoreCache ignore the configured file caches
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
-l, --layoutDir string filesystem path to layout directory
--logLevel string log level (debug|info|warn|error)
diff --git a/docs/content/en/commands/hugo_mod_npm.md b/docs/content/en/commands/hugo_mod_npm.md
index eafda1768..e9bd9d9b1 100644
--- a/docs/content/en/commands/hugo_mod_npm.md
+++ b/docs/content/en/commands/hugo_mod_npm.md
@@ -41,4 +41,4 @@ hugo mod npm [command] [flags]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Manage modules
-* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project
+* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Merges module Node.js dependencies into an npm workspace
diff --git a/docs/content/en/commands/hugo_mod_npm_pack.md b/docs/content/en/commands/hugo_mod_npm_pack.md
index 8637d7486..4482a4d1e 100644
--- a/docs/content/en/commands/hugo_mod_npm_pack.md
+++ b/docs/content/en/commands/hugo_mod_npm_pack.md
@@ -5,20 +5,18 @@ url: /commands/hugo_mod_npm_pack/
---
## hugo mod npm pack
-Experimental: Prepares and writes a composite package.json file for your project
+Merges module Node.js dependencies into an npm workspace
### Synopsis
-Prepares and writes a composite package.json file for your project.
+Merges Node.js dependencies from all Hugo modules into a "packages/hugoautogen" npm workspace.
-On first run it creates a "package.hugo.json" in the project root if not already there. This file will be used as a template file
-with the base dependency set.
+The merged dependencies are written to packages/hugoautogen/package.json, and the root package.json
+is updated with a "workspaces" entry pointing to "packages/hugoautogen".
-This set will be merged with all "package.hugo.json" files found in the dependency tree, picking the version closest to the project.
+The source entries are read from either package.hugo.json or package.json in the module root, with package.hugo.json taking precedence if both exist.
-This command is marked as 'Experimental'. We think it's a great idea, so it's not likely to be
-removed from Hugo, but we need to test this out in "real life" to get a feel of it,
-so this may/will change in future versions of Hugo.
+See [Node.js dependencies](/hugo-modules/nodejs-dependencies/) for more information.
```
diff --git a/docs/content/en/commands/hugo_server.md b/docs/content/en/commands/hugo_server.md
index 4345fbd7a..ec99b1ac0 100644
--- a/docs/content/en/commands/hugo_server.md
+++ b/docs/content/en/commands/hugo_server.md
@@ -45,13 +45,13 @@ hugo server [command] [flags]
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
-h, --help help for server
- --ignoreCache ignores the cache directory
+ --ignoreCache ignore the configured file caches
-l, --layoutDir string filesystem path to layout directory
--liveReloadPort int port for live reloading (i.e. 443 in HTTPS proxy situations) (default -1)
--minify minify any supported output format (HTML, XML etc.)
-N, --navigateToChanged navigate to changed content file on live browser reload
--noChmod don't sync permission mode of files
- --noHTTPCache prevent HTTP caching
+ --noHTTPCache disable browser caching of pages served by the embedded web server
--noTimes don't sync modification time of files
-O, --openBrowser open the project in a browser after server startup
--panicOnWarning panic on first WARNING log
diff --git a/docs/content/en/configuration/all.md b/docs/content/en/configuration/all.md
index 5cd79a467..36fc4c091 100644
--- a/docs/content/en/configuration/all.md
+++ b/docs/content/en/configuration/all.md
@@ -94,7 +94,7 @@ disableDefaultLanguageRedirect
disableDefaultSiteRedirect
: {{< new-in 0.154.5 />}}
-: (bool) Whether to disable generation of the alias redirect to the [default site](g). When [`defaultContentLanguageInSubdir`][], [`defaultContentRoleInSubdir`][], or [`defaultContentVersionInSubdir`][] is `true`, this prevents the root directory from redirecting to the default site's subdirectory. Conversely, when these are `false`, it prevents the subdirectories from redirecting back to the root. Default is `false`.
+: (`bool`) Whether to disable generation of the alias redirect to the [default site](g). When [`defaultContentLanguageInSubdir`][], [`defaultContentRoleInSubdir`][], or [`defaultContentVersionInSubdir`][] is `true`, this prevents the root directory from redirecting to the default site's subdirectory. Conversely, when these are `false`, it prevents the subdirectories from redirecting back to the root. Default is `false`.
disableHugoGeneratorInject
: (`bool`) Whether to disable injection of a `` tag into the home page. Default is `false`.
@@ -139,7 +139,7 @@ i18nDir
: (`string`) The designated directory for translation tables. Default is `i18n`. {{% module-mounts-note %}}
ignoreCache
-: (`bool`) Whether to ignore the cache directory. Default is `false`.
+: (`bool`) Whether to ignore the configured file caches. Default is `false`.
ignoreFiles
: (`[]string`) A slice of [regular expressions](g) used to exclude specific files from a build. These expressions are matched against the absolute file path and apply to files within the `content`, `data`, and `i18n` directories. For more advanced file exclusion options, see the section on [module mounts][].
@@ -153,14 +153,9 @@ ignoreVendorPaths
imaging
: See [configure imaging][].
-locale
-: (`string`) The site's language tag, conforming to the syntax described in [RFC 5646][]. This value does not affect translations or localization. Hugo uses this value to populate:
-
- - The `language` element in the [embedded RSS template][]
- - The `lang` attribute of the `html` element in the [embedded alias template][]
- - The `og:locale` `meta` element in the [embedded Open Graph template][]
-
- When present in the root of the configuration, this value is ignored if one or more language keys exists. Please specify this value independently for each language key.
+languageCode
+: {{}}
+: Use [`locale`](#locale) instead.
languages
: See [configure languages][].
@@ -168,6 +163,10 @@ languages
layoutDir
: (`string`) The designated directory for templates. Default is `layouts`. {{% module-mounts-note %}}
+{{% include "/_common/configuration/locale.md" %}}
+
+ For a multilingual project, specify this value independently for each language key. See [configure languages][].
+
mainSections
: (`string` or `[]string`) The main sections of a site. If set, the [`MainSections`][] method on the `Site` object returns the given sections, otherwise it returns the section with the most pages.
@@ -420,9 +419,6 @@ Some configuration settings, such as menus and custom parameters, can be defined
[configure ugly URLs]: /configuration/ugly-urls/
[configure versions]: /configuration/versions/
[duration]: https://pkg.go.dev/time#Duration
-[embedded Open Graph template]: <{{% eturl opengraph %}}>
-[embedded RSS template]: <{{% eturl rss %}}>
-[embedded alias template]: <{{% eturl alias %}}>
[module mounts]: /configuration/module/#mounts
[non-spacing marks]: https://www.compart.com/en/unicode/category/Mn
[os.UserCacheDir]: https://pkg.go.dev/os#UserCacheDir
diff --git a/docs/content/en/configuration/cascade.md b/docs/content/en/configuration/cascade.md
index 5616314a8..98320edbe 100644
--- a/docs/content/en/configuration/cascade.md
+++ b/docs/content/en/configuration/cascade.md
@@ -9,9 +9,9 @@ keywords: []
You can configure your site to cascade front matter values to the home page and any of its descendants. However, this cascading will be prevented if the descendant already defines the field, or if a closer ancestor [node](g) has already cascaded a value for the same field through its front matter's `cascade` key.
> [!note]
-> You can also configure cascading behavior within a page's front matter. See [details].
+> You can also configure cascading behavior within a page's front matter. See [details][].
-For example, to cascade a "color" parameter to the home page and all its descendants:
+For example, to cascade the `color` page parameter to all pages:
{{< code-toggle file=hugo >}}
[cascade.params]
@@ -24,51 +24,38 @@ color = 'red'
We deprecated the `_target` front matter key in favor of `target` in v0.156.0 on 2026-02-17. Remove footnote #1 on or after 2027-05-17 (15 months after deprecation).
-->
-The `target`[^1] keyword allows you to target specific pages or [environments](g). For example, to cascade a "color" parameter to pages within the "articles" section, including the "articles" section page itself:
+The `target` key accepts a [page matcher](g) to limit cascaded values to a subset of pages.[^1] If a target is omitted, values cascade to all pages.
-[^1]: The `_target` alias for `target` is deprecated and will be removed in a future release.
+{{% include "/_common/configuration/page-matcher.md" %}}
+
+For example, to cascade the `color` page parameter to the `articles` section and its descendants, but only for the English (`en`) and German (`de`) language sites:
{{< code-toggle file=hugo >}}
[cascade.params]
color = 'red'
[cascade.target]
path = '{/articles,/articles/**}'
+[cascade.target.sites.matrix]
+languages = '{en,de}'
{{< /code-toggle >}}
-Use any combination of these keywords to target pages and/or environments:
-
-environment
-: (`string`) A [glob pattern](g) matching the build [environment](g). For example: `{staging,production}`.
-
-kind
-: (`string`) A [glob pattern](g) matching the [page kind](g). For example: `{taxonomy,term}`.
-
-lang
-: (`string`) A [glob pattern](g) matching the [page language]. For example: `{en,de}`.
-
-path
-: (`string`) A [glob pattern](g) matching the page's [logical path](g). For example: `{/books,/books/**}`.
-
## Array
-Define an array of cascade parameters to apply different values to different targets. For example:
+Define an array of cascade maps to apply different values to different targets. For example:
{{< code-toggle file=hugo >}}
[[cascade]]
[cascade.params]
color = 'red'
[cascade.target]
-path = '/books/**'
-kind = 'page'
-lang = '{en,de}'
+path = '{/articles,/articles/**}'
[[cascade]]
[cascade.params]
color = 'blue'
[cascade.target]
-path = '/films/**'
-kind = 'page'
-environment = 'production'
+path = '{/tutorials,/tutorials/**}'
{{< /code-toggle >}}
+[^1]: The `_target` alias for `target` is deprecated and will be removed in a future release.
+
[details]: /content-management/front-matter/#cascade-1
-[page language]: /methods/page/language/
diff --git a/docs/content/en/configuration/introduction.md b/docs/content/en/configuration/introduction.md
index 7a117ba00..d4cf0dbe2 100644
--- a/docs/content/en/configuration/introduction.md
+++ b/docs/content/en/configuration/introduction.md
@@ -219,6 +219,9 @@ Note that you don't need to be so verbose as in the default setup below; a `_mer
{{< code-toggle file=hugo dataKey="config_helpers.mergeStrategy" skipHeader=true />}}
+> [!note]
+> Hugo can merge map configuration values from modules and themes into the project configuration, but cannot merge slice values. This applies to top-level slice keys such as `menus`, as well as to map keys whose values are slices, such as the per-kind format lists in `outputs`.
+
## Environment variables
You can also configure settings using operating system environment variables:
diff --git a/docs/content/en/configuration/languages.md b/docs/content/en/configuration/languages.md
index b289d8ae5..dff133fa6 100644
--- a/docs/content/en/configuration/languages.md
+++ b/docs/content/en/configuration/languages.md
@@ -59,19 +59,7 @@ languageName
: {{}}
: Use [`label`](#label) instead.
-locale
-: (`string`) The language tag as described in [RFC 5646][]. This is the primary value used by the [`language.Translate`][] function to select a translation table, falling back to the language key if a matching translation table does not exist.
-
- Hugo also uses this value to populate:
-
- - The `lang` attribute of the `html` element in the [embedded alias template][]
- - The `language` element in the [embedded RSS template][]
- - The `locale` property in the [embedded OpenGraph template][]
-
- > [!note]
- > This value does not affect localization of dates, numbers, and currencies, nor does it affect the site's URL structure. These are controlled by the [language key](#language-keys).
-
- Access this value from a template using the [`Language.Locale`][] method on a `Site` or `Page` object.
+{{% include "/_common/configuration/locale.md" %}}
title
: (`string`) The site title for this language. Access this value from a template using the [`Title`][] method on a `Site` object.
@@ -203,15 +191,10 @@ public
[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
[`Language.Direction`]: /methods/site/language/#direction
[`Language.Label`]: /methods/site/language/#label
-[`Language.Locale`]: /methods/site/language/#locale
[`Title`]: /methods/site/title/
[`defaultContentLanguageInSubdir`]: #defaultcontentlanguageinsubdir
[`defaultContentLanguage`]: #defaultcontentlanguage
[`dir`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir
[`disableDefaultSiteRedirect`]: /configuration/all/#disabledefaultsiteredirect
-[`language.Translate`]: /functions/lang/translate/
-[embedded OpenGraph template]: <{{% eturl opengraph %}}>
-[embedded RSS template]: <{{% eturl rss %}}>
-[embedded alias template]: <{{% eturl alias %}}>
-[language keys]: #language-keys
+[language keys]: /configuration/languages/#language-keys
[translating by file name]: /content-management/multilingual/#translation-by-file-name
diff --git a/docs/content/en/configuration/module.md b/docs/content/en/configuration/module.md
index 4f7c98e4e..60b1b979f 100644
--- a/docs/content/en/configuration/module.md
+++ b/docs/content/en/configuration/module.md
@@ -119,6 +119,10 @@ noMounts
noVendor
: (`bool`) Whether to disable vendoring for this import. This setting is restricted to the main project. Default is `false`.
+usePackageJSON
+: {{< new-in 0.159.0 />}}
+: (`string`) Whether to use the import's npm dependencies in [hugo mod npm pack](commands/hugo_mod_npm_pack/). One of `auto` (default), `always` or `never`. When set to `auto`, Hugo will enable this if either there is a Hugo config file (e.g. `hugo.toml`) or a `package.hugo.json` file in the module root.
+
path
: (`string`) The module path, either a valid Go module path (e.g., `github.com/gohugoio/myShortcodes`) or the directory name if stored in the [`themesDir`][].
@@ -135,11 +139,11 @@ version
### Default mounts
-Within a project, if you define a mount to map a file system path to a component path, the corresponding default mount for that component will be removed. This action essentially overwrites the standard, automatic mapping for that specific component with your custom one.
+Defining a mount for a component within a project configuration removes the default mount for that component.
-Within a module, if you define a mount to map a file system path to a component path, all of the default mounts will be removed. Defining a mount at the module level is a more sweeping change, causing all default mappings within that module to be discarded.
+Defining a mount for a component within a module configuration removes all default mounts for that module.
-In either case, if you still need one of the default mounts, you must explicitly add it along with the new mount. Because custom mounts override defaults, any necessary default mappings must be re-added manually after you introduce your custom configuration.
+If you still need any of the default mounts, you must explicitly add them along with the new mount.
These are the default mounts:
@@ -154,10 +158,22 @@ target
disableWatch
: (`bool`) Whether to disable watching in watch mode for this mount. Default is `false`.
+excludeFiles
+: {{< deprecated-in 0.153.0 />}}
+: Use [`files`](#files) instead.
+
files
: {{< new-in 0.153.0 />}}
: (`[]string`) A [glob slice](g) defining the files to include or exclude.
+includeFiles
+: {{< deprecated-in 0.153.0 />}}
+: Use [`files`](#files) instead.
+
+lang
+: {{< deprecated-in 0.153.0 />}}
+: Use [`sites`](#sites) instead.
+
sites
: {{< new-in 0.153.0 />}}
: (`map`) A map to define [sites matrix](g) and [sites complements](g) for the mount. Relevant for `content` and `layouts` mounts, and `static` mounts when in multihost mode. For `static` and `layouts`, only the `matrix` keyword is supported.
diff --git a/docs/content/en/configuration/permalinks.md b/docs/content/en/configuration/permalinks.md
index 49ad35b36..2c9d19223 100644
--- a/docs/content/en/configuration/permalinks.md
+++ b/docs/content/en/configuration/permalinks.md
@@ -6,153 +6,96 @@ categories: []
keywords: []
---
-This is the default configuration:
-
-{{< code-toggle config=permalinks />}}
-
-Define a URL pattern for each top-level section. Each URL pattern can target a given language and/or page kind.
+Use the `permalinks` configuration to define custom URL patterns for your pages. Hugo supports two forms: a map form for simple section-based patterns, and an array form that supports [page matchers](g) for more precise targeting.
> [!note]
> The [`url`] front matter field overrides any matching permalink pattern.
-## Monolingual example
+## Map form
-With this content structure:
-
-```text
-content/
-├── posts/
-│ ├── bash-in-slow-motion.md
-│ └── tls-in-a-nutshell.md
-├── tutorials/
-│ ├── git-for-beginners.md
-│ └── javascript-bundling-with-hugo.md
-└── _index.md
-```
-
-Render tutorials under "training", and render the posts under "articles" with a date-base hierarchy:
+Define URL patterns for each top-level [section](g), keyed by [page kind](g). For example, to configure URL patterns for the `articles` section:
{{< code-toggle file=hugo >}}
[permalinks.page]
-posts = '/articles/:year/:month/:slug/'
-tutorials = '/training/:slug/'
+articles = '/blog/:year/:month/:slug/'
[permalinks.section]
-posts = '/articles/'
-tutorials = '/training/'
+articles = '/blog/'
{{< /code-toggle >}}
-The structure of the published site will be:
-
-```text
-public/
-├── articles/
-│ ├── 2023/
-│ │ ├── 04/
-│ │ │ └── bash-in-slow-motion/
-│ │ │ └── index.html
-│ │ └── 06/
-│ │ └── tls-in-a-nutshell/
-│ │ └── index.html
-│ └── index.html
-├── training/
-│ ├── git-for-beginners/
-│ │ └── index.html
-│ ├── javascript-bundling-with-hugo/
-│ │ └── index.html
-│ └── index.html
-└── index.html
-```
-
-To create a date-based hierarchy for regular pages in the content root:
+To configure permalinks per language, nest the `permalinks` key under the language key:
{{< code-toggle file=hugo >}}
-[permalinks.page]
-'/' = '/:year/:month/:slug/'
+[languages]
+ [languages.de]
+ label = 'Deutsch'
+ locale = 'de-DE'
+ weight = 1
+ [languages.de.permalinks]
+ [languages.de.permalinks.page]
+ articles = '/artikel/:year/:month/:slug/'
+ [languages.de.permalinks.section]
+ articles = '/artikel/'
+ [languages.en]
+ label = 'English'
+ locale = 'en-US'
+ weight = 2
+ [languages.en.permalinks]
+ [languages.en.permalinks.page]
+ articles = '/blog/:year/:month/:slug/'
+ [languages.en.permalinks.section]
+ articles = '/blog/'
{{< /code-toggle >}}
-Use the same approach with taxonomy terms. For example, to omit the taxonomy segment of the URL:
+## Array form
+
+{{< new-in 0.161.0 />}}
+
+Define an array of permalink entries to apply different URL patterns to different subsets of pages. Each entry requires a `pattern` key. Hugo applies the first matching pattern.
+
+The optional `target` key accepts a [page matcher](g). If `target` is omitted, the pattern applies to all pages.
+
+{{% include "/_common/configuration/page-matcher.md" %}}
+
+For example, to apply language-specific URL patterns to the `articles` section page and its leaf pages separately:
{{< code-toggle file=hugo >}}
-[permalinks.term]
-'tags' = '/:slug/'
+[[permalinks]]
+ pattern = '/artikel/'
+ [permalinks.target]
+ path = '{/articles}'
+ [permalinks.target.sites]
+ [permalinks.target.sites.matrix]
+ languages = ['de']
+[[permalinks]]
+ pattern = '/artikel/:year/:month/:slug/'
+ [permalinks.target]
+ path = '{/articles/**}'
+ [permalinks.target.sites]
+ [permalinks.target.sites.matrix]
+ languages = ['de']
+[[permalinks]]
+ pattern = '/blog/'
+ [permalinks.target]
+ path = '{/articles}'
+ [permalinks.target.sites]
+ [permalinks.target.sites.matrix]
+ languages = ['en']
+[[permalinks]]
+ pattern = '/blog/:year/:month/:slug/'
+ [permalinks.target]
+ path = '{/articles/**}'
+ [permalinks.target.sites]
+ [permalinks.target.sites.matrix]
+ languages = ['en']
{{< /code-toggle >}}
-## Multilingual example
-
-Use the `permalinks` configuration as a component of your localization strategy.
-
-With this content structure:
-
-```text
-content/
-├── en/
-│ ├── books/
-│ │ ├── les-miserables.md
-│ │ └── the-hunchback-of-notre-dame.md
-│ └── _index.md
-└── es/
- ├── books/
- │ ├── les-miserables.md
- │ └── the-hunchback-of-notre-dame.md
- └── _index.md
-```
-
-And this project configuration:
+To define a fallback that matches any page not already matched by a preceding entry, place a pattern without a `target` key at the end:
{{< code-toggle file=hugo >}}
-defaultContentLanguage = 'en'
-defaultContentLanguageInSubdir = true
-
-[languages.en]
-contentDir = 'content/en'
-direction = 'ltr'
-label = 'English'
-locale = 'en-US'
-weight = 1
-
-[languages.en.permalinks.page]
-books = '/books/:slug/'
-
-[languages.en.permalinks.section]
-books = '/books/'
-
-[languages.es]
-contentDir = 'content/es'
-direction = 'ltr'
-label = 'Español'
-locale = 'es-ES'
-weight = 2
-
-[languages.es.permalinks.page]
-books = '/libros/:slug/'
-
-[languages.es.permalinks.section]
-books = '/libros/'
+[[permalinks]]
+pattern = '/:section/:slug/'
{{< /code-toggle >}}
-The structure of the published site will be:
-
-```text
-public/
-├── en/
-│ ├── books/
-│ │ ├── les-miserables/
-│ │ │ └── index.html
-│ │ ├── the-hunchback-of-notre-dame/
-│ │ │ └── index.html
-│ │ └── index.html
-│ └── index.html
-├── es/
-│ ├── libros/
-│ │ ├── les-miserables/
-│ │ │ └── index.html
-│ │ ├── the-hunchback-of-notre-dame/
-│ │ │ └── index.html
-│ │ └── index.html
-│ └── index.html
-└── index.html
-```
-
## Tokens
Use these tokens when defining a URL pattern.
diff --git a/docs/content/en/configuration/security.md b/docs/content/en/configuration/security.md
index 54342ad51..24da90e7b 100644
--- a/docs/content/en/configuration/security.md
+++ b/docs/content/en/configuration/security.md
@@ -33,8 +33,46 @@ http.mediaTypes
http.urls
: (`[]string`) A slice of [regular expressions](g) matching the URLs that the `resources.GetRemote` function is allowed to access.
-> [!note]
-> Setting an allowlist to the string `none` will completely disable the associated feature.
+node.permissions.disable
+: {{< new-in 0.161.0 />}}
+: (`bool`) Whether to disable the Node.js [permission model]. When `false`, Hugo runs Node.js tools with the `--permission` flag, restricting their file system and resource access to what is explicitly allowed below. Default is `false`.
+
+node.permissions.allowAddons
+: {{< new-in 0.161.0 />}}
+: (`[]string`) A slice of Node.js tool names permitted to load native addons (`--allow-addons`).
+
+node.permissions.allowChildProcess
+: {{< new-in 0.161.0 />}}
+: (`[]string`) A slice of Node.js tool names permitted to spawn child processes (`--allow-child-process`).
+
+node.permissions.allowRead
+: {{< new-in 0.161.0 />}}
+: (`[]string`) A slice of file system paths that Node.js tools are allowed to read (`--allow-fs-read`). Paths are relative to the working directory; `"."` means the working directory itself. Use `"*"` to allow all paths.
+
+node.permissions.allowWorker
+: {{< new-in 0.161.0 />}}
+: (`[]string`) A slice of Node.js tool names permitted to spawn worker threads (`--allow-worker`).
+
+node.permissions.allowWrite
+: {{< new-in 0.161.0 />}}
+: (`[]string`) A slice of file system paths that Node.js tools are allowed to write (`--allow-fs-write`). Paths are relative to the working directory; `"."` means the working directory itself. Use `"*"` to allow all paths.
+
+## Negation rules
+
+{{< new-in 0.161.0 />}}
+
+Any pattern in an allowlist can be negated by prefixing it with an exclamation mark (`!`) and one space to turn it into a deny rule. Deny rules take precedence over allow rules. An allowlist composed entirely of deny rules implicitly allows everything it does not deny. An empty allowlist rejects everything.
+
+For example, to allow all URLs except those pointing to `evil.example.com`:
+
+```toml
+[security.http]
+urls = ['.*', '! ^https?://evil\.example\.com']
+```
+
+Setting an allowlist to the string `none` will completely disable the associated feature.
+
+## Environment variables
You can also override your project configuration with environment variables. For example, to block `resources.GetRemote` from accessing any URL:
@@ -47,4 +85,5 @@ Learn more about [using environment variables] to configure your site.
[`os.Getenv`]: /functions/os/getenv
[`resources.GetRemote`]: /functions/resources/getremote
[inline shortcodes]: /content-management/shortcodes/#inline
+[permission model]: https://nodejs.org/api/permissions.html#permission-model
[using environment variables]: /configuration/introduction/#environment-variables
diff --git a/docs/content/en/content-management/build-options.md b/docs/content/en/content-management/build-options.md
index 0e4d4020b..ea614d304 100644
--- a/docs/content/en/content-management/build-options.md
+++ b/docs/content/en/content-management/build-options.md
@@ -242,7 +242,7 @@ public/
Consider this example. A documentation site has a team of contributors with access to 20 custom shortcodes. Each shortcode takes several arguments, and requires documentation for the contributors to reference when using them.
-Instead of external documentation for the shortcodes, include an "internal" section that is hidden when building the production site.
+Instead of external documentation for the shortcodes, include an `internal` section that is hidden when building the production site.
```text
content/
diff --git a/docs/content/en/content-management/front-matter.md b/docs/content/en/content-management/front-matter.md
index bcb40b077..738cc0ad7 100644
--- a/docs/content/en/content-management/front-matter.md
+++ b/docs/content/en/content-management/front-matter.md
@@ -16,7 +16,7 @@ The front matter at the top of each content file is metadata that:
- Controls the published structure of your site
- Determines template selection
-Provide front matter using a serialization format, one of [JSON], [TOML], or [YAML]. Hugo determines the front matter format by examining the delimiters that separate the front matter from the page content.
+Provide front matter using a serialization format, one of [JSON][], [TOML][], or [YAML][]. Hugo determines the front matter format by examining the delimiters that separate the front matter from the page content.
See examples of front matter delimiters by toggling between the serialization formats below.
@@ -36,78 +36,76 @@ Front matter fields may be [boolean](g), [integer](g), [float](g), [string](g),
The most common front matter fields are `date`, `draft`, `title`, and `weight`, but you can specify metadata using any of fields below.
> [!note]
-> The field names below are reserved. For example, you cannot create a custom field named `type`. Create custom fields under the `params` key. See the [parameters] section for details.
-
-[parameters]: #parameters
+> The field names below are reserved. For example, you cannot create a custom field named `type`. Create custom fields under the `params` key. See the [parameters](#parameters) section for details.
aliases
-: (`[]string`) An array of one or more [page-relative](g) or [site-relative](g) paths that should redirect to the current page. Hugo resolves these to [server-relative](g) URLs during the build process. Access these values from a template using the [`Aliases`] method on a `Page` object. See the [aliases] section for details.
+: (`[]string`) An array of one or more [page-relative](g) or [site-relative](g) paths that should redirect to the current page. Hugo resolves these to [server-relative](g) URLs during the build process. Access these values from a template using the [`Aliases`][] method on a `Page` object. See the [aliases][] section for details.
build
-: (`map`) A map of [build options].
+: (`map`) A map of [build options][].
cascade
-: (`map`) A map (or a slice of maps) of front matter keys whose values are passed down to the page's descendants unless overwritten by self or a closer ancestor's cascade. See the [cascade] section for details.
+: (`map`) A map (or array of maps) of front matter keys whose values are passed down to the page's descendants unless overwritten by self or a closer ancestor's cascade. See the [cascade][] section for details.
date
-: (`string`) The date associated with the page, typically the creation date. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Date`] method on a `Page` object.
+: (`string`) The date associated with the page, typically the creation date. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Date`][] method on a `Page` object.
description
-: (`string`) Conceptually different than the page `summary`, the description is typically rendered within a `meta` element within the `head` element of the published HTML file. Access this value from a template using the [`Description`] method on a `Page` object.
+: (`string`) Conceptually different than the page `summary`, the description is typically rendered within a `meta` element within the `head` element of the published HTML file. Access this value from a template using the [`Description`][] method on a `Page` object.
draft
-: (`bool`) Whether to disable rendering unless you pass the `--buildDrafts` flag to the `hugo` command. Access this value from a template using the [`Draft`] method on a `Page` object.
+: (`bool`) Whether to disable rendering unless you pass the `--buildDrafts` flag to the `hugo` command. Access this value from a template using the [`Draft`][] method on a `Page` object.
expiryDate
-: (`string`) The page expiration date. On or after the expiration date, the page will not be rendered unless you pass the `--buildExpired` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`ExpiryDate`] method on a `Page` object.
+: (`string`) The page expiration date. On or after the expiration date, the page will not be rendered unless you pass the `--buildExpired` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`ExpiryDate`][] method on a `Page` object.
headless
-: (`bool`) Applicable to [leaf bundles], whether to set the `render` and `list` [build options] to `never`, creating a headless bundle of [page resources].
+: (`bool`) Applicable to [leaf bundles][], whether to set the `render` and `list` [build options][] to `never`, creating a headless bundle of [page resources][].
isCJKLanguage
-: (`bool`) Whether the content language is in the [CJK](g) family. This value determines how Hugo calculates word count, and affects the values returned by the [`WordCount`], [`FuzzyWordCount`], [`ReadingTime`], and [`Summary`] methods on a `Page` object.
+: (`bool`) Whether the content language is in the [CJK](g) family. This value determines how Hugo calculates word count, and affects the values returned by the [`WordCount`][], [`FuzzyWordCount`][], [`ReadingTime`][], and [`Summary`][] methods on a `Page` object.
keywords
-: (`[]string`) An array of keywords, typically rendered within a `meta` element within the `head` element of the published HTML file, or used as a [taxonomy](g) to classify content. Access these values from a template using the [`Keywords`] method on a `Page` object.
+: (`[]string`) An array of keywords, typically rendered within a `meta` element within the `head` element of the published HTML file, or used as a [taxonomy](g) to classify content. Access these values from a template using the [`Keywords`][] method on a `Page` object.
lastmod
-: (`string`) The date that the page was last modified. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Lastmod`] method on a `Page` object.
+: (`string`) The date that the page was last modified. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Lastmod`][] method on a `Page` object.
layout
-: (`string`) Provide a template name to [target a specific template], overriding the default [template lookup order]. Set the value to the base file name of the template, excluding its extension. Access this value from a template using the [`Layout`] method on a `Page` object.
+: (`string`) Provide a template name to [target a specific template][], overriding the default [template lookup order][]. Set the value to the base file name of the template, excluding its extension. Access this value from a template using the [`Layout`][] method on a `Page` object.
linkTitle
-: (`string`) Typically a shorter version of the `title`. Access this value from a template using the [`LinkTitle`] method on a `Page` object.
+: (`string`) Typically a shorter version of the `title`. Access this value from a template using the [`LinkTitle`][] method on a `Page` object.
markup
-: (`string`) An identifier corresponding to one of the supported [content formats]. If not provided, Hugo determines the content renderer based on the file extension.
+: (`string`) An identifier corresponding to one of the supported [content formats][]. If not provided, Hugo determines the content renderer based on the file extension.
menus
-: (`string`, `[]string`, or `map`) If set, Hugo adds the page to the given menu or menus. See the [menus] page for details.
+: (`string`, `[]string`, or `map`) If set, Hugo adds the page to the given menu or menus. See the [menus][] page for details.
modified
: Alias to [lastmod](#lastmod).
outputs
-: (`[]string`) The [output formats] to render. See [configure outputs] for more information.
+: (`[]string`) The [output formats][] to render. See [configure outputs][] for more information.
params
-: (`map`) A map of custom [page parameters].
+: (`map`) A map of custom [page parameters][].
pubdate
: Alias to [publishDate](#publishdate).
publishDate
-: (`string`) The page publication date. Before the publication date, the page will not be rendered unless you pass the `--buildFuture` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`PublishDate`] method on a `Page` object.
+: (`string`) The page publication date. Before the publication date, the page will not be rendered unless you pass the `--buildFuture` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`PublishDate`][] method on a `Page` object.
published
: Alias to [publishDate](#publishdate).
resources
-: (`map array`) An array of maps to provide metadata for [page resources].
+: (`map array`) An array of maps to provide metadata for [page resources]. Each element supports the `src`, `name`, `title`, and `params` keys.
sitemap
-: (`map`) A map of sitemap options. See the [sitemap templates] page for details. Access these values from a template using the [`Sitemap`] method on a `Page` object.
+: (`map`) A map of sitemap options. See the [sitemap templates][] page for details. Access these values from a template using the [`Sitemap`][] method on a `Page` object.
sites
: {{< new-in 0.153.0 />}}
@@ -128,28 +126,28 @@ sites
slug
-: (`string`) Overrides the last segment of the URL path. Not applicable to `home`, `section`, `taxonomy`, or `term` pages. See the [URL management] page for details. Access this value from a template using the [`Slug`] method on a `Page` object.
+: (`string`) Overrides the last segment of the URL path. Not applicable to `home`, `section`, `taxonomy`, or `term` pages. See the [URL management][] page for details. Access this value from a template using the [`Slug`][] method on a `Page` object.
summary
-: (`string`) Conceptually different than the page `description`, the summary either summarizes the content or serves as a teaser to encourage readers to visit the page. Access this value from a template using the [`Summary`] method on a `Page` object.
+: (`string`) Conceptually different than the page `description`, the summary either summarizes the content or serves as a teaser to encourage readers to visit the page. Access this value from a template using the [`Summary`][] method on a `Page` object.
title
-: (`string`) The page title. Access this value from a template using the [`Title`] method on a `Page` object.
+: (`string`) The page title. Access this value from a template using the [`Title`][] method on a `Page` object.
translationKey
-: (`string`) An arbitrary value used to relate two or more translations of the same page, useful when the translated pages do not share a common path. Access this value from a template using the [`TranslationKey`] method on a `Page` object.
+: (`string`) An arbitrary value used to relate two or more translations of the same page, useful when the translated pages do not share a common path. Access this value from a template using the [`TranslationKey`][] method on a `Page` object.
type
-: (`string`) The [content type](g), overriding the value derived from the top-level section in which the page resides. Access this value from a template using the [`Type`] method on a `Page` object.
+: (`string`) The [content type](g), overriding the value derived from the top-level section in which the page resides. Access this value from a template using the [`Type`][] method on a `Page` object.
unpublishdate
: Alias to [expirydate](#expirydate).
url
-: (`string`) Overrides the entire URL path. Applicable to regular pages and section pages. See the [URL management] page for details.
+: (`string`) Overrides the entire URL path. Applicable to regular pages and section pages. See the [URL management][] page for details.
weight
-: (`int`) The page [weight](g), used to order the page within a [page collection](g). Access this value from a template using the [`Weight`] method on a `Page` object.
+: (`int`) The page [weight](g), used to order the page within a [page collection](g). Access this value from a template using the [`Weight`][] method on a `Page` object.
## Parameters
@@ -164,15 +162,15 @@ weight = 10
author = 'John Smith'
{{< /code-toggle >}}
-Access these values from a template using the [`Params`] or [`Param`] method on a `Page` object.
+Access these values from a template using the [`Params`][] or [`Param`][] method on a `Page` object.
-Hugo provides [embedded templates] to optionally insert meta data within the `head` element of your rendered pages. These embedded templates expect the following front matter parameters:
+Hugo provides [embedded templates][] to optionally insert meta data within the `head` element of your rendered pages. These embedded templates expect the following front matter parameters:
Parameter|Data type|Used by these embedded templates
:--|:--|:--
-`audio`|`[]string`|[`opengraph.html`]
-`images`|`[]string`|[`opengraph.html`], [`schema.html`], [`twitter_cards.html`]
-`videos`|`[]string`|[`opengraph.html`]
+`audio`|`[]string`|[`opengraph.html`][]
+`images`|`[]string`|[`opengraph.html`][], [`schema.html`][], [`twitter_cards.html`][]
+`videos`|`[]string`|[`opengraph.html`][]
The embedded templates will skip a parameter if not provided in front matter, but will throw an error if the data type is unexpected.
@@ -207,7 +205,7 @@ You can add taxonomy terms to the front matter of any these [page kinds](g):
- `taxonomy`
- `term`
-Access taxonomy terms from a template using the [`Params`] or [`GetTerms`] method on a `Page` object. For example:
+Access taxonomy terms from a template using the [`Params`][] or [`GetTerms`][] method on a `Page` object. For example:
```go-html-template {file="layouts/page.html"}
{{ with .GetTerms "tags" }}
@@ -220,13 +218,14 @@ Access taxonomy terms from a template using the [`Params`] or [`GetTerms`] metho
{{ end }}
```
-[`GetTerms`]: /methods/page/getterms/
-
## Cascade
+> [!note]
+> For multilingual projects, defining cascade values in your project configuration is often more efficient. This avoids repeating the same cascade values for each language. See [details](/configuration/cascade/).
+
A [node](g) can cascade front matter values to its descendants. However, this cascading will be prevented if the descendant already defines the field, or if a closer ancestor node has already cascaded a value for that same field.
-For example, to cascade a "color" parameter from the home page to all its descendants:
+For example, to cascade the `color` page parameter from the home page to all its descendants:
{{< code-toggle file=content/_index.md fm=true >}}
title = 'Home'
@@ -234,47 +233,28 @@ title = 'Home'
color = 'red'
{{< /code-toggle >}}
-{{< new-in 0.153.0 />}}
-From Hugo 0.153.0, you can also set the [sites](#sites) front matter as cascade front matter values, which means that you can e.g. apply one or more languages to the `target` pages.
-
### Target
-The `target`[^1] keyword allows you to target specific pages or [environments](g). For example, to cascade a "color" parameter from the home page only to pages within the "articles" section, including the "articles" section page itself:
+The `target` key accepts a [page matcher](g) to limit cascaded values to a subset of pages.[^1] If a target is not specified, values cascade to all descendant pages.
-[^1]: The `_target` alias for `target` is deprecated and will be removed in a future release.
+{{% include "/_common/configuration/page-matcher.md" %}}
-{{< code-toggle file=content/_index.md fm=true >}}
-title = 'Home'
+For example, to cascade the `color` page parameter from the home page to the `articles` section and its descendants:
+
+{{< code-toggle file=hugo >}}
[cascade.params]
color = 'red'
[cascade.target]
path = '{/articles,/articles/**}'
-[cascade.target.sites.matrix]
-languages = ['en','fr']
{{< /code-toggle >}}
-Use any combination of these keywords to target pages and/or environments:
-
-environment
-: (`string`) A [glob pattern](g) matching the build [environment](g). For example: `{staging,production}`.
-
-kind
-: (`string`) A [glob pattern](g) matching the [page kind](g). For example: `{taxonomy,term}`.
-
-path
-: (`string`) A [glob pattern](g) matching the page's [logical path](g). For example: `{/books,/books/**}`.
-
-sites
-: {{< new-in 0.153.0 />}}
-: (`map`) A map to define [sites matrix](g) for the target, as in: Which sites should receive the cascaded values.
-
### Array
-Define an array of cascade parameters to apply different values to different targets. For example:
+Define an array of cascade maps to apply different values to different targets. For example:
{{< code-toggle file=content/_index.md fm=true >}}
title = 'Home'
@@ -282,24 +262,17 @@ title = 'Home'
[cascade.params]
color = 'red'
[cascade.target]
-path = '{/books/**}'
-kind = 'page'
+path = '{/articles,/articles/**}'
[[cascade]]
[cascade.params]
color = 'blue'
[cascade.target]
-path = '{/films/**}'
-kind = 'page'
+path = '{/tutorials,/tutorials/**}'
{{< /code-toggle >}}
-> [!note]
-> For multilingual projects, defining cascade values in your project configuration is often more efficient. This avoids repeating the same cascade values on the home, section, taxonomy, or term page for each language. See [details](/configuration/cascade/).
->
-> If you choose to define cascade values in front matter for a multilingual project, you must create a corresponding home, section, taxonomy, or term page for every language.
-
## Emacs Org Mode
-If your [content format] is [Emacs Org Mode], you may provide front matter using Org Mode keywords. For example:
+If your [content format][] is [Emacs Org Mode][], you may provide front matter using Org Mode keywords. For example:
```text {file="content/example.org"}
#+TITLE: Example
@@ -319,9 +292,6 @@ Note that you can also specify array elements on a single line:
#+TAGS[]: red blue
```
-[content format]: /content-management/formats/
-[emacs org mode]: https://orgmode.org/
-
## Dates
When populating a date field, whether a [custom page parameter](#parameters) or one of the four predefined fields ([`date`](#date), [`expiryDate`](#expirydate), [`lastmod`](#lastmod), [`publishDate`](#publishdate)), use one of these parsable formats:
@@ -334,6 +304,13 @@ To override the default time zone, set the [`timeZone`](/configuration/all/#time
1. The time zone specified in your project configuration
1. The `Etc/UTC` time zone
+[^1]: The `_target` alias for `target` is deprecated and will be removed in a future release.
+
+[URL management]: /content-management/urls/#slug
+[`GetTerms`]: /methods/page/getterms/
+[`Param`]: /methods/page/param/
+[`Params`]: /methods/page/params/
+[`Summary`]: /methods/page/summary/
[`aliases`]: /methods/page/aliases/
[`date`]: /methods/page/date/
[`description`]: /methods/page/description/
@@ -345,14 +322,11 @@ To override the default time zone, set the [`timeZone`](/configuration/all/#time
[`layout`]: /methods/page/layout/
[`linktitle`]: /methods/page/linktitle/
[`opengraph.html`]: <{{% eturl opengraph %}}>
-[`Param`]: /methods/page/param/
-[`Params`]: /methods/page/params/
[`publishdate`]: /methods/page/publishdate/
[`readingtime`]: /methods/page/readingtime/
[`schema.html`]: <{{% eturl schema %}}>
[`sitemap`]: /methods/page/sitemap/
[`slug`]: /methods/page/slug/
-[`Summary`]: /methods/page/summary/
[`title`]: /methods/page/title/
[`translationkey`]: /methods/page/translationkey/
[`twitter_cards.html`]: <{{% eturl twitter_cards %}}>
@@ -363,7 +337,9 @@ To override the default time zone, set the [`timeZone`](/configuration/all/#time
[build options]: /content-management/build-options/
[cascade]: #cascade-1
[configure outputs]: /configuration/outputs/#outputs-per-page
+[content format]: /content-management/formats/
[content formats]: /content-management/formats/#classification
+[emacs org mode]: https://orgmode.org/
[embedded templates]: /templates/embedded/
[json]: https://www.json.org/
[leaf bundles]: /content-management/page-bundles/#leaf-bundles
@@ -375,5 +351,4 @@ To override the default time zone, set the [`timeZone`](/configuration/all/#time
[target a specific template]: /templates/lookup-order/#target-a-template
[template lookup order]: /templates/lookup-order/
[toml]: https://toml.io/
-[URL management]: /content-management/urls/#slug
[yaml]: https://yaml.org/
diff --git a/docs/content/en/content-management/markdown-attributes.md b/docs/content/en/content-management/markdown-attributes.md
index 42e7bcf94..17533ebfa 100644
--- a/docs/content/en/content-management/markdown-attributes.md
+++ b/docs/content/en/content-management/markdown-attributes.md
@@ -48,10 +48,7 @@ block = true # default is false
## Standalone images
-By default, when the [Goldmark] Markdown renderer encounters a standalone image element (no other elements or text on the same line), it wraps the image element within a paragraph element per the [CommonMark specification].
-
-[CommonMark specification]: https://spec.commonmark.org/current/
-[Goldmark]: https://github.com/yuin/goldmark
+By default, when the [Goldmark][] Markdown renderer encounters a standalone image element (no other elements or text on the same line), it wraps the image element within a paragraph element per the [CommonMark specification][].
If you were to place an attribute list beneath an image element, Hugo would apply the attributes to the surrounding paragraph, not the image.
@@ -64,9 +61,10 @@ wrapStandAloneImageWithinParagraph = false # default is true
## Usage
-You may add [global HTML attributes], or HTML attributes specific to the current element type. Consistent with its content security model, Hugo removes HTML event attributes such as `onclick` and `onmouseover`.
+You may add [global HTML attributes][], or HTML attributes specific to the current element type. Consistent with its content security model, Hugo removes HTML event attributes such as `onclick` and `onmouseover`.
-[global HTML attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
+> [!note]
+> Within fenced code blocks, Hugo interprets the `style` attribute as a syntax highlighting [option][option] rather than a global HTML attribute.
The attribute list consists of one or more key-value pairs, separated by spaces or commas, wrapped by braces. You must quote string values that contain spaces. Unlike HTML, boolean attributes must have both key and value.
@@ -112,6 +110,10 @@ This is a paragraph.
{class=foo}
````
-As shown above, the attribute list for fenced code blocks is not limited to HTML attributes. You can also configure syntax highlighting by passing one or more of [these options](/functions/transform/highlight/#options).
+As shown above, the attribute list for fenced code blocks is not limited to HTML attributes. You can also configure syntax highlighting by passing one or more of [these options][option].
+[CommonMark specification]: https://spec.commonmark.org/current/
+[global HTML attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
+[Goldmark]: https://github.com/yuin/goldmark
[render hook templates]: /render-hooks/introduction/
+[option]: /functions/transform/highlight/#options
diff --git a/docs/content/en/content-management/multilingual.md b/docs/content/en/content-management/multilingual.md
index d3904db71..f8a8fbffe 100644
--- a/docs/content/en/content-management/multilingual.md
+++ b/docs/content/en/content-management/multilingual.md
@@ -29,6 +29,9 @@ Their language is assigned according to the language code added as a suffix to t
By having the same path and base file name, the content pieces are linked together as translated pages.
+> [!note]
+> The language code in a file name must be lowercase. For example, use `about.en-us.md` instead of `about.en-US.md`.
+
> [!note]
> If a file has no language code, it will be assigned the default language.
diff --git a/docs/content/en/content-management/page-bundles.md b/docs/content/en/content-management/page-bundles.md
index a5bf9a3af..4af1ceb61 100644
--- a/docs/content/en/content-management/page-bundles.md
+++ b/docs/content/en/content-management/page-bundles.md
@@ -9,7 +9,7 @@ keywords: []
A page bundle is a directory that encapsulates both content and associated resources.
-By way of example, this site has an "about" page and a "privacy" page:
+By way of example, this site has an `about` page and a `privacy` page:
```text
content/
@@ -19,7 +19,7 @@ content/
└── privacy.md
```
-The "about" page is a page bundle. It logically associates a resource with content by bundling them together. Resources within a page bundle are [page resources], accessible with the [`Resources`] method on the `Page` object.
+The `about` page is a page bundle. It logically associates a resource with content by bundling them together. Resources within a page bundle are [page resources], accessible with the [`Resources`] method on the `Page` object.
Page bundles are either _leaf bundles_ or _branch bundles_.
diff --git a/docs/content/en/content-management/page-resources.md b/docs/content/en/content-management/page-resources.md
index db92734c1..c2a7827aa 100644
--- a/docs/content/en/content-management/page-resources.md
+++ b/docs/content/en/content-management/page-resources.md
@@ -5,9 +5,7 @@ categories: []
keywords: []
---
-Page resources are only accessible from [page bundles](/content-management/page-bundles), those directories with `index.md` or
-`_index.md` files at their root. Page resources are only available to the
-page with which they are bundled.
+Page resources are only accessible from [page bundles][], those directories with `index.md` or`_index.md` files at their root. Page resources are only available to the page with which they are bundled.
In this example, `first-post` is a page bundle with access to 10 page resources including audio, data, documents, images, and video. Although `second-post` is also a page bundle, it has no page resources and is unable to directly access the page resources associated with `first-post`.
@@ -40,7 +38,7 @@ Use any of these methods on a `Page` object to capture page resources:
- [`Resources.GetMatch`]
- [`Resources.Match`]
- Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action.
+ Once you have captured a resource, use any of the applicable [`Resource`][] methods to return a value or perform an action.
The following examples assume this content structure:
@@ -106,22 +104,22 @@ List the titles in the data file, and throw an error if the file does not exist.
## Metadata
-The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm).
+The page resources' metadata is managed from the corresponding page's front matter with an array parameter named `resources`.
> [!note]
> Resources of type `page` get `Title` etc. from their own front matter.
-name
-: (`string`) Sets the value returned in `Name`.
+src
+: (`string`) Required. A [glob pattern](g) matching one or more page resources by file path, relative to the page bundle. Matching is case-insensitive. When the pattern matches multiple resources, the same metadata is applied to each.
-> [!note]
-> The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources.
+name
+: (`string`) Sets the value returned by [`Name`]. Supports the [`:counter`][] placeholder. After assignment, use `name`, not the original file path, with [`Resources.Get`][], [`Resources.Match`][], and [`Resources.GetMatch`][].
title
-: (`string`) Sets the value returned in `Title`
+: (`string`) Sets the value returned by [`Title`][]. Supports the [`:counter`][] placeholder.
params
-: (`map`) A map of custom key-value pairs.
+: (`map`) A map of custom key-value pairs. When multiple array entries match the same resource, their `params` maps are merged; later entries take precedence for duplicate keys.
### Resources metadata example
@@ -134,8 +132,6 @@ resources:
name: header
- src: documents/photo_specs.pdf
title: Photo Specifications
- params:
- icon: photo
- src: documents/guide.pdf
title: Instruction Guide
- src: documents/checklist.pdf
@@ -155,20 +151,18 @@ resources:
From the example above:
- `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`.
-- `documents/photo_specs.pdf` will get the `photo` icon.
-- `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`.
-- Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon.
-- All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`.
-- Every docx in the bundle will receive the `word` icon.
+- `documents/photo_specs.pdf`, `documents/guide.pdf`, `documents/checklist.pdf`, and `documents/payment.docx` will get `Title` as set by `title`.
+- All `PDF` files will get the `pdf` icon and a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`.
+- All `.docx` files will get the `word` icon.
> [!note]
-> The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
+> For `name` and `title`, the first matching array entry wins; later matches are ignored. For `params`, all matching entries contribute; later entries take precedence for duplicate keys. Place more specific `src` patterns before broader wildcards to control which `name` and `title` values are applied.
### The `:counter` placeholder in `name` and `title`
The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`.
-The counter starts at 1 the first time they are used in either `name` or `title`.
+Each unique `src` pattern maintains independent counters for `name` and `title`, each starting at 1 with the first matching resource.
For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as:
@@ -179,24 +173,24 @@ title = 'Engine inspections'
title = 'Specification #:counter'
[[resources]]
src = '**.pdf'
- name = 'pdf-file-:counter'
+ name = 'pdf-file-:counter.pdf'
{{ code-toggle >}}
the `Name` and `Title` will be assigned to the resource files as follows:
-| Resource file | `Name` | `Title` |
-|-------------------|-------------------|-----------------------|
-| checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` |
-| guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` |
-| other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` |
-| photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` |
+| Resource file | `Name` | `Title` |
+|------------------|--------------------|----------------------|
+| checklist.pdf | `"pdf-file-1.pdf"` | `"checklist.pdf"` |
+| guide.pdf | `"pdf-file-2.pdf"` | `"guide.pdf"` |
+| other\_specs.pdf | `"pdf-file-3.pdf"` | `"Specification #1"` |
+| photo\_specs.pdf | `"pdf-file-4.pdf"` | `"Specification #2"` |
## Multilingual
By default, with a multilingual single-host project, Hugo does not duplicate shared page during the build.
> [!note]
-> This behavior is limited to Markdown content. Shared page resources for other [content formats] are copied into each language bundle.
+> This behavior is limited to Markdown content. Shared page resources for other [content formats][] are copied into each language bundle.
Consider this project configuration:
@@ -272,11 +266,11 @@ public/
This approach reduces build times, storage requirements, bandwidth consumption, and deployment times, ultimately reducing cost.
> [!important]
-> To resolve Markdown link and image destinations to the correct location, you must use link and image render hooks that capture the page resource with the [`Resources.Get`] method, and then invoke its [`RelPermalink`] method.
+> To resolve Markdown link and image destinations to the correct location, you must use link and image render hooks that capture the page resource with the [`Resources.Get`][] method, and then invoke its [`RelPermalink`][] method.
>
-> In its default configuration, Hugo automatically uses the [embedded link render hook] and the [embedded image render hook] for multilingual single-host projects, specifically when the [duplication of shared page resources] feature is disabled. This is the default behavior for such projects. If custom link or image render hooks are defined by your project, modules, or themes, these will be used instead.
+> In its default configuration, Hugo automatically uses the [embedded link render hook][] and the [embedded image render hook][] for multilingual single-host projects, specifically when the [duplication of shared page resources][] feature is disabled. This is the default behavior for such projects. If custom link or image render hooks are defined by your project, modules, or themes, these will be used instead.
>
-> You can also configure Hugo to `always` use the embedded link or image render hook, use it only as a `fallback`, or `never` use it. See [details](/configuration/markup/#renderhookslinkuseembedded).
+> You can also configure Hugo to `always` use the embedded link or image render hook, use it only as a `fallback`, or `never` use it. See [details][].
Although duplicating shared page resources is inefficient, you can enable this feature in your project configuration if desired:
@@ -285,13 +279,18 @@ Although duplicating shared page resources is inefficient, you can enable this f
duplicateResourceFiles = true
{{< /code-toggle >}}
+[`:counter`]: #the-counter-placeholder-in-name-and-title
+[`Name`]: /methods/resource/name/
[`RelPermalink`]: /methods/resource/relpermalink/
[`Resource`]: /methods/resource
[`Resources.ByType`]: /methods/page/resources#bytype
-[`Resources.Get`]: /methods/page/resources/#get
[`Resources.GetMatch`]: /methods/page/resources#getmatch
+[`Resources.Get`]: /methods/page/resources/#get
[`Resources.Match`]: /methods/page/resources#match
+[`Title`]: /methods/resource/title/
[content formats]: /content-management/formats/
+[details]: /configuration/markup/#renderhookslinkuseembedded
[duplication of shared page resources]: /configuration/markup/#duplicateresourcefiles
[embedded image render hook]: /render-hooks/images/#embedded
[embedded link render hook]: /render-hooks/links/#embedded
+[page bundles]: /content-management/page-bundles
diff --git a/docs/content/en/content-management/syntax-highlighting.md b/docs/content/en/content-management/syntax-highlighting.md
index 57735b0ab..05c51d559 100644
--- a/docs/content/en/content-management/syntax-highlighting.md
+++ b/docs/content/en/content-management/syntax-highlighting.md
@@ -8,13 +8,10 @@ aliases: [/extras/highlighting/,/extras/highlight/,/tools/syntax-highlighting/]
Hugo provides several methods to add syntax highlighting to code examples:
-- Use the [`transform.Highlight`] function within your templates
-- Use the [`highlight`] shortcode with any [content format](g)
+- Use the [`transform.Highlight`][] function within your templates
+- Use the [`highlight`][] shortcode with any [content format](g)
- Use fenced code blocks with the Markdown content format
-[`transform.Highlight`]: /functions/transform/highlight/
-[`highlight`]: /shortcodes/highlight/
-
## Fenced code blocks
In its default configuration, Hugo highlights code examples within fenced code blocks, following this form:
@@ -29,13 +26,10 @@ CODE
: The code to highlight.
LANG
-: The language of the code to highlight. Choose from one of the [supported languages]. This value is case-insensitive.
+: The language of the code to highlight. Choose from one of the [supported languages][]. This value is case-insensitive. If omitted or unsupported, Hugo renders the text as a plain text block without syntax highlighting. Consistent with the [CommonMark specification][], fenced code blocks require a known language identifier to trigger semantic syntax highlighting.
OPTIONS
-: One or more space-separated or comma-separated key-value pairs wrapped in braces. Set default values for each option in your [project configuration]. The key names are case-insensitive.
-
-[supported languages]: #languages
-[project configuration]: /configuration/markup/#highlight
+: One or more space-separated or comma-separated key-value pairs wrapped in braces. Set default values for each option in your [project configuration][]. The key names are case-insensitive.
For example, with this Markdown:
@@ -95,8 +89,14 @@ Hugo renders this to:
These are the supported languages. Use one of the identifiers, not the language name, when specifying a language for:
-- The [`transform.Highlight`] function
-- The [`highlight`] shortcode
+- The [`transform.Highlight`][] function
+- The [`highlight`][] shortcode
- Fenced code blocks
{{< chroma-lexers >}}
+
+[`highlight`]: /shortcodes/highlight/
+[`transform.Highlight`]: /functions/transform/highlight/
+[CommonMark specification]: https://spec.commonmark.org/0.31.2/#indented-code-blocks
+[project configuration]: /configuration/markup/#highlight
+[supported languages]: #languages
diff --git a/docs/content/en/content-management/taxonomies.md b/docs/content/en/content-management/taxonomies.md
index c8fcf78c1..826f73192 100644
--- a/docs/content/en/content-management/taxonomies.md
+++ b/docs/content/en/content-management/taxonomies.md
@@ -103,13 +103,13 @@ tags_weight = 1000
tags = ['chemistry','science']
{{ code-toggle >}}
-With the front matter above, the "Organic Chemistry" page will float towards the top of the list on section and home pages, and it will sink towards the bottom of the list on the "chemistry" and "science" term pages.
+With the front matter above, the `organic-chemistry` page will float towards the top of the list on section and home pages, and it will sink towards the bottom of the list on the `chemistry` and `science` term pages.
## Metadata
Display metadata about each term by creating a corresponding branch bundle in the `content` directory.
-For example, create an "authors" taxonomy:
+For example, create an `authors` taxonomy:
{{< code-toggle file=hugo >}}
[taxonomies]
@@ -136,7 +136,7 @@ title = 'John Smith'
affiliation = 'University of Chicago'
{{< /code-toggle >}}
-Then create a _taxonomy_ template specific to the "authors" taxonomy:
+Then create a _taxonomy_ template specific to the `authors` taxonomy:
```go-html-template {file="layouts/authors/taxonomy.html"}
{{ define "main" }}
@@ -156,7 +156,7 @@ Then create a _taxonomy_ template specific to the "authors" taxonomy:
In the example above we list each author including their affiliation and portrait.
-Or create a _term_ template specific to the "authors" taxonomy:
+Or create a _term_ template specific to the `authors` taxonomy:
```go-html-template {file="layouts/authors/term.html"}
{{ define "main" }}
diff --git a/docs/content/en/content-management/urls.md b/docs/content/en/content-management/urls.md
index e82ac0c1a..d107b0f87 100644
--- a/docs/content/en/content-management/urls.md
+++ b/docs/content/en/content-management/urls.md
@@ -105,9 +105,7 @@ monolingual|`about`|`https://example.org/about/`
multilingual|`/about`|`https://example.org/about/`
multilingual|`about`|`https://example.org/de/about/`
-#### Permalinks tokens in front matter
-
-{{< new-in 0.131.0 />}}
+#### Tokens
You can also use tokens when setting the `url` value. This is typically used in `cascade` sections:
diff --git a/docs/content/en/contribute/development.md b/docs/content/en/contribute/development.md
index f2168ca78..2860f588a 100644
--- a/docs/content/en/contribute/development.md
+++ b/docs/content/en/contribute/development.md
@@ -29,15 +29,10 @@ For a complete guide to contributing to Hugo, see the [Contribution Guide].
## Prerequisites
-To build the extended or extended/deploy edition from source you must:
+To build Hugo from source you must install:
1. Install [Git]
1. Install [Go] version 1.25.0 or later
-1. Install a C compiler, either [GCC] or [Clang]
-1. Update your `PATH` environment variable as described in the [Go documentation]
-
-> [!note]
-> See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows.
## GitHub workflow
@@ -71,23 +66,29 @@ Step 4
: Make changes.
Step 5
-: Compile and install.
+: Build and install.
- To compile and install the standard edition:
+ To build and install the standard edition:
- ```text
- go install
+ ```sh
+ CGO_ENABLED=0 go install
```
- To compile and install the extended edition:
+ {{< new-in v0.159.2 />}} To build and install the deploy edition:
- ```text
+ ```sh
+ CGO_ENABLED=0 go install -tags withdeploy
+ ```
+
+ To build and install the extended edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
+
+ ```sh
CGO_ENABLED=1 go install -tags extended
```
- To compile and install the extended/deploy edition:
+ To build and install the extended/deploy edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
- ```text
+ ```sh
CGO_ENABLED=1 go install -tags extended,withdeploy
```
@@ -130,46 +131,17 @@ Step 9
Step 10
: A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR.
-## Building from source
-
-You can build, install, and test Hugo at any point in its development history. The examples below build and install the extended edition of Hugo.
-
-To build and install the latest release:
-
-```sh
-CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
-```
-
-To build and install a specific release:
-
-```sh
-CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@v0.158.0
-```
-
-To build and install at the latest commit on the master branch:
-
-```sh
-CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@master
-```
-
-To build and install at a specific commit:
-
-```sh
-CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@c0d9beb
-```
-
-[bugs]: https://github.com/gohugoio/hugo/issues?q=is%3Aopen+is%3Aissue+label%3ABug
[Clang]: https://clang.llvm.org/
-[commit message guidelines]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md#git-commit-message-guidelines
[Contribution Guide]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md
-[create a proposal]: https://github.com/gohugoio/hugo/issues/new?labels=Proposal%2C+NeedsTriage&template=feature_request.md
-[documentation]: /documentation
-[documentation repository]: https://github.com/gohugoio/hugoDocs
-[forum]: https://discourse.gohugo.io
[GCC]: https://gcc.gnu.org/
[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
[Go]: https://go.dev/doc/install
-[Go documentation]: https://go.dev/doc/code#Command
+[bugs]: https://github.com/gohugoio/hugo/issues?q=is%3Aopen+is%3Aissue+label%3ABug
+[commit message guidelines]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md#git-commit-message-guidelines
+[create a proposal]: https://github.com/gohugoio/hugo/issues/new?labels=Proposal%2C+NeedsTriage&template=feature_request.md
+[documentation repository]: https://github.com/gohugoio/hugoDocs
+[documentation]: /documentation
+[forum]: https://discourse.gohugo.io
[issue queue]: https://github.com/gohugoio/hugo/issues
[issues]: https://github.com/gohugoio/hugo/issues
[project repository]: https://github.com/gohugoio/hugo/
diff --git a/docs/content/en/functions/collections/Where.md b/docs/content/en/functions/collections/Where.md
index 40dd78f98..c8e4ae415 100644
--- a/docs/content/en/functions/collections/Where.md
+++ b/docs/content/en/functions/collections/Where.md
@@ -142,7 +142,7 @@ For example, to return a slice of pages where the `color` page parameter is eith
{{ $pages := where $fruit "Params.color" "in" $colors }}
```
-To return a slice of pages where the "color" page parameter is neither "red" nor "yellow":
+To return a slice of pages where the `color` page parameter is neither `red` nor `yellow`:
```go-html-template
{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
@@ -155,7 +155,7 @@ To return a slice of pages where the "color" page parameter is neither "red" nor
Compare a `slice` to a `slice`, returning elements with common values. This is frequently used when comparing taxonomy terms.
-For example, to return a slice of pages where any of the terms in the "genres" taxonomy are "suspense" or "romance":
+For example, to return a slice of pages where any of the terms in the `genres` taxonomy are "suspense" or "romance":
```go-html-template
{{ $books := where site.RegularPages "Section" "eq" "books" }}
@@ -166,7 +166,7 @@ For example, to return a slice of pages where any of the terms in the "genres" t
## Regular expression comparison
-To return a slice of pages where the "author" page parameter begins with either "victor" or "Victor":
+To return a slice of pages where the `author` page parameter begins with either "victor" or "Victor":
```go-html-template
{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }}
diff --git a/docs/content/en/functions/crypto/FNV32a.md b/docs/content/en/functions/crypto/FNV32a.md
deleted file mode 100644
index 03bcc57e7..000000000
--- a/docs/content/en/functions/crypto/FNV32a.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: crypto.FNV32a
-description: Returns the 32-bit FNV (Fowler-Noll-Vo) non-cryptographic hash of the given string.
-categories: []
-keywords: []
-params:
- functions_and_methods:
- aliases: []
- returnType: int
- signatures: [crypto.FNV32a STRING]
-expiryDate: 2026-07-31 # deprecated 2024-07-31 in v0.129.0
----
-
-{{< deprecated-in 0.129.0 >}}
-Use [`hash.FNV32a`] instead.
-
-[`hash.FNV32a`]: /functions/hash/FNV32a/
-{{< /deprecated-in >}}
diff --git a/docs/content/en/functions/css/Build.md b/docs/content/en/functions/css/Build.md
index 932d2c706..30f6d823f 100644
--- a/docs/content/en/functions/css/Build.md
+++ b/docs/content/en/functions/css/Build.md
@@ -12,6 +12,9 @@ params:
{{< new-in 0.158.0 />}}
+> [!note]
+> The `css.Build` function is backed by the [`evanw/esbuild`][] package, providing a mature, high-performance foundation for bundling, transformation, and minification.
+
Use the `css.Build` function to:
- Recursively replace `@import` statements in CSS files with the content of the imported files
@@ -90,7 +93,7 @@ To minify the generated CSS code, use the [`minify`](#minify) option as describe
## Options
-The `css.Build` function takes an optional map of options based on the underlying [`esbuild`] package. Use these options to fine-tune bundling, minification, and browser compatibility.
+The `css.Build` function takes an optional map of options to fine-tune bundling, minification, and browser compatibility.
externals
: (`[]string`) A slice of path patterns to exclude from bundling. The `@import` statements for these patterns remain as-is in the generated CSS code. See [details][esb_external].
@@ -169,6 +172,126 @@ targetPath
{{ $r := resources.Get "css/main.css" | css.Build $opts }}
```
+vars
+: {{< new-in 0.160.0 />}}
+: (`map`) A map of key-value pairs used to generate CSS variables. The `css.Build` function injects these variables into the stylesheet when it encounters the `hugo:vars` internal identifier within an `@import` statement.
+
+ ```go-html-template
+ {{ $vars := dict
+ "font-family" "\"Times New Roman\", Times, serif"
+ "font-size" "24px"
+ "primary-color" "blue"
+ }}
+ {{ $opts := dict "vars" $vars }}
+ {{ $r := resources.Get "css/main.css" | css.Build $opts }}
+ ```
+
+ In the example above, using the identifier in your CSS allows you to access the values using standard CSS variable syntax.
+
+ ```css
+ @import 'hugo:vars';
+
+ .element {
+ color: var(--primary-color);
+ font-family: var(--font-family);
+ font-size: var(--font-size);
+ }
+ ```
+
+ The above produces output equivalent to:
+
+ ```css
+ :root {
+ --font-family:
+ "Times New Roman",
+ Times,
+ serif;
+ --font-size: 24px;
+ --primary-color: blue;
+ }
+
+ .element {
+ color: var(--primary-color);
+ font-family: var(--font-family);
+ font-size: var(--font-size);
+ }
+````
+
+ {{< new-in 0.161.0 />}}
+
+ The map may optionally contain nested maps. Each nested map is exposed as a separate `hugo:vars/` namespace, where `` is the key of the nested map (lowercased). Top-level scalar values and nested maps are independent. A top-level `@import 'hugo:vars'` only includes scalar values, while `@import 'hugo:vars/'` only includes the scalars from the named nested map.
+
+ ```go-html-template
+ {{ $vars := dict
+ "font-family" "\"Times New Roman\", Times, serif"
+ "font-size" "24px"
+ "primary-color" "blue"
+ "mobile" (dict
+ "font-size" "12px"
+ "primary-color" "red"
+ )
+ }}
+ {{ $opts := dict "vars" $vars }}
+ {{ $r := resources.Get "css/main.css" | css.Build $opts }}
+ ```
+
+ Because nested imports follow the same rules as regular `@import` statements, you can attach a media query, feature query, or cascade layer assignment to a `hugo:vars/` import.
+
+ ```css
+ @import 'hugo:vars';
+ @import 'hugo:vars/mobile' (max-width: 650px);
+
+ body {
+ background-color: var(--primary-color);
+ font-family: var(--font-family);
+ }
+ ```
+
+ The above produces output equivalent to:
+
+ ```css
+ :root {
+ --font-family: "Times New Roman", Times, serif;
+ --font-size: 24px;
+ --primary-color: blue;
+ }
+
+ @media (max-width: 650px) {
+ :root {
+ --font-size: 12px;
+ --primary-color: red;
+ }
+ }
+
+ body {
+ background-color: var(--primary-color);
+ font-family: var(--font-family);
+ }
+ ```
+
+ The `vars` option is useful for setting CSS variables within your project configuration.
+
+ {{< code-toggle file=hugo >}}
+ [params.theme.style]
+ font-family = '"Times New Roman", Times, serif'
+ font-size = '24px'
+ primary-color = 'blue'
+
+ [params.theme.style.mobile]
+ font-size = '12px'
+ primary-color = 'red'
+ {{< /code-toggle >}}
+
+ ```go-html-template
+ {{ $opts := dict "vars" site.Params.theme.style }}
+ {{ $r := resources.Get "css/main.css" | css.Build $opts }}
+ ```
+
+ When passing a `vars` map to the `css.Build` function, you can use the [`css.Quoted`][] function to explicitly indicate that a value must be treated as a quoted string, most commonly for `font-family` names or the `content` property.
+
+ > [!note]
+ > If you're using TailwindCSS and want to use the `vars` option to inject CSS variables, see [this section in the TailwindCSS documentation](./TailwindCSS.md#inject-css-variables-with-vars).
+
## Example
The example below uses several of the [options](#options) described above to bundle, transform, and minify CSS code.
@@ -180,6 +303,7 @@ The example below uses several of the [options](#options) described above to bun
"minify" (cond hugo.IsDevelopment false true)
"sourceMap" (cond hugo.IsDevelopment "linked" "none")
"target" (slice "chrome115" "edge115" "firefox116" "ios16.4" "opera101" "safari16.4")
+ "targetPath" "css/styles.css"
}}
{{ with . | css.Build $opts }}
{{ if hugo.IsDevelopment }}
@@ -203,17 +327,6 @@ Using the options above, Hugo does the following:
- Publishes the generated CSS code to `css/styles.css`
- In production, adds an SRI hash and inserts a file hash into the filename
-[`esbuild`]: https://github.com/evanw/esbuild
-[`publishDir`]: /configuration/all/#publishdir
-[browserlist]: https://browsersl.ist
-[esb_external]: https://esbuild.github.io/api/#external
-[esb_loader]: https://esbuild.github.io/api/#loader
-[esb_mainfields]: https://esbuild.github.io/api/#main-fields
-[esb_minify]: https://esbuild.github.io/api/#minify
-[esb_sourcemap]: https://esbuild.github.io/api/#sourcemap
-[esb_sourcesContent]: https://esbuild.github.io/api/#sources-content
-[esb_target]: https://esbuild.github.io/api/#target
-
## Common patterns
The examples below cover the most frequent use cases for referencing resources within your project or within Node packages. These patterns apply to both `@import` statements and the `url()` functional notation used for images and fonts.
@@ -254,3 +367,15 @@ To reference a specific file within a Node package, provide the path starting wi
```css {file="/assets/css/main.css"}
@import "bootstrap/dist/css/bootstrap-grid.css";
```
+
+[`css.Quoted`]: /functions/css/quoted/
+[`evanw/esbuild`]: https://github.com/evanw/esbuild
+[`publishDir`]: /configuration/all/#publishdir
+[browserlist]: https://browsersl.ist
+[esb_external]: https://esbuild.github.io/api/#external
+[esb_loader]: https://esbuild.github.io/api/#loader
+[esb_mainfields]: https://esbuild.github.io/api/#main-fields
+[esb_minify]: https://esbuild.github.io/api/#minify
+[esb_sourcemap]: https://esbuild.github.io/api/#sourcemap
+[esb_sourcesContent]: https://esbuild.github.io/api/#sources-content
+[esb_target]: https://esbuild.github.io/api/#target
diff --git a/docs/content/en/functions/css/Quoted.md b/docs/content/en/functions/css/Quoted.md
index 58784f3e6..a3d32a751 100644
--- a/docs/content/en/functions/css/Quoted.md
+++ b/docs/content/en/functions/css/Quoted.md
@@ -13,13 +13,29 @@ params:
> [!note]
-> This function is only applicable to the [`vars`] option passed to the [`css.Sass`] function.
+> This function is only applicable to the `vars` option passed to the [`css.Build`][] or [`css.Sass`][] functions.
When passing a `vars` map to the `css.Sass` function, Hugo detects common typed CSS values such as `24px` or `#FF0000` using regular expression matching. If necessary, you can bypass automatic type inference by using the `css.Quoted` function to explicitly indicate that the value must be treated as a quoted string.
-For example:
+For the `css.Build` function, use `css.Quoted` to explicitly indicate that a value must be treated as a quoted string, most commonly for `font-family` names or the `content` property.
-```scss {file="assets/sass/main.scss"}
+In the example below, we use `css.Quoted` to ensure the values for the `content` property are injected as strings.
+
+```go-html-template
+{{ $vars := dict
+ "ol-li-after" ("6" | css.Quoted)
+ "ul-li-after" ("7" | css.Quoted)
+}}
+
+{{ $opts := dict "vars" $vars "transpiler" "dartsass" }}
+{{ with resources.Get "sass/main.scss" | css.Sass $opts }}
+
+{{ end }}
+```
+
+Using the `hugo:vars` identifier in your stylesheet:
+
+```scss
@use "hugo:vars" as h;
ol li::after {
@@ -31,35 +47,9 @@ ul li::after {
}
```
-```go-html-template {file="layouts/_partials/css.html"}
-{{ $vars := dict
- "ol_li_after" ("6" | css.Quoted )
- "ul_li_after" ("7" | css.Quoted )
-}}
+The resulting CSS contains quoted strings:
-{{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict
- "enableSourceMap" hugo.IsDevelopment
- "outputStyle" (cond hugo.IsDevelopment "expanded" "compressed")
- "targetPath" "css/main.css"
- "transpiler" "dartsass"
- "vars" $vars
- }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsDevelopment }}
-
- {{ else }}
- {{ with . | fingerprint }}
-
- {{ end }}
- {{ end }}
- {{ end }}
-{{ end }}
-```
-
-The Sass code is transpiled to:
-
-```css {file="public/css/main.css"}
+```css
ol li::after {
content: "6";
}
@@ -69,5 +59,5 @@ ul li::after {
}
```
-[`css.Sass`]: /functions/css/sass/
-[`vars`]: /functions/css/sass/#vars
+[`css.Build`]: /functions/css/build/#vars
+[`css.Sass`]: /functions/css/sass/#vars
diff --git a/docs/content/en/functions/css/Sass.md b/docs/content/en/functions/css/Sass.md
index c5e10772b..3173a5a47 100644
--- a/docs/content/en/functions/css/Sass.md
+++ b/docs/content/en/functions/css/Sass.md
@@ -14,7 +14,7 @@ aliases: [/functions/resources/tocss/]
Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language.
> [!warning]
-> The embedded LibSass transpiler was deprecated in [v0.153.0][] and will be removed in a future release. Use the Dart Sass transpiler instead.
+> The embedded LibSass transpiler was deprecated in [v0.153.0][] and will be removed in a future release. Use the Dart Sass transpiler instead by setting the `transpiler` option to `dartsass` as shown in the examples below.
Sass has two forms of syntax: [SCSS][] and [indented][]. Hugo supports both.
@@ -23,44 +23,215 @@ Sass has two forms of syntax: [SCSS][] and [indented][]. Hugo supports both.
enableSourceMap
: (`bool`) Whether to generate a source map. Default is `false`.
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "enableSourceMap" true
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
includePaths
: (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "includePaths" (slice "node_modules/bootstrap/scss")
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
outputStyle
: (`string`) The output style of the resulting CSS. With LibSass, one of `nested` (default), `expanded`, `compact`, or `compressed`. With Dart Sass, either `expanded` (default) or `compressed`.
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "outputStyle" "compressed"
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
precision
: (`int`) The precision of floating point math. Applicable to LibSass. Default is `8`.
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "precision" 10
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
silenceDeprecations
: {{< new-in 0.139.0 />}}
-: (`slice`) A slice of deprecation IDs to silence. IDs are enclosed in brackets within Dart Sass warning messages (e.g., `import` in `WARN Dart Sass: DEPRECATED [import]`). Applicable to Dart Sass. Default is `false`.
+: (`slice`) A slice of deprecation IDs to silence. IDs are enclosed in brackets within Dart Sass warning messages (e.g., `import` in `WARN Dart Sass: DEPRECATED [import]`). Applicable to Dart Sass.
+
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "silenceDeprecations" (slice "import")
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
silenceDependencyDeprecations
: {{< new-in 0.146.0 />}}
-: (`bool`) Whether to silence deprecation warnings from dependencies, where a dependency is considered any file transitively imported through a load path. This does not apply to `@warn` or `@debug` rules.Default is `false`.
+: (`bool`) Whether to silence deprecation warnings from dependencies, where a dependency is considered any file transitively imported through a load path. This does not apply to `@warn` or `@debug` rules. Default is `false`.
+
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "silenceDependencyDeprecations" true
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
sourceMapIncludeSources
: (`bool`) Whether to embed sources in the generated source map. Applicable to Dart Sass. Default is `false`.
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "enableSourceMap" true "sourceMapIncludeSources" true
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
targetPath
-: (`string`) The publish path for the transformed resource, relative to the[`publishDir`][]. If unset, the target path defaults to the asset's original path with a `.css` extension.
+: (`string`) The publish path for the transformed resource, relative to the [`publishDir`][]. If unset, the target path defaults to the asset's original path with a `.css` extension.
+
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "targetPath" "css/bundle.css"
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
transpiler
: (`string`) The transpiler to use, either `libsass` or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass). Default is `libsass`.
- > [!warning]
- > The embedded LibSass transpiler was deprecated in [v0.153.0][] and will be removed in a future release. Use the Dart Sass transpiler instead.
+ ```go-html-template
+ {{ $opts := dict "transpiler" "dartsass" }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
vars
-: (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
+: (`map`) A map of key-value pairs used to generate Sass variables. The `css.Sass` function injects these variables into the stylesheet when it encounters the `hugo:vars` internal identifier within a `@use` or `@import` statement.
+
+ ```go-html-template
+ {{ $vars := dict
+ "font-family" "\"Times New Roman\", Times, serif"
+ "font-size" "24px"
+ "primary-color" "blue"
+ }}
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "vars" $vars
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
+ In the example above, using the identifier in your stylesheet allows you to access the values as Sass variables in the `hugo:vars` namespace:
```scss
- // LibSass
- @import "hugo:vars";
+ @use 'hugo:vars' as v;
- // Dart Sass
- @use "hugo:vars" as v;
+ .element {
+ color: v.$primary-color;
+ font-family: v.$font-family;
+ font-size: v.$font-size;
+ }
+ ```
+
+ The above produces output equivalent to:
+
+ ```css
+ .element {
+ color: blue;
+ font-family: "Times New Roman", Times, serif;
+ font-size: 24px;
+ }
+ ```
+
+ {{< new-in 0.161.0 />}}
+
+ The map may optionally contain nested maps. Each nested map is exposed as a separate `hugo:vars/` namespace, where `` is the key of the nested map (lowercased). Top-level scalar values and nested maps are independent. A top-level `@use 'hugo:vars'` only includes scalar values, while `@use 'hugo:vars/'` only includes the scalars from the named nested map.
+
+ ```go-html-template
+ {{ $vars := dict
+ "font-family" "\"Times New Roman\", Times, serif"
+ "font-size" "24px"
+ "primary-color" "blue"
+ "mobile" (dict
+ "font-size" "12px"
+ "primary-color" "red"
+ )
+ }}
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "vars" $vars
+ }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
+ ```
+
+ In the stylesheet, reference each nested namespace with a separate `@use` statement. Assign an alias to access the variables from that namespace:
+
+ ```scss
+ @use 'hugo:vars' as v;
+ @use 'hugo:vars/mobile' as mobile;
+
+ body {
+ color: v.$primary-color;
+ font-family: v.$font-family;
+ font-size: v.$font-size;
+ }
+
+ @media (max-width: 650px) {
+ body {
+ color: mobile.$primary-color;
+ font-size: mobile.$font-size;
+ }
+ }
+ ```
+
+ The above produces output equivalent to:
+
+ ```css
+ body {
+ color: blue;
+ font-family: "Times New Roman", Times, serif;
+ font-size: 24px;
+ }
+
+ @media (max-width: 650px) {
+ body {
+ color: red;
+ font-size: 12px;
+ }
+ }
+ ```
+
+ The `vars` option is useful for setting Sass variables within your project configuration.
+
+ {{< code-toggle file=hugo >}}
+ [params.theme.style]
+ font-family = '"Times New Roman", Times, serif'
+ font-size = '24px'
+ primary-color = 'blue'
+
+ [params.theme.style.mobile]
+ font-size = '12px'
+ primary-color = 'red'
+ {{< /code-toggle >}}
+
+ ```go-html-template
+ {{ $opts := dict
+ "transpiler" "dartsass"
+ "vars" site.Params.theme.style }}
+ {{ $r := resources.Get "sass/main.scss" | css.Sass $opts }}
```
When passing a `vars` map to the `css.Sass` function, Hugo detects common typed CSS values such as `24px` or `#FF0000` using regular expression matching. If necessary, you can bypass automatic type inference by using the [`css.Quoted`][] or [`css.Unquoted`][] function to explicitly indicate a value's type.
@@ -77,7 +248,7 @@ vars
"vars" site.Params.styles
"includePaths" (slice "node_modules/bootstrap/scss")
}}
- {{ with . | toCSS $opts }}
+ {{ with . | css.Sass $opts }}
{{ if hugo.IsDevelopment }}
{{ else }}
diff --git a/docs/content/en/functions/css/TailwindCSS.md b/docs/content/en/functions/css/TailwindCSS.md
index d104ed96a..f912fcf26 100644
--- a/docs/content/en/functions/css/TailwindCSS.md
+++ b/docs/content/en/functions/css/TailwindCSS.md
@@ -24,15 +24,18 @@ Use the `css.TailwindCSS` function to process your Tailwind CSS files. This func
## Setup
Step 1
-: Install the Tailwind CSS CLI v4.0 or later:
+: Install Tailwind CSS v4.0 or later:
```sh {copy=true}
npm install --save-dev tailwindcss @tailwindcss/cli @tailwindcss/typography
```
- The Tailwind CSS CLI is also available as a [standalone executable]. You must install it outside of your project directory and ensure its path is included in your system's `PATH` environment variable.
+
+
+ > [!note]
+ > As of v0.161.0, Hugo no longer supports the Tailwind [standalone binary]. You must now install the Tailwind CSS CLI via `npm` as shown above.
- [standalone executable]: https://github.com/tailwindlabs/tailwindcss/releases/latest
+ [standalone binary]: https://github.com/tailwindlabs/tailwindcss/releases/latest
Step 2
: Add this to your project configuration:
@@ -113,3 +116,25 @@ disableInlineImports
skipInlineImportsNotFound
: (`bool`) Whether to allow the build process to continue despite unresolved import statements, preserving the original import declarations. It is important to note that the inline importer does not process URL-based imports or those with media queries, and these will remain unaltered even when this option is disabled. Default is `false`.
+
+## Inject CSS variables with `vars`
+
+The [css.Build](./Build) function has a [vars](./Build#vars) option that can be used to inject CSS variables into your stylesheets. This is particularly useful for dynamically setting values based on your site's configuration or other data. To use this with Tailwind CSS, you can use [css.Build](./Build) as a preprocessor step before passing the result to `css.TailwindCSS`. Here's how you can do it:
+
+```go-html-template
+{{ with resources.Get "css/styles.css" }}
+ {{ $cssOpts := dict
+ "vars" (dict "favourite-color" "#7f93c9")
+ "externals" (slice "tailwindcss")
+ }}
+ {{ $tailwindOpts := dict "disableInlineImports" true }}
+ {{ with . | css.Build $cssOpts | css.TailwindCSS $tailwindOpts }}
+
+ {{ end }}
+{{ end }}
+```
+
+Some notes to the above:
+
+- Marking `tailwindcss` as an external in the `css.Build` options prevents it from being processed by the build step, allowing it to be correctly handled by the Tailwind CSS CLI in the subsequent step.
+- The `disableInlineImports` option is set to `true` for the Tailwind CSS step as imports are handled by the `css.Build`.
diff --git a/docs/content/en/functions/css/Unquoted.md b/docs/content/en/functions/css/Unquoted.md
index 9800b9de0..5aebb12c0 100644
--- a/docs/content/en/functions/css/Unquoted.md
+++ b/docs/content/en/functions/css/Unquoted.md
@@ -13,61 +13,39 @@ params:
> [!note]
-> This function is only applicable to the [`vars`] option passed to the [`css.Sass`] function.
+> This function is only applicable to the `vars` option passed to the [`css.Sass`][] function.
-When passing a `vars` map to the `css.Sass` function, Hugo detects common typed CSS values such as `24px` or `#FF0000` using regular expression matching. If necessary, you can bypass automatic type inference by using the `css.Unquoted` function to explicitly indicate that the value must not be treated as a quoted string.
+When passing a `vars` map to the `css.Sass` function, Hugo detects common typed CSS values such as `24px` or `#FF0000` using regular expression matching. If necessary, you can bypass automatic type inference by using the `css.Unquoted` function to explicitly indicate that the value must be treated as an unquoted string.
-For example:
+In the example below, we use `css.Unquoted` to ensure the value for the `font-family` property is injected without quotes.
-```scss {file="assets/sass/main.scss"}
-@use "hugo:vars" as h;
-
-h1 {
- font-size: h.$font-size-h1;
-}
-
-h2 {
- font-size: h.$font-size-h2;
-}
-```
-
-```go-html-template {file="layouts/_partials/css.html"}
+```go-html-template
{{ $vars := dict
- "font_size_h1" ("72px * 0.500" | css.Unquoted)
- "font_size_h2" ("72px * 0.375" | css.Unquoted)
+ "font-main" ("sans-serif" | css.Unquoted)
}}
-{{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict
- "enableSourceMap" hugo.IsDevelopment
- "outputStyle" (cond hugo.IsDevelopment "expanded" "compressed")
- "targetPath" "css/main.css"
- "transpiler" "dartsass"
- "vars" $vars
- }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsDevelopment }}
-
- {{ else }}
- {{ with . | fingerprint }}
-
- {{ end }}
- {{ end }}
- {{ end }}
+{{ $opts := dict "vars" $vars "transpiler" "dartsass" }}
+{{ with resources.Get "sass/main.scss" | css.Sass $opts }}
+
{{ end }}
```
-The Sass rules are transpiled to:
+Using the `hugo:vars` identifier in your stylesheet:
-```css {file="public/css/main.css"}
-h1 {
- font-size: 36px;
-}
+```scss
+@use "hugo:vars" as h;
-h2 {
- font-size: 27px;
+body {
+ font-family: h.$font-main;
}
```
-[`css.Sass`]: /functions/css/sass/
-[`vars`]: /functions/css/sass/#vars
+The resulting CSS contains an unquoted string:
+
+```css
+body {
+ font-family: sans-serif;
+}
+```
+
+[`css.Sass`]: /functions/css/sass/#vars
diff --git a/docs/content/en/functions/hash/FNV32a.md b/docs/content/en/functions/hash/FNV32a.md
index b108acff8..fc2d67373 100644
--- a/docs/content/en/functions/hash/FNV32a.md
+++ b/docs/content/en/functions/hash/FNV32a.md
@@ -8,7 +8,7 @@ params:
aliases: []
returnType: int
signatures: [hash.FNV32a STRING]
-aliases: [/functions/crypto.fnv32a]
+aliases: [/functions/crypto/fnv32a/,/functions/crypto.fnv32a]
---
```go-html-template
diff --git a/docs/content/en/functions/hugo/Generator.md b/docs/content/en/functions/hugo/Generator.md
index b2238e41d..223da5aec 100644
--- a/docs/content/en/functions/hugo/Generator.md
+++ b/docs/content/en/functions/hugo/Generator.md
@@ -11,5 +11,5 @@ params:
---
```go-html-template
-{{ hugo.Generator }} →
+{{ hugo.Generator }} →
```
diff --git a/docs/content/en/functions/hugo/Version.md b/docs/content/en/functions/hugo/Version.md
index 8778e173e..0aa7e157b 100644
--- a/docs/content/en/functions/hugo/Version.md
+++ b/docs/content/en/functions/hugo/Version.md
@@ -11,5 +11,5 @@ params:
---
```go-html-template
-{{ hugo.Version }} → 0.158.0
+{{ hugo.Version }} → 0.161.1
```
diff --git a/docs/content/en/functions/js/Batch.md b/docs/content/en/functions/js/Batch.md
index 9e6a33c88..b4b85cd51 100644
--- a/docs/content/en/functions/js/Batch.md
+++ b/docs/content/en/functions/js/Batch.md
@@ -10,6 +10,9 @@ params:
signatures: ['js.Batch [ID]']
---
+> [!note]
+> The `js.Batch` function is backed by the [`evanw/esbuild`][] package, providing a mature, high-performance foundation for bundling, transformation, and minification.
+
> [!note]
> For a runnable example of this feature, see [this test and demo repo](https://github.com/bep/hugojsbatchdemo/).
@@ -287,22 +290,23 @@ import './lib1.js';
console.log('entrypoints-workaround.js');
```
+[ESBuild]: https://github.com/evanw/esbuild
+[JavaScript import]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
+[OptionsSetter]: #optionssetter
+[SetOptions]: #optionssetter
[`Resource`]: /methods/resource/
[`Resources.Mount`]: /methods/page/resources/#mount
[`Resources`]: /methods/page/resources/
+[`evanw/esbuild`]: https://github.com/evanw/esbuild
[`templates.Defer`]: /functions/templates/defer/
[build options]: #build-options
[code splitting]: https://esbuild.github.io/api/#splitting
[config]: #config
-[ESBuild]: https://github.com/evanw/esbuild
[group]: #group
[instance]: #instance
-[JavaScript import]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
[js.Batch Demo Repo]: https://github.com/bep/hugojsbatchdemo/
-[OptionsSetter]: #optionssetter
[params options]: #params-options
[runner]: #runner
-[script]: #script
[script options]: #script-options
-[SetOptions]: #optionssetter
+[script]: #script
[with]: /functions/go-template/with/
diff --git a/docs/content/en/functions/js/Build.md b/docs/content/en/functions/js/Build.md
index 87d379e46..60960a15d 100644
--- a/docs/content/en/functions/js/Build.md
+++ b/docs/content/en/functions/js/Build.md
@@ -10,7 +10,10 @@ params:
signatures: ['js.Build [OPTIONS] RESOURCE']
---
-The `js.Build` function uses the [evanw/esbuild] package to:
+> [!note]
+> The `js.Build` function is backed by the [`evanw/esbuild`][] package, providing a mature, high-performance foundation for bundling, transformation, and minification.
+
+Use the `js.Build` function to:
- Bundle
- Transpile (TypeScript and JSX)
@@ -74,7 +77,7 @@ For other files (e.g. `JSON`, `CSS`) you need to use the relative path including
import * as data from 'my/module/data.json';
```
-Any imports in a file outside `assets` or that does not resolve to a component inside `assets` will be resolved by [ESBuild](https://esbuild.github.io/) with the **project directory** as the resolve directory (used as the starting point when looking for `node_modules` etc.). Also see [hugo mod npm pack](/commands/hugo_mod_npm_pack/). If you have any imported npm dependencies in your project, you need to make sure to run `npm install` before you run `hugo build`.
+Any imports in a file outside `assets` or that does not resolve to a component inside `assets` will be resolved by [esbuild](https://esbuild.github.io/) with the **project directory** as the resolve directory (used as the starting point when looking for `node_modules` etc.). Also see [hugo mod npm pack](/commands/hugo_mod_npm_pack/). If you have any imported npm dependencies in your project, you need to make sure to run `npm install` before you run `hugo build`.
Also note the new `params` option that can be passed from template to your JS files, e.g.:
@@ -118,4 +121,4 @@ Or with options:
```
-[evanw/esbuild]: https://github.com/evanw/esbuild
+[`evanw/esbuild`]: https://github.com/evanw/esbuild
diff --git a/docs/content/en/functions/lang/Translate.md b/docs/content/en/functions/lang/Translate.md
index 442090f25..f8bdc069b 100644
--- a/docs/content/en/functions/lang/Translate.md
+++ b/docs/content/en/functions/lang/Translate.md
@@ -11,11 +11,9 @@ params:
aliases: [/functions/i18n]
---
-The `lang.Translate` function returns the value associated with given key as defined in the translation table for the current language.
+The `lang.Translate` function returns the value associated with the given key by searching the current language's [translation tables](#translation-tables), then those for the [`defaultContentLanguage`][].
-If the key is not found in the translation table for the current language, the `lang.Translate` function falls back to the translation table for the [`defaultContentLanguage`][].
-
-If the key is not found in the translation table for the `defaultContentLanguage`, the `lang.Translate` function returns an empty string.
+If not found, the function returns an empty string.
> [!note]
> To list missing and fallback translations, set [`printI18nWarnings`][] to `true` in your project configuration, or use the `--printI18nWarnings` flag when building your project.
@@ -24,14 +22,21 @@ If the key is not found in the translation table for the `defaultContentLanguage
## Translation tables
-Create translation tables in the `i18n` directory, naming each file according to [RFC 5646][]. Translation tables may be JSON, TOML, or YAML. For example:
+{{% glossary-term "translation table" %}}
+
+For example:
```text
i18n/en.toml
i18n/pt-BR.toml
```
-The base name must match the [`locale`][] or [language key][] as defined in your project configuration. Hugo selects the translation table based on the `locale`, falling back to the language key if a matching translation table does not exist.
+Hugo searches for a matching translation table using the following base names, in order:
+
+1. The [`locale`][] of the current language
+1. The [key][] of the current language
+1. The locale of the [`defaultContentLanguage`][]
+1. The key of the [`defaultContentLanguage`][]
Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7][] are also supported. You may omit the `art-x-` prefix for brevity. For example:
@@ -177,7 +182,7 @@ Template code:
## Reserved keys
-Hugo uses the [go-i18n][] package to look up values in translation tables. This package reserves the following keys for internal use:
+Hugo uses the [`nicksnyder/go-i18n`][] package to look up values in translation tables. This package reserves the following keys for internal use:
id
: (`string`) Uniquely identifies the message.
@@ -236,12 +241,11 @@ Then in your templates:
{{ T "_other" }} → otro
```
+[CLDR]: https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
+[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
[`defaultContentLanguage`]: /configuration/all/#defaultcontentlanguage
[`enableMissingTranslationPlaceholders`]: /configuration/all/#enablemissingtranslationplaceholders
-[`locale`]: /configuration/languages/#locale
+[`locale`]: /configuration/all/#locale
+[`nicksnyder/go-i18n`]: https://github.com/nicksnyder/go-i18n
[`printI18nWarnings`]: /configuration/all/#printi18nwarnings
-[CLDR]: https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
-[go-i18n]: https://github.com/nicksnyder/go-i18n
-[language key]: /configuration/languages/#language-keys
-[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
-[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646
+[key]: /configuration/languages/#language-keys
diff --git a/docs/content/en/functions/math/Acos.md b/docs/content/en/functions/math/Acos.md
index 32537e2dd..cac9d82f6 100644
--- a/docs/content/en/functions/math/Acos.md
+++ b/docs/content/en/functions/math/Acos.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Acos VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Acos 1 }} → 0
```
diff --git a/docs/content/en/functions/math/Asin.md b/docs/content/en/functions/math/Asin.md
index 76114a72e..4b082fdb8 100644
--- a/docs/content/en/functions/math/Asin.md
+++ b/docs/content/en/functions/math/Asin.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Asin VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Asin 1 }} → 1.5707963267948966
```
diff --git a/docs/content/en/functions/math/Atan.md b/docs/content/en/functions/math/Atan.md
index 5c8268b47..4bcde0929 100644
--- a/docs/content/en/functions/math/Atan.md
+++ b/docs/content/en/functions/math/Atan.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Atan VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Atan 1 }} → 0.7853981633974483
```
diff --git a/docs/content/en/functions/math/Atan2.md b/docs/content/en/functions/math/Atan2.md
index 942fffdf8..01bb0aefa 100644
--- a/docs/content/en/functions/math/Atan2.md
+++ b/docs/content/en/functions/math/Atan2.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Atan2 VALUE VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Atan2 1 2 }} → 0.4636476090008061
```
diff --git a/docs/content/en/functions/math/Cos.md b/docs/content/en/functions/math/Cos.md
index 249a064bb..08d8abe52 100644
--- a/docs/content/en/functions/math/Cos.md
+++ b/docs/content/en/functions/math/Cos.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Cos VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Cos 1 }} → 0.5403023058681398
```
diff --git a/docs/content/en/functions/math/Pi.md b/docs/content/en/functions/math/Pi.md
index 0bc74bf03..45010d5ed 100644
--- a/docs/content/en/functions/math/Pi.md
+++ b/docs/content/en/functions/math/Pi.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Pi]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Pi }} → 3.141592653589793
```
diff --git a/docs/content/en/functions/math/Sin.md b/docs/content/en/functions/math/Sin.md
index b5ab86bb8..2a0ffcdfc 100644
--- a/docs/content/en/functions/math/Sin.md
+++ b/docs/content/en/functions/math/Sin.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Sin VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Sin 1 }} → 0.8414709848078965
```
diff --git a/docs/content/en/functions/math/Tan.md b/docs/content/en/functions/math/Tan.md
index c4f861c05..b05b4b848 100644
--- a/docs/content/en/functions/math/Tan.md
+++ b/docs/content/en/functions/math/Tan.md
@@ -10,8 +10,6 @@ params:
signatures: [math.Tan VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.Tan 1 }} → 1.557407724654902
```
diff --git a/docs/content/en/functions/math/ToDegrees.md b/docs/content/en/functions/math/ToDegrees.md
index f01cd4728..6c3ed5981 100644
--- a/docs/content/en/functions/math/ToDegrees.md
+++ b/docs/content/en/functions/math/ToDegrees.md
@@ -10,8 +10,6 @@ params:
signatures: [math.ToDegrees VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.ToDegrees 1.5707963267948966 }} → 90
```
diff --git a/docs/content/en/functions/math/ToRadians.md b/docs/content/en/functions/math/ToRadians.md
index b5acbb65b..b4459773a 100644
--- a/docs/content/en/functions/math/ToRadians.md
+++ b/docs/content/en/functions/math/ToRadians.md
@@ -10,8 +10,6 @@ params:
signatures: [math.ToRadians VALUE]
---
-{{< new-in 0.130.0 />}}
-
```go-html-template
{{ math.ToRadians 90 }} → 1.5707963267948966
```
diff --git a/docs/content/en/functions/resources/FromString.md b/docs/content/en/functions/resources/FromString.md
index 0ca741936..160e85d81 100644
--- a/docs/content/en/functions/resources/FromString.md
+++ b/docs/content/en/functions/resources/FromString.md
@@ -22,9 +22,9 @@ Let's say you need to publish a file named "site.json" in the root of your `publ
```json
{
- "build_date": "2026-03-16T13:56:25-07:00",
- "hugo_version": "0.158.0",
- "last_modified": "2026-02-16T12:04:52-07:00"
+ "build_date": "2026-04-04T10:46:21-07:00",
+ "hugo_version": "0.161.1",
+ "last_modified": "2026-04-04T10:46:26-07:00"
}
```
diff --git a/docs/content/en/functions/transform/CanHighlight.md b/docs/content/en/functions/transform/CanHighlight.md
index 5e3b04a81..8fa640a4e 100644
--- a/docs/content/en/functions/transform/CanHighlight.md
+++ b/docs/content/en/functions/transform/CanHighlight.md
@@ -1,6 +1,6 @@
---
title: transform.CanHighlight
-description: Reports whether the given code language is supported by the Chroma highlighter.
+description: Reports whether the given language is supported for syntax highlighting.
categories: []
keywords: [highlight]
params:
diff --git a/docs/content/en/functions/transform/HTMLUnescape.md b/docs/content/en/functions/transform/HTMLUnescape.md
index ab9be942b..828b80df3 100644
--- a/docs/content/en/functions/transform/HTMLUnescape.md
+++ b/docs/content/en/functions/transform/HTMLUnescape.md
@@ -25,5 +25,5 @@ In most contexts Go's [`html/template`][] package will escape special characters
```
[`safehtml`]: /functions/safe/html/
-[html entities]: https://developer.mozilla.org/en-us/docs/glossary/entity
+[html entities]: https://developer.mozilla.org/en-US/docs/Glossary/Entity
[`html/template`]: https://pkg.go.dev/html/template
diff --git a/docs/content/en/functions/transform/Highlight.md b/docs/content/en/functions/transform/Highlight.md
index 1e4e235b4..72f154ea4 100644
--- a/docs/content/en/functions/transform/Highlight.md
+++ b/docs/content/en/functions/transform/Highlight.md
@@ -11,26 +11,20 @@ params:
aliases: [/functions/highlight]
---
-The `highlight` function uses the [Chroma] syntax highlighter, supporting over 200 languages with more than 40 [highlighting styles].
-
-[chroma]: https://github.com/alecthomas/chroma
-[highlighting styles]: /quick-reference/syntax-highlighting-styles/
+The `transform.Highlight` function uses the [`alecthomas/chroma`][] package to generate syntax-highlighted HTML from the provided code, [language][], and [options][].
## Arguments
-The `transform.Highlight` shortcode takes three arguments.
+The `transform.Highlight` function takes three arguments.
CODE
: (`string`) The code to highlight.
LANG
-: (`string`) The language of the code to highlight. Choose from one of the [supported languages]. This value is case-insensitive.
+: (`string`) The [language][] of the code to highlight. This value is case-insensitive.
OPTIONS
-: (`map or string`) A map or comma-separated key-value pairs wrapped in quotation marks. Set default values for each option in your [project configuration]. The key names are case-insensitive.
-
-[project configuration]: /configuration/markup#highlight
-[supported languages]: /content-management/syntax-highlighting#languages
+: (`map or string`) A map or comma-separated key-value pairs wrapped in quotation marks. You can set default values for each option in your [project configuration][]. The key names are case-insensitive.
## Examples
@@ -51,3 +45,8 @@ OPTIONS
## Options
{{% include "_common/syntax-highlighting-options.md" %}}
+
+[`alecthomas/chroma`]: https://github.com/alecthomas/chroma
+[language]: /content-management/syntax-highlighting#languages
+[options]: #options-1
+[project configuration]: /configuration/markup#highlight
diff --git a/docs/content/en/functions/transform/PortableText.md b/docs/content/en/functions/transform/PortableText.md
index d100f5eb2..a100cd3c2 100644
--- a/docs/content/en/functions/transform/PortableText.md
+++ b/docs/content/en/functions/transform/PortableText.md
@@ -11,16 +11,16 @@ params:
{{< new-in "0.145.0" />}}
-[Portable Text](https://www.portabletext.org/) is a JSON structure that represent rich text content in the [Sanity](https://www.sanity.io/) CMS. In Hugo, this function is typically used in a [Content Adapter](https://gohugo.io/content-management/content-adapters/) that creates pages from Sanity data.
+[Portable Text][] is a JSON structure that represents rich text content in the [Sanity][] CMS. In Hugo, this function is typically used in a [content adapter][] that creates pages from Sanity data.
## Types supported
- `block` and `span`
-- `image`. Note that the image handling is currently very simple; we link to the `asset.url` using `asset.altText` as the image alt text and `asset.title` as the title. For more fine grained control you may want to process the images in a [image render hook](/render-hooks/images/).
-- `code` (see the [code-input](https://www.sanity.io/plugins/code-input) plugin). Code will be rendered as [fenced code blocks](/contribute/documentation/#fenced-code-blocks) with any file name provided passed on as a markdown attribute.
+- `image`. Note that the image handling is currently very simple; we link to the `asset.url` using `asset.altText` as the image alt text and `asset.title` as the title. For more fine-grained control you may want to process the images in an [image render hook][].
+- `code` (see the [code-input][] plugin). Code will be rendered as fenced code blocks with any file name provided passed as a Markdown attribute.
> [!note]
-> Since the Portable Text gets converted to Markdown before it gets passed to Hugo, rendering of links, headings, images and code blocks can be controlled with [Render Hooks](https://gohugo.io/render-hooks/).
+> Since the Portable Text gets converted to Markdown before it gets passed to Hugo, rendering of links, headings, images and code blocks can be controlled with [render hooks][].
## Example
@@ -34,10 +34,9 @@ params:
{{/* See https://www.sanity.io/docs/api-cdn */}}
{{ $api = "apicdn" }}
{{ end }}
-{{ $url := printf "https://%s.%s.sanity.io/v2021-06-07/data/query/production" $projectID $api }}
+{{ $url := printf "https://%s.%s.sanity.io/v2021-06-07/data/query/production" $projectID $api }}
-{{/* prettier-ignore-start */ -}}
-{{ $q := `*[_type == 'post']{
+{{ $q := `*[_type == 'post']{
title, publishedAt, summary, slug, body[]{
...,
_type == "image" => {
@@ -61,7 +60,6 @@ params:
},
}`
}}
-{{/* prettier-ignore-end */ -}}
{{ $body := dict "query" $q | jsonify }}
{{ $opts := dict "method" "post" "body" $body }}
{{ $r := resources.GetRemote $url $opts }}
@@ -94,7 +92,7 @@ params:
### Sanity setup
-Below outlines a suitable Sanity studio setup for the above example.
+The following outlines a suitable Sanity studio setup for the above example.
```ts {file="sanity.config.ts" copy=true}
import {defineConfig} from 'sanity'
@@ -192,7 +190,7 @@ export const schemaTypes = [postType]
## Server setup
-Unfortunately, Sanity's API does not support [RFC 7234](https://tools.ietf.org/html/rfc7234) and their output changes even if the data has not. A recommended setup is therefore to use their cached `apicdn` endpoint (see above) and then set up a reasonable polling and file cache strategy in your Hugo configuration, e.g:
+Unfortunately, Sanity's API does not support [RFC 7234][] and their output changes even if the data has not. A recommended setup is therefore to use their cached `apicdn` endpoint (see above) and then set up a reasonable polling and file cache strategy in your Hugo configuration, e.g:
{{< code-toggle file=hugo >}}
@@ -210,6 +208,15 @@ Unfortunately, Sanity's API does not support [RFC 7234](https://tools.ietf.org/h
{{< /code-toggle >}}
-The polling above will be used when running the server/watch mode and rebuild when you push new content in Sanity.
+The polling above will be used when running the server/watch mode and rebuilds when you push new content to Sanity.
-See [Caching in resources.GetRemote](/functions/resources/getremote/#caching) for more fine grained control.
+See [Caching in resources.GetRemote][] for more fine-grained control.
+
+[Caching in resources.GetRemote]: /functions/resources/getremote/#caching
+[Portable Text]: https://www.portabletext.org/
+[RFC 7234]: https://tools.ietf.org/html/rfc7234
+[Sanity]: https://www.sanity.io/
+[code-input]: https://www.sanity.io/plugins/code-input
+[content adapter]: /content-management/content-adapters/
+[image render hook]: /render-hooks/images/
+[render hooks]: /render-hooks/
diff --git a/docs/content/en/functions/transform/ToMath.md b/docs/content/en/functions/transform/ToMath.md
index 27b2f0d70..95837ffaa 100644
--- a/docs/content/en/functions/transform/ToMath.md
+++ b/docs/content/en/functions/transform/ToMath.md
@@ -13,14 +13,14 @@ aliases: [/functions/tomath]
{{< new-in 0.132.0 />}}
-Hugo uses an embedded instance of the [KaTeX] display engine to render mathematical markup to HTML. You do not need to install the KaTeX display engine.
+Hugo uses an embedded instance of the [KaTeX][] display engine to render mathematical markup to HTML. You do not need to install the KaTeX display engine.
```go-html-template
{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }}
```
> [!note]
-> By default, Hugo renders mathematical markup to [MathML], and does not require any CSS to display the result.
+> By default, Hugo renders mathematical markup to [MathML][], and does not require any CSS to display the result.
>
> To optimize rendering quality and accessibility, use the `htmlAndMathml` output option as described below. This approach requires an external stylesheet.
@@ -31,13 +31,13 @@ Hugo uses an embedded instance of the [KaTeX] display engine to render mathemati
## Options
-Pass a map of options as the second argument to the `transform.ToMath` function. The options below are a subset of the KaTeX [rendering options].
+Pass a map of options as the second argument to the `transform.ToMath` function. The options below are a subset of the KaTeX [rendering options][].
displayMode
: (`bool`) Whether to render in display mode instead of inline mode. Default is `false`.
errorColor
-: (`string`) The color of the error messages expressed as an RGB [hexadecimal color]. Default is `#cc0000`.
+: (`string`) The color of the error messages expressed as an RGB [hexadecimal color][]. Default is `#cc0000`.
fleqn
: (`bool`) Whether to render flush left with a 2em left margin. Default is `false`.
@@ -179,7 +179,7 @@ Step 4
{{< new-in 0.144.0 />}}
-You can also use the `transform.ToMath` function to render chemical equations, leveraging the `\ce` and `\pu` functions from the [mhchem] package.
+You can also use the `transform.ToMath` function to render chemical equations, leveraging the `\ce` and `\pu` functions from the [`mhchem`][] package.
```text
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
@@ -187,10 +187,10 @@ $$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
-[`Content`]: /methods/page/content/
-[`Summary`]: /methods/page/summary/
-[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
[KaTeX]: https://katex.org/
[MathML]: https://developer.mozilla.org/en-US/docs/Web/MathML
-[mhchem]: https://mhchem.github.io/MathJax-mhchem/
+[`Content`]: /methods/page/content/
+[`Summary`]: /methods/page/summary/
+[`mhchem`]: https://mhchem.github.io/MathJax-mhchem/
+[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
[rendering options]: https://katex.org/docs/options.html
diff --git a/docs/content/en/functions/transform/Unmarshal.md b/docs/content/en/functions/transform/Unmarshal.md
index 7e9726749..c92f6a054 100644
--- a/docs/content/en/functions/transform/Unmarshal.md
+++ b/docs/content/en/functions/transform/Unmarshal.md
@@ -40,7 +40,7 @@ title: Les Misérables
author: Victor Hugo
`}}
-{{ $book := unmarshal $string }}
+{{ $book := transform.Unmarshal $string }}
{{ $book.title }} → Les Misérables
{{ $book.author }} → Victor Hugo
```
diff --git a/docs/content/en/functions/transform/XMLEscape.md b/docs/content/en/functions/transform/XMLEscape.md
index d9a9cdf93..a69803e01 100644
--- a/docs/content/en/functions/transform/XMLEscape.md
+++ b/docs/content/en/functions/transform/XMLEscape.md
@@ -34,5 +34,5 @@ When using `transform.XMLEscape` in a template rendered by Go's [`html/template`
```
[disallowed characters]: https://www.w3.org/TR/xml/#charsets
-[html entities]: https://developer.mozilla.org/en-us/docs/glossary/entity
+[html entities]: https://developer.mozilla.org/en-US/docs/Glossary/Entity
[`html/template`]: https://pkg.go.dev/html/template
diff --git a/docs/content/en/getting-started/quick-start.md b/docs/content/en/getting-started/quick-start.md
index f88229196..9ed328c18 100644
--- a/docs/content/en/getting-started/quick-start.md
+++ b/docs/content/en/getting-started/quick-start.md
@@ -4,7 +4,7 @@ description: Create your first Hugo project.
categories: []
keywords: []
params:
- minVersion: v0.156.0
+ minVersion: v0.158.0
weight: 10
aliases: [/quickstart/,/overview/quickstart/]
---
@@ -20,7 +20,7 @@ In this tutorial you will:
Before you begin this tutorial you must:
-1. [Install Hugo] (extended or extended/deploy edition, {{% param "minVersion" %}} or later)
+1. [Install Hugo] (any edition, {{% param "minVersion" %}} or later)
1. [Install Git]
You must also be comfortable working from the command line.
@@ -50,7 +50,7 @@ Run these commands to create a Hugo project with the [Ananke][] theme. The next
hugo new project quickstart
cd quickstart
git init
-git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
+git submodule add https://github.com/gohugo-ananke/ananke themes/ananke
echo "theme = 'ananke'" >> hugo.toml
hugo server
```
@@ -80,7 +80,7 @@ git init
Clone the [Ananke][] theme into the `themes` directory, adding it to your project as a [Git submodule][].
```text
-git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
+git submodule add https://github.com/gohugo-ananke/ananke themes/ananke
```
Append a line to your project configuration file, indicating the current theme.
@@ -170,9 +170,7 @@ hugo server -D
```
> [!note]
-> Most theme authors provide configuration guidelines and options. Make sure to visit your theme's repository or documentation site for details.
->
-> [The New Dynamic][], authors of the Ananke theme, provide [documentation][] for configuration and usage. They also provide a [demonstration site][].
+> Now that you have the Ananke theme installed, check out their [documentation][] and [demonstration site][] to learn how to configure and customize it.
## Publish the project
@@ -196,8 +194,8 @@ For other resources to help you learn Hugo, including books and video tutorials,
[Ananke]: https://github.com/theNewDynamic/gohugo-theme-ananke
[are different applications]: https://learn.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.3
-[demonstration site]: https://gohugo-ananke-theme-demo.netlify.app/
-[documentation]: https://github.com/theNewDynamic/gohugo-theme-ananke#readme
+[demonstration site]: https://ananke-theme.netlify.app/
+[documentation]: https://ananke-documentation.netlify.app/
[draft, future, and expired content]: /getting-started/usage/#draft-future-and-expired-content
[external learning resources]: /getting-started/external-learning-resources/
[forum]: https://discourse.gohugo.io/
@@ -213,4 +211,3 @@ For other resources to help you learn Hugo, including books and video tutorials,
[project skeleton]: /getting-started/directory-structure/#project-skeleton
[requesting help]: https://discourse.gohugo.io/t/requesting-help/9132
[specification]: https://spec.commonmark.org/
-[The New Dynamic]: https://www.thenewdynamic.com/
diff --git a/docs/content/en/getting-started/usage.md b/docs/content/en/getting-started/usage.md
index abf471dc0..42d4e3f98 100644
--- a/docs/content/en/getting-started/usage.md
+++ b/docs/content/en/getting-started/usage.md
@@ -15,12 +15,6 @@ After [installing] Hugo, test your installation by running:
hugo version
```
-You should see something like:
-
-```text
-hugo v0.158.0-f41be7959a44108641f1e081adf5c4be7fc1bb63+extended linux/amd64 BuildDate=2026-03-16T17:42:04Z VendorInfo=gohugoio
-```
-
## Display available commands
To see a list of the available commands and flags:
diff --git a/docs/content/en/host-and-deploy/deploy-with-hugo-deploy.md b/docs/content/en/host-and-deploy/deploy-with-hugo-deploy.md
index 6dae734c4..b894fef94 100644
--- a/docs/content/en/host-and-deploy/deploy-with-hugo-deploy.md
+++ b/docs/content/en/host-and-deploy/deploy-with-hugo-deploy.md
@@ -9,7 +9,7 @@ aliases: [/hosting-and-deployment/hugo-deploy/]
Use the `hugo deploy` command to deploy your site Amazon S3, Azure Blob Storage, or Google Cloud Storage.
> [!note]
-> This feature requires the Hugo extended/deploy edition. See the [installation] section for details.
+> This feature requires the deploy or extended/deploy edition. See the [installation] section for details.
## Assumptions
diff --git a/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md b/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md
index f7f8869a1..15446f2e9 100644
--- a/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md
+++ b/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md
@@ -40,9 +40,9 @@ Step 2
env:
variables:
# Application versions
- DART_SASS_VERSION: 1.98.0
- GO_VERSION: 1.26.1
- HUGO_VERSION: 0.158.0
+ DART_SASS_VERSION: 1.99.0
+ GO_VERSION: 1.26.2
+ HUGO_VERSION: 0.161.1
# Time zone
TZ: Europe/Oslo
# Cache
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-01.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-01.png
index 9c7a4380d..5449f5199 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-01.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-01.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-02.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-02.png
index 595a164ea..c2542b98a 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-02.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-02.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-03.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-03.png
index 6d4228b4a..ba3daed29 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-03.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-03.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-06.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-06.png
index 33010b11d..246723b04 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-06.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-06.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-07.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-07.png
index 10ed1c7c6..0f31143e2 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-07.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-07.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-08.png b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-08.png
index 396387314..6cfe03831 100644
Binary files a/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-08.png and b/docs/content/en/host-and-deploy/host-on-cloudflare/cloudflare-08.png differ
diff --git a/docs/content/en/host-and-deploy/host-on-cloudflare/index.md b/docs/content/en/host-and-deploy/host-on-cloudflare/index.md
index eb6c1d7e3..d1e672579 100644
--- a/docs/content/en/host-and-deploy/host-on-cloudflare/index.md
+++ b/docs/content/en/host-and-deploy/host-on-cloudflare/index.md
@@ -49,44 +49,66 @@ Step 2
# The Cloudflare Worker automatically installs Node.js dependencies.
#------------------------------------------------------------------------------
+ # Exit on error, undefined variables, or pipe failures
+ set -euo pipefail
+
+ build_temp_dir=""
+
+ # Perform cleanup
+ cleanup() {
+ if [[ -n "${build_temp_dir:-}" && -d "${build_temp_dir}" ]]; then
+ rm -rf "${build_temp_dir}"
+ fi
+ }
+
+ # Register the cleanup trap
+ trap cleanup EXIT SIGINT SIGTERM
+
main() {
+ # Define tool versions
+ DART_SASS_VERSION=1.99.0
+ GO_VERSION=1.26.2
+ HUGO_VERSION=0.161.1
+ NODE_VERSION=24.15.0
- DART_SASS_VERSION=1.98.0
- GO_VERSION=1.26.1
- HUGO_VERSION=0.158.0
- NODE_VERSION=24.14.0
-
+ # Set the build timezone
export TZ=Europe/Oslo
+ # Create and move into a temporary directory for downloads
+ build_temp_dir=$(mktemp -d)
+ pushd "${build_temp_dir}" > /dev/null
+
+ # Create the local tools directory
+ mkdir -p "${HOME}/.local"
+
# Install Dart Sass
echo "Installing Dart Sass ${DART_SASS_VERSION}..."
curl -sLJO "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
tar -C "${HOME}/.local" -xf "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
- rm "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
export PATH="${HOME}/.local/dart-sass:${PATH}"
# Install Go
echo "Installing Go ${GO_VERSION}..."
curl -sLJO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
tar -C "${HOME}/.local" -xf "go${GO_VERSION}.linux-amd64.tar.gz"
- rm "go${GO_VERSION}.linux-amd64.tar.gz"
export PATH="${HOME}/.local/go/bin:${PATH}"
# Install Hugo
echo "Installing Hugo ${HUGO_VERSION}..."
- curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
- mkdir "${HOME}/.local/hugo"
- tar -C "${HOME}/.local/hugo" -xf "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
- rm "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
+ curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
+ mkdir -p "${HOME}/.local/hugo"
+ tar -C "${HOME}/.local/hugo" -xf "hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
export PATH="${HOME}/.local/hugo:${PATH}"
# Install Node.js
echo "Installing Node.js ${NODE_VERSION}..."
curl -sLJO "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz"
tar -C "${HOME}/.local" -xf "node-v${NODE_VERSION}-linux-x64.tar.xz"
- rm "node-v${NODE_VERSION}-linux-x64.tar.xz"
export PATH="${HOME}/.local/node-v${NODE_VERSION}-linux-x64/bin:${PATH}"
+ # Return to the project root
+ popd > /dev/null
+
# Verify installations
echo "Verifying installations..."
echo Dart Sass: "$(sass --version)"
@@ -104,10 +126,8 @@ Step 2
# Build the site
echo "Building the site..."
hugo build --gc --minify
-
}
- set -euo pipefail
main "$@"
```
@@ -120,12 +140,12 @@ Step 4

Step 5
-: On the "Workers" tab, press the **Get started** button to the right of the "Import a repository" item.
+: Verify your account if prompted.

Step 6
-: Connect to GitHub.
+: On the "Create a Worker" page, under the "Ship something new" heading, press the **Connect GitHub** button.

@@ -139,25 +159,18 @@ Step 8

- Your browser will be redirected to the Cloudflare dashboard.
-
Step 9
-: On the "Workers" tab, press the **Get started** button to the right of the "Import a repository" item.
-
- 
-
-Step 10
-: Select the repository to import.
+: On the "Create a Worker" page, under the "Select a repository" heading, select the repository to deploy, then press the **Next** button.

-Step 11
-: On the "Set up your application" screen, provide a project name, leave the build command blank, then press the **Create and deploy** button.
+Step 10
+: On the "Create a Worker" page, under the "Set up your application" heading, provide a project name, leave the build command blank, then press the **Deploy** button.

-Step 12
-: Wait for the site to build and deploy, then visit your site.
+Step 11
+: Wait for the site to build and deploy, then press the **Visit** button in the upper left corner of your screen.

diff --git a/docs/content/en/host-and-deploy/host-on-github-pages/index.md b/docs/content/en/host-and-deploy/host-on-github-pages/index.md
index 03b17869c..2b0ac3a86 100644
--- a/docs/content/en/host-and-deploy/host-on-github-pages/index.md
+++ b/docs/content/en/host-and-deploy/host-on-github-pages/index.md
@@ -77,10 +77,10 @@ Step 4
build:
runs-on: ubuntu-latest
env:
- DART_SASS_VERSION: 1.98.0
- GO_VERSION: 1.26.1
- HUGO_VERSION: 0.158.0
- NODE_VERSION: 24.14.0
+ DART_SASS_VERSION: 1.99.0
+ GO_VERSION: 1.26.2
+ HUGO_VERSION: 0.161.1
+ NODE_VERSION: 24.15.0
TZ: Europe/Oslo
steps:
- name: Checkout
@@ -99,7 +99,7 @@ Step 4
node-version: ${{ env.NODE_VERSION }}
- name: Setup Pages
id: pages
- uses: actions/configure-pages@v5
+ uses: actions/configure-pages@v6
- name: Create directory for user-specific executable files
run: |
mkdir -p "${HOME}/.local"
@@ -150,7 +150,7 @@ Step 4
path: ${{ runner.temp }}/hugo_cache
key: ${{ steps.cache-restore.outputs.cache-primary-key }}
- name: Upload artifact
- uses: actions/upload-pages-artifact@v3
+ uses: actions/upload-pages-artifact@v5
with:
path: ./public
deploy:
@@ -162,7 +162,7 @@ Step 4
steps:
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v4
+ uses: actions/deploy-pages@v5
```
Step 5
diff --git a/docs/content/en/host-and-deploy/host-on-gitlab-pages.md b/docs/content/en/host-and-deploy/host-on-gitlab-pages.md
index 6792b4f8d..0cb722b9c 100644
--- a/docs/content/en/host-and-deploy/host-on-gitlab-pages.md
+++ b/docs/content/en/host-and-deploy/host-on-gitlab-pages.md
@@ -24,9 +24,9 @@ Define your [CI/CD](g) jobs by creating a `.gitlab-ci.yml` file in the root of y
```yaml {file=".gitlab-ci.yml" copy=true}
variables:
# Application versions
- DART_SASS_VERSION: 1.98.0
- HUGO_VERSION: 0.158.0
- NODE_VERSION: 24.14.0
+ DART_SASS_VERSION: 1.99.0
+ HUGO_VERSION: 0.161.1
+ NODE_VERSION: 24.15.0
# Git
GIT_DEPTH: 0
GIT_STRATEGY: clone
@@ -35,7 +35,7 @@ variables:
TZ: Europe/Oslo
image:
- name: golang:1.26.1-bookworm
+ name: golang:1.26.2-bookworm
pages:
stage: deploy
diff --git a/docs/content/en/host-and-deploy/host-on-netlify/index.md b/docs/content/en/host-and-deploy/host-on-netlify/index.md
index 34ff0673e..4847212c8 100644
--- a/docs/content/en/host-and-deploy/host-on-netlify/index.md
+++ b/docs/content/en/host-and-deploy/host-on-netlify/index.md
@@ -30,10 +30,10 @@ Step 1
```text {file="netlify.toml" copy=true}
[build.environment]
- DART_SASS_VERSION = "1.98.0"
- GO_VERSION = "1.26.1"
- HUGO_VERSION = "0.158.0"
- NODE_VERSION = "24.14.0"
+ DART_SASS_VERSION = "1.99.0"
+ GO_VERSION = "1.26.2"
+ HUGO_VERSION = "0.161.1"
+ NODE_VERSION = "24.15.0"
TZ = "Europe/Oslo"
[build]
@@ -48,10 +48,10 @@ Step 1
```text {file="netlify.toml" copy=true}
[build.environment]
- DART_SASS_VERSION = "1.98.0"
- GO_VERSION = "1.26.1"
- HUGO_VERSION = "0.158.0"
- NODE_VERSION = "24.14.0"
+ DART_SASS_VERSION = "1.99.0"
+ GO_VERSION = "1.26.2"
+ HUGO_VERSION = "0.161.1"
+ NODE_VERSION = "24.15.0"
TZ = "Europe/Oslo"
[build]
diff --git a/docs/content/en/host-and-deploy/host-on-render/index.md b/docs/content/en/host-and-deploy/host-on-render/index.md
index c0cac9261..3211abd96 100644
--- a/docs/content/en/host-and-deploy/host-on-render/index.md
+++ b/docs/content/en/host-and-deploy/host-on-render/index.md
@@ -35,13 +35,13 @@ Step 1
staticPublishPath: public
envVars:
- key: DART_SASS_VERSION
- value: 1.98.0
+ value: 1.99.0
- key: GO_VERSION
- value: 1.26.1
+ value: 1.26.2
- key: HUGO_VERSION
- value: 0.158.0
+ value: 0.161.1
- key: NODE_VERSION
- value: 24.14.0
+ value: 24.15.0
- key: TZ
value: Europe/Oslo
```
@@ -59,34 +59,51 @@ Step 2
# Render automatically installs Node.js dependencies.
#------------------------------------------------------------------------------
- main() {
+ # Exit on error, undefined variables, or pipe failures
+ set -euo pipefail
- # Create directory for user-specific executable files
- echo "Creating directory for user-specific executable files..."
+ build_temp_dir=""
+
+ # Perform cleanup
+ cleanup() {
+ if [[ -n "${build_temp_dir:-}" && -d "${build_temp_dir}" ]]; then
+ rm -rf "${build_temp_dir}"
+ fi
+ }
+
+ # Register the cleanup trap
+ trap cleanup EXIT SIGINT SIGTERM
+
+ main() {
+ # Create and move into a temporary directory for downloads
+ build_temp_dir=$(mktemp -d)
+ pushd "${build_temp_dir}" > /dev/null
+
+ # Create the local tools directory
mkdir -p "${HOME}/.local"
# Install Dart Sass
echo "Installing Dart Sass ${DART_SASS_VERSION}..."
curl -sLJO "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
tar -C "${HOME}/.local" -xf "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
- rm "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
export PATH="${HOME}/.local/dart-sass:${PATH}"
# Install Go
echo "Installing Go ${GO_VERSION}..."
curl -sLJO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
tar -C "${HOME}/.local" -xf "go${GO_VERSION}.linux-amd64.tar.gz"
- rm "go${GO_VERSION}.linux-amd64.tar.gz"
export PATH="${HOME}/.local/go/bin:${PATH}"
# Install Hugo
echo "Installing Hugo ${HUGO_VERSION}..."
- curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
+ curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
mkdir -p "${HOME}/.local/hugo"
- tar -C "${HOME}/.local/hugo" -xf "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
- rm "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
+ tar -C "${HOME}/.local/hugo" -xf "hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
export PATH="${HOME}/.local/hugo:${PATH}"
+ # Return to the project root
+ popd > /dev/null
+
# Verify installations
echo "Verifying installations..."
echo Dart Sass: "$(sass --version)"
@@ -104,10 +121,8 @@ Step 2
# Build the site
echo "Building the site..."
hugo build --gc --minify --baseURL "${RENDER_EXTERNAL_URL}"
-
}
- set -euo pipefail
main "$@"
```
diff --git a/docs/content/en/host-and-deploy/host-on-sourcehut-pages.md b/docs/content/en/host-and-deploy/host-on-sourcehut-pages.md
index 905459636..5d84b30b6 100644
--- a/docs/content/en/host-and-deploy/host-on-sourcehut-pages.md
+++ b/docs/content/en/host-and-deploy/host-on-sourcehut-pages.md
@@ -84,7 +84,7 @@ environment:
site: .srht.site
tasks:
- package: |
- DART_SASS_VERSION=1.98.0
+ DART_SASS_VERSION=1.99.0
mkdir -p $HOME/.local
curl -L https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64-musl.tar.gz -o dart-sass.tar.gz
tar -xzf dart-sass.tar.gz -C $HOME/.local
diff --git a/docs/content/en/host-and-deploy/host-on-vercel/index.md b/docs/content/en/host-and-deploy/host-on-vercel/index.md
index 8eacaee9f..be04aa4a1 100644
--- a/docs/content/en/host-and-deploy/host-on-vercel/index.md
+++ b/docs/content/en/host-and-deploy/host-on-vercel/index.md
@@ -45,44 +45,66 @@ Step 2
# The Vercel build image automatically installs Node.js dependencies.
#------------------------------------------------------------------------------
+ # Exit on error, undefined variables, or pipe failures
+ set -euo pipefail
+
+ build_temp_dir=""
+
+ # Perform cleanup
+ cleanup() {
+ if [[ -n "${build_temp_dir:-}" && -d "${build_temp_dir}" ]]; then
+ rm -rf "${build_temp_dir}"
+ fi
+ }
+
+ # Register the cleanup trap
+ trap cleanup EXIT SIGINT SIGTERM
+
main() {
+ # Define tool versions
+ DART_SASS_VERSION=1.99.0
+ GO_VERSION=1.26.2
+ HUGO_VERSION=0.161.1
+ NODE_VERSION=24.15.0
- DART_SASS_VERSION=1.98.0
- GO_VERSION=1.26.1
- HUGO_VERSION=0.158.0
- NODE_VERSION=24.14.0
-
+ # Set the build timezone
export TZ=Europe/Oslo
+ # Create and move into a temporary directory for downloads
+ build_temp_dir=$(mktemp -d)
+ pushd "${build_temp_dir}" > /dev/null
+
+ # Create the local tools directory
+ mkdir -p "${HOME}/.local"
+
# Install Dart Sass
echo "Installing Dart Sass ${DART_SASS_VERSION}..."
curl -sLJO "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
tar -C "${HOME}/.local" -xf "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
- rm "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
export PATH="${HOME}/.local/dart-sass:${PATH}"
# Install Go
echo "Installing Go ${GO_VERSION}..."
curl -sLJO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
tar -C "${HOME}/.local" -xf "go${GO_VERSION}.linux-amd64.tar.gz"
- rm "go${GO_VERSION}.linux-amd64.tar.gz"
export PATH="${HOME}/.local/go/bin:${PATH}"
# Install Hugo
echo "Installing Hugo ${HUGO_VERSION}..."
- curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
- mkdir "${HOME}/.local/hugo"
- tar -C "${HOME}/.local/hugo" -xf "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
- rm "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
+ curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
+ mkdir -p "${HOME}/.local/hugo"
+ tar -C "${HOME}/.local/hugo" -xf "hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
export PATH="${HOME}/.local/hugo:${PATH}"
# Install Node.js
echo "Installing Node.js ${NODE_VERSION}..."
curl -sLJO "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz"
tar -C "${HOME}/.local" -xf "node-v${NODE_VERSION}-linux-x64.tar.xz"
- rm "node-v${NODE_VERSION}-linux-x64.tar.xz"
export PATH="${HOME}/.local/node-v${NODE_VERSION}-linux-x64/bin:${PATH}"
+ # Return to the project root
+ popd > /dev/null
+
# Verify installations
echo "Verifying installations..."
echo Dart Sass: "$(sass --version)"
@@ -98,12 +120,10 @@ Step 2
fi
# Build the site
- echo "Building the site"
+ echo "Building the site..."
hugo build --gc --minify --baseURL "https://${VERCEL_PROJECT_PRODUCTION_URL}"
-
}
- set -euo pipefail
main "$@"
```
diff --git a/docs/content/en/hugo-modules/nodejs-dependencies.md b/docs/content/en/hugo-modules/nodejs-dependencies.md
new file mode 100644
index 000000000..6adb18367
--- /dev/null
+++ b/docs/content/en/hugo-modules/nodejs-dependencies.md
@@ -0,0 +1,52 @@
+---
+title: Node.js dependencies
+description: How to manage Node dependencies in Hugo Modules.
+date: 2026-03-22
+categories: []
+keywords: []
+weight: 40
+---
+
+Hugo Modules that need Node packages (e.g. for Tailwind CSS) can declare those dependencies in a standard `package.json` at the module root. Hugo consolidates dependencies from all modules into an [npm workspace], so you only need a single `npm install` at the project level.
+
+[npm workspace]: https://docs.npmjs.com/cli/using-npm/workspaces
+
+## Declaring dependencies
+
+Each Hugo Module declares its Node dependencies in a `package.json` file in its root directory, using the standard `dependencies` and `devDependencies` fields.
+
+> [!note]
+> We improved this setup greatly in Hugo [v0.159.0](https://github.com/gohugoio/hugo/releases/tag/v0.159.0), but we kept the old `package.hugo.json` in the search path. Mostly to preserve as much backward compatibility as possible, but it may also be useful in some situations to reserve a separate set of Node dependencies for Hugo.
+
+## Consolidating with `hugo mod npm pack`
+
+Run [`hugo mod npm pack`] to collect Node dependencies from all modules and write them to `packages/hugoautogen/package.json`. Hugo also adds a `workspaces` entry to your project's root `package.json` pointing to this auto-generated package.
+
+The resulting project structure:
+
+```text
+project/
+├── package.json # your project's package.json (updated with workspaces entry)
+├── packages/
+│ └── hugoautogen/
+│ ├── package.json # auto-generated, contains consolidated module deps
+│ └── hugo_packagemeta.json # metadata and checksums for staleness detection
+└── ...
+```
+
+> [!note]
+In Hugo < v0.159.0 Hugo wrote the dependencies into your project's package.json, so if you have used `hugo mod npm pack` on your project using older Hugo versions, now is the time to do a spring cleaning of your project `package.json` file: Only direct Node dependencies needs to live in this file, all incoming dependencies from imported Hugo Modules gets written to `packages/hugoautogen/package.json`.
+
+When merging, the **topmost version, starting from the project, take precedence**. If a module declares `tailwindcss@4.1` but your project already has `tailwindcss@4.0`, the project version wins and the module dependency is excluded from the generated workspace package.
+
+## Staleness detection
+
+When Hugo detects that the npm dependency configuration has changed in one or more of the modules in use, you will get a warning in the console:
+
+```text
+WARN npm dependencies are out of sync, please run "hugo mod npm pack" (you may also want to run "npm install" after that)
+```
+
+This ensures you don't forget to re-run `hugo mod npm pack` after updating module versions.
+
+[`hugo mod npm pack`]: /commands/hugo_mod_npm_pack
diff --git a/docs/content/en/installation/windows.md b/docs/content/en/installation/windows.md
index 8563ab7ee..3cc6ee4a8 100644
--- a/docs/content/en/installation/windows.md
+++ b/docs/content/en/installation/windows.md
@@ -47,7 +47,85 @@ To uninstall the extended edition of Hugo:
winget uninstall --name "Hugo (Extended)"
```
-{{% include "/_common/installation/04-build-from-source.md" %}}
+## Build from source
+
+To build Hugo from source you must install:
+
+1. [Git]
+1. [Go] version 1.25.0 or later
+
+> [!note]
+> The Bash-style `KEY=VALUE cmd` syntax used in the macOS and Linux build-from-source instructions does not work in PowerShell or Command Prompt. Use the code block matching your shell.
+
+### Standard edition
+
+To build and install the standard edition:
+
+PowerShell:
+
+```powershell
+$env:CGO_ENABLED=0; go install github.com/gohugoio/hugo@latest
+```
+
+Command Prompt:
+
+```bat
+set CGO_ENABLED=0
+go install github.com/gohugoio/hugo@latest
+```
+
+### Deploy edition
+
+{{< new-in v0.159.2 />}}
+
+To build and install the deploy edition:
+
+PowerShell:
+
+```powershell
+$env:CGO_ENABLED=0; go install -tags withdeploy github.com/gohugoio/hugo@latest
+```
+
+Command Prompt:
+
+```bat
+set CGO_ENABLED=0
+go install -tags withdeploy github.com/gohugoio/hugo@latest
+```
+
+### Extended edition
+
+To build and install the extended edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
+
+PowerShell:
+
+```powershell
+$env:CGO_ENABLED=1; go install -tags extended github.com/gohugoio/hugo@latest
+```
+
+Command Prompt:
+
+```bat
+set CGO_ENABLED=1
+go install -tags extended github.com/gohugoio/hugo@latest
+```
+
+### Extended/deploy edition
+
+To build and install the extended/deploy edition, first install a C compiler such as [GCC] or [Clang] and then run the following command:
+
+PowerShell:
+
+```powershell
+$env:CGO_ENABLED=1; go install -tags extended,withdeploy github.com/gohugoio/hugo@latest
+```
+
+Command Prompt:
+
+```bat
+set CGO_ENABLED=1
+go install -tags extended,withdeploy github.com/gohugoio/hugo@latest
+```
> [!note]
> See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows.
@@ -66,5 +144,9 @@ Latest version available?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mar
[^2]: Easy if a previous version is still installed.
[Chocolatey]: https://chocolatey.org/
+[Clang]: https://clang.llvm.org/
+[GCC]: https://gcc.gnu.org/
+[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+[Go]: https://go.dev/doc/install
[Scoop]: https://scoop.sh/
[Winget]: https://learn.microsoft.com/en-us/windows/package-manager/
diff --git a/docs/content/en/methods/menu-entry/PageRef.md b/docs/content/en/methods/menu-entry/PageRef.md
index 8d4e53656..f75a4f6ec 100644
--- a/docs/content/en/methods/menu-entry/PageRef.md
+++ b/docs/content/en/methods/menu-entry/PageRef.md
@@ -79,7 +79,7 @@ Hugo render this HTML:
```
-In the above note that the `href` attribute of the second `anchor` element is blank because Hugo was unable to find the "services" page.
+In the above note that the `href` attribute of the second `anchor` element is blank because Hugo was unable to find the `services` page.
With this template code:
diff --git a/docs/content/en/methods/output-format/MediaType.md b/docs/content/en/methods/output-format/MediaType.md
index 45f6267a1..9283868bf 100644
--- a/docs/content/en/methods/output-format/MediaType.md
+++ b/docs/content/en/methods/output-format/MediaType.md
@@ -33,4 +33,4 @@ params:
### Type
-(`string`) Returns the the current format's media type.
+(`string`) Returns the current format's media type.
diff --git a/docs/content/en/methods/page/AllTranslations.md b/docs/content/en/methods/page/AllTranslations.md
index e34c8b745..6baeb407f 100644
--- a/docs/content/en/methods/page/AllTranslations.md
+++ b/docs/content/en/methods/page/AllTranslations.md
@@ -68,7 +68,7 @@ And this template:
{{ end }}
```
-Hugo will render this list on the "Book 1" page of each site:
+Hugo will render this list on the `book-1` page of each site:
```html
@@ -78,7 +78,7 @@ Hugo will render this list on the "Book 1" page of each site:
```
-On the "Book 2" page of the English and German sites, Hugo will render this:
+On the `book-2` page of the English and German sites, Hugo will render this:
```html
diff --git a/docs/content/en/methods/page/InSection.md b/docs/content/en/methods/page/InSection.md
index adca82d86..b56c92b97 100644
--- a/docs/content/en/methods/page/InSection.md
+++ b/docs/content/en/methods/page/InSection.md
@@ -32,7 +32,7 @@ content/
└── _index.md
```
-When rendering the "auction-1" page:
+When rendering the `auction-1` page:
```go-html-template
{{ with .Site.GetPage "/" }}
@@ -73,7 +73,7 @@ Inside of the `with` block, the [context](g) (the dot) is the section `Page` obj
{{ end }}
```
-The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+The result would be wrong when rendering the `auction-1` page because we are comparing the section page to itself.
> [!note]
> Use the `$` to get the context passed into the template.
diff --git a/docs/content/en/methods/page/IsAncestor.md b/docs/content/en/methods/page/IsAncestor.md
index fe1b78454..68d56ecbd 100644
--- a/docs/content/en/methods/page/IsAncestor.md
+++ b/docs/content/en/methods/page/IsAncestor.md
@@ -28,7 +28,7 @@ content/
└── _index.md
```
-When rendering the "auctions" page:
+When rendering the `auctions` page:
```go-html-template
{{ with .Site.GetPage "/" }}
@@ -69,7 +69,7 @@ Inside of the `with` block, the [context](g) (the dot) is the section `Page` obj
{{ end }}
```
-The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+The result would be wrong when rendering the `auction-1` page because we are comparing the section page to itself.
> [!note]
> Use the `$` to get the context passed into the template.
diff --git a/docs/content/en/methods/page/IsDescendant.md b/docs/content/en/methods/page/IsDescendant.md
index 6ee8d3c4f..1ccb79196 100644
--- a/docs/content/en/methods/page/IsDescendant.md
+++ b/docs/content/en/methods/page/IsDescendant.md
@@ -28,7 +28,7 @@ content/
└── _index.md
```
-When rendering the "auctions" page:
+When rendering the `auctions` page:
```go-html-template
{{ with .Site.GetPage "/" }}
@@ -69,7 +69,7 @@ Inside of the `with` block, the [context](g) (the dot) is the section `Page` obj
{{ end }}
```
-The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+The result would be wrong when rendering the `auction-1` page because we are comparing the section page to itself.
> [!note]
> Use the `$` to get the context passed into the template.
diff --git a/docs/content/en/methods/page/Language.md b/docs/content/en/methods/page/Language.md
index 26a40e5e0..0ee7a9284 100644
--- a/docs/content/en/methods/page/Language.md
+++ b/docs/content/en/methods/page/Language.md
@@ -39,7 +39,7 @@ weight = 2
{{< new-in 0.153.0 />}}
-(`bool`) Reports whether this is the [default language][].
+(`bool`) Reports whether this is the [default language](g).
```go-html-template
{{ .Language.IsDefault }} → true
@@ -103,13 +103,6 @@ Use [`Label`](#label) instead.
{{}}
-[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646
-[`direction`]: /configuration/languages/#direction
-[`label`]: /configuration/languages/#label
-[`locale`]: /configuration/languages/#locale
-[default language]: /quick-reference/glossary/#default-language
-[details]: /methods/site/language/
-
## Example
Use the code below to create a language selector, allowing users to navigate between the different translated versions of the current page.
@@ -133,3 +126,9 @@ Use the code below to create a language selector, allowing users to navigate bet
{{ end }}
```
+
+[`direction`]: /configuration/languages/#direction
+[`label`]: /configuration/languages/#label
+[`locale`]: /configuration/languages/#locale
+[details]: /methods/site/language/
+[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646
diff --git a/docs/content/en/methods/page/Translations.md b/docs/content/en/methods/page/Translations.md
index da3715cf1..1310bdab1 100644
--- a/docs/content/en/methods/page/Translations.md
+++ b/docs/content/en/methods/page/Translations.md
@@ -68,7 +68,7 @@ And this template:
{{ end }}
```
-Hugo will render this list on the "Book 1" page of the English site:
+Hugo will render this list on the `book-1` page of the English site:
```html
@@ -77,7 +77,7 @@ Hugo will render this list on the "Book 1" page of the English site:
```
-Hugo will render this list on the "Book 2" page of the English site:
+Hugo will render this list on the `book-2` page of the English site:
```html
diff --git a/docs/content/en/methods/site/Language.md b/docs/content/en/methods/site/Language.md
index 6f2f013e7..73f097dda 100644
--- a/docs/content/en/methods/site/Language.md
+++ b/docs/content/en/methods/site/Language.md
@@ -39,7 +39,7 @@ weight = 2
{{< new-in 0.153.0 />}}
-(`bool`) Reports whether this is the [default language][].
+(`bool`) Reports whether this is the [default language](g).
```go-html-template
{{ .Site.Language.IsDefault }} → true
@@ -118,5 +118,4 @@ Some of the methods above are commonly used in a base template as attributes for
[`direction`]: /configuration/languages/#direction
[`label`]: /configuration/languages/#label
[`locale`]: /configuration/languages/#locale
-[default language]: /quick-reference/glossary/#default-language
[details]: /methods/page/language/
diff --git a/docs/content/en/methods/site/MainSections.md b/docs/content/en/methods/site/MainSections.md
index 0df8de649..8137bbc5d 100644
--- a/docs/content/en/methods/site/MainSections.md
+++ b/docs/content/en/methods/site/MainSections.md
@@ -23,7 +23,7 @@ Template:
If `mainSections` is not defined in your project configuration, this method returns a slice with one element---the top-level section with the most pages.
-With this content structure, the "films" section has the most pages:
+With this content structure, the `films` section has the most pages:
```text
content/
diff --git a/docs/content/en/methods/site/Menus.md b/docs/content/en/methods/site/Menus.md
index 0c8509e92..082f87393 100644
--- a/docs/content/en/methods/site/Menus.md
+++ b/docs/content/en/methods/site/Menus.md
@@ -69,7 +69,7 @@ When viewing the home page, the result is:
```
-When viewing the "books" page, the result is:
+When viewing the `books` page, the result is:
```html