Releases: gohugoio/hugo
v0.163.0
The main topic in this release is improvements to the AVIF image handling that we introduced in v0.162.0. See the docs for details, but:
- We have turned down the default
qualityfor AVIF to 60. Turns out, JPEG/WebP with quality 75 is comparable to AVIF with quality 60. You can now also set quality per image format in your project config (and also per image processed if needed). - We have added a
hintto the AVIF with the same values as forWEBP. Forlossycompression, the photo/picture hints (and the default) encodes with YUV420 chroma subsampling instead of YUV444, keeping 444 for text/icon/drawing. This greatly reduces the memory needed to encode these images.
Improvements
- resources/jsconfig: Remove deprecated baseUrl setting ff2903a @bep #14991 #14996
- all: Adjust tests for deprecated link and image render hook settings ca68936 @jmooring
- all: Run go fix ./... 781fabf @bep
- pagesfromdata: Use relative path for content adapter template metrics 1d018ef @anupamojha-eng #14999
- ci: Re-add macos-latest to the test matrix 121bc6c @bep
- images: Deprecate Imaging.Compression and move it down to webp and avif configs cf18b82 @bep #14998
- Only support the latest Go version 98ad9b3 @bep #14997
- page: Add IsBranch and deprecate IsNode b89e7fe @bep #11574
- images: Force cache invalidation for AVIF target e8fefc8 @bep #14990
- images: Add a per-format AVIF hint setting a043d3e @bep #14992
- images: Make AVIF chroma subsampling content-aware via the hint 341f575 @bep #14987
- Cap AVIF lossy quality at 99 248241b @bep #14981
- config: Deprecate the glogal imaging quality setting 4e47d95 @bep #14979
- images: Make 60 the default quality for AVIF 03b4b54 @bep #14979
- livereload: Disconnect from websocket server on pageswap 79be053 @bep #14983
- tpl/tplimpl/embedded: Prevent leading newline in sitemap template 0f44046 @bep #14977
- images: Recover from memory alloc errors in WASM image processors 4e17421 @bep #14985
- images: Add quality setting per image format b01ecd4 @bep #14957
- misc: Remove duplicate words in comments 45c00b7 @jmooring #14936 #14950 #14965
- Add some PNG to AVIF golden test cases 28d882a @bep
Dependency Updates
- build(deps): bump github.com/bits-and-blooms/bitset 0d29fc8 @dependabot[bot]
- build(deps): bump github.com/tetratelabs/wazero bb57404 @dependabot[bot]
- build(deps): bump github.com/rogpeppe/go-internal from 1.14.1 to 1.15.0 7d1b1fb @dependabot[bot]
- build(deps): bump github.com/getkin/kin-openapi from 0.138.0 to 0.139.0 77a1147 @dependabot[bot]
v0.162.1
v0.162.0
The notable new feature in this release is support for AVIF images (both encoder and decoder). There's a demo site set up that demonstrates the difference between HDR AVIF and SDR JPEG images. Note that that demo is only really interesting if viewed on an HDR capable screen (e.g. Apple Retina).
Security fixes
There are some notable security fixes in this release.
Security fixes in Go
This release upgrades from Go 1.26.1 to 126.3, which brings a set of security fixes. Some relevant for Hugo are:
- XSS in html/template (CVE-2026-39826 & CVE-2026-39823): Two separate vulnerabilities where escaper bypasses in html/template could lead to Cross-Site Scripting (XSS).
- html/template: Fixes an issue where JS template literal contexts were incorrectly tracked across template branches, which could lead to improper content escaping.
Security fixes and hardening in Hugo
The following changes either fix a concrete issue or reduce the default attack surface of hugo builds.
- Disallow
text/htmlcontent files by default (e41a064). A newsecurity.allowContentpolicy gates which content media types may be used for pages under/content.text/htmlis denied by default; sites that rely on hand-authored or adapter-emitted HTML content can opt back in withsecurity.allowContent = ['.*']. - Re-check
security.http.urlson every redirect hop inresources.GetRemote(86fbb0f). - Reject symlinked entries in
resources.Get(f8b5fa0).
We will update this section later with links to CVEs where applicable.
All changes
- hugolib: Fix Page.GitInfo for modules with go.mod in a repo subdirectory df54219 @bep #14942
- Fix typo in CONTRIBUTING.md 4bc7cae @bep
- resources: Fix the :counter placeholder 5d51b82 @jmooring #14921
- commands: Fix import from Jekyll 81d7762 @jmooring #14795 #14906
- Fix prevention of direct symlink reads in resources.Get f8b5fa0 @bep
- commands: Fix github-dark chromastyles 88d838a @xndvaz #14831
- Disallow HTML content by default e41a064 @bep
- Add image processing support for AVIF 90d9f81 @bep #7837
- config: Preserve intentionally empty maps 80e6084 @jmooring #14944
- hugolib: Merge existing hugo_stats.json when renderSegments is set aeb9a5c @bep #14939
- all: Replace RWMutex struct caches with ConcurrentMap c4bbc28 @bep
- tpl/tplimpl: Consolidate and improve embedded template integration tests d8c7021 @jmooring #14932
- parser: Drop empty sub maps from hugo config output ee4f1ac @bep #14855
- markup/highlight: Allow overriding type and code via options b613365 @bep #11872
- Update AI assistance disclosure requirements d2c821b @bep
- hugolib: Use AllTranslated in IsTranslated 4ed7600 @bep
- tpl: Simplify sitemap template cbe4339 @bep #14912
- tpl: Use AllTranslations in sitemap template 6475d30 @bep #14912 #14917
- tpl/collections: Make dict return nil when no values are provided 67aede4 @bep
- Sync Go template package to 1.26.3 87f194b @bep #14897
- Upgrade to Go 1.26.3 d81e3c2 @bep #14897
- ci: Check embedded template formatting with gotmplfmt 7c65a4d @bep
- tpl: Run gotmplfmt -w . d31a927 @bep
- markup/goldmark/codeblocks: Always split Chroma options into .Options c36608c @jmooring #14909
- hugolib: Allow empty params front matter 2f361a8 @xndvaz #14886
- common/hmaps: Merge slice-valued module config into site config 5559263 @jmooring #13869
- tpl: Use GetMatch for both local and global image resources 656fc04 @bep #14062
- Revert "markup/tableofcontents: Skip empty TOC levels" a20cb5b @bep #14898
- tpl/templates: Reject Defer inside partialCached 4d775cb @bep #13492
- common/hexec: Make NODE_PATH a fallback for ESM bare imports ae7bf74 @bep #13987
- config: Allow repeating the root key in /config files ba5d812 @bep #12899 #14882
- Revise test naming guidelines in AGENTS.md be4a0df @bep
- Update AGENTS.md e4cf565 @bep
- js: Return error for missing batch imports 9e64953 @xndvaz #13737
- resources/images: Keep smart crop target size f0cfc28 @xndvaz #13688
- testing: Use synctest where relevant 16e854a @bep
- security: Validate redirects against security.http.urls 86fbb0f @bep #14871
- markup/tableofcontents: Skip empty TOC levels 7d4af7a @xndvaz #7128
- Fall back to hugo.buildDate in hugo.BuildDate() in non-vcs builds 28147cb @bep #14862
- css: Make css.Build's file-loader URLs absolute to web context root e51e761 @bep #14849
- hugolib: Don't warn about lang/kind/path coming from cascade.params 7011239 @bep #14848
- markup/goldmark: Unwrap inner HTML for plain code blocks 694906f @cyphercodes #14820
- tpl/tplimpl: Extend page image lookup to include global resources d27b9c0 @ogulcanaydogan #14062
- security: Allow hostnames starting with digits in default http.urls 62cef36 @bep #14837
- commands: Improve description of command flags ff22c62 @jmooring #14817
- build(deps): bump golang.org/x/net from 0.54.0 to 0.55.0 4f444c8 @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.40.0 to 0.41.0 fe6c726 @dependabot[bot]
- build(deps): bump github.com/getkin/kin-openapi from 0.137.0 to 0.138.0 6a2a038 @dependabot[bot]
- build(deps): bump github.com/JohannesKaufmann/html-to-markdown/v2 cf1de59 @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.39.0 to 0.40.0 97f990c @dependabot[bot]
- build(deps): bump golang.org/x/tools from 0.44.0 to 0.45.0 b99634e @dependabot[bot]
- build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 fdd977e @dependabot[bot]
- build(deps): bump github.com/pelletier/go-toml/v2 from 2.3.0 to 2.3.1 123018d @dependabot[bot]
- deps: Upgrade to Chroma v2.24.1 b88fa8c @bep #14839
v0.161.1
What's Changed
- resources: Honor Retry-After header in resources.GetRemote retries c4eba92 @bep #14828
- warpc: Move to parson.c in https://github.com/kgabis/parson 8b40a96 @bep #14823
- config/security: Add AllowChildProcess to security.node.permissions d65af84 @bep #14824
- config/security: Restrict default http.urls "@" deny to userinfo 454450a @bep #14825
v0.161.0
This release contains two security hardening fixes:
- We now run the Node tools PostCSS, Babel and TailwindCSS, by default, with the
--permissionflag with the permissions defined in security.node.permissions. This means that you need Node >= 22 installed and thatcss.TailwindCSSnow requires that the Tailwind CSS CLI must be installed as a Node.js package. The standalone executable is no longer supported - We have made the defaults in security.http.urls more restrictive.
But there are some notable new features, as well:
Nested vars support in css.Build and css.Sass
A practical example in css.Build would be to have something like this in hugo.toml:
[params.style]
primary = "#000000"
background = "#ffffff"
[params.style.dark]
primary = "#ffffff"
background = "#000000"And in the stylesheet:
@import "hugo:vars";
@import "hugo:vars/dark" (prefers-color-scheme: dark);
:root {
color-scheme: light dark;
}Slice-based permalinks config
The permalinks configuration is now much more flexible (the old setup still works). It uses the same target matchers as in the cascade config, meaning you can now do:
permalinks:
- target:
kind: page
path: "/books/**"
pattern: /books/:year/:slug/
- target:
kind: section
path: "/{books,books/**}"
pattern: /libros/:sections[1:]
- target:
kind: page
pattern: /other/:slug/The above example isn't great, but it at least shows the gist of it.
A more flexible scheme for identifiers in filenames
What we had before was e.g. content/mypost.en.md which told Hugo that the content files was in English. With the new setup you could also name the file content/mypost._language_en_.md. This alone doesn't sound very useful, but this allows you to use more prefixes:
| Prefix | Description | Relevant for |
|---|---|---|
| language_ | Language | Content and layout files. |
| role_ | Role | Content and layout files. |
| version_ | Version | Content and layout files. |
| outputformat_ | Output format | Layout files. |
| mediatype_ | Media type | Layout files. |
| kind_ | Page kind | Layout files. |
| layout_ | Layout | Layout files. |
All Changes
- langs/i18n: Fix translation lookup when using language variants 72b85d5 @jmooring #7982
- create: Fix non-deterministic conflict detection in hugo new content 6436deb @jmooring #12602 #12786 #14112 #14769
- commands: Fix environment isolation for configuration settings 1eea9fb @jmooring #14763
- Fix filename dimension identifiers (role_X, version_X) to replace mount config 8d6145f @bep #14756
- Fix it so we never auto-fallback to page resources in other roles/versions 9747724 @bep #14749 #14752
- css: Support nested hugo:vars/ imports 7622dd8 @bep #14705
- github: Update GitHub actions versions 0814059 @bep #14810
- hugolib: Do not render aliases if the page is not rendered 8920d56 @jmooring #14807
- langs/i18n: Improve default content language fallback 633cc77 @jmooring #14243
- helpers: Remove unused code 4c40c6d @bep
- common/constants: Remove unused consts d2594db @bep
- common/paths: Remove unused code ab2de51 @bep
- tests: Update Ruby setup action to v1.305.0 75f6183 @jmooring
- langs: Use Language.Locale as primary localization key 1b7495b @jmooring #9109
- config/security: Add "! " negation to Whitelist, harden default http.urls 79f030b @bep #14792
- Harden Node tool execution with --permission flag a54c398 @bep #7287
- tpl/collections: Honor the Eqer interface in where comparisons f5fce93 @bep #14777
- modules: Ignore non-require blocks in go.mod rewrite 4169c1f @bep #14783
- Replace the concurrent map with an identical upstream version 7574e35 @bep
- Add slice-based permalinks config with PageMatcher target 017a7cd @bep #14744
- commands: Add missing import e3413d9 @bep
- Revert "common/hugo: Deprecate extended and extended_withdeploy editions" b01cc14 @bep #14771
- Adjust the SECURITY.md slightly 8ee19ff @bep
- resources/page: Add passing test for Issue #14325 0d58e42 @jmooring
- Add a more flexible filename identifier scheme that also allows setting roles and versions (#14754) ce2a156 @bep #14750
- common/hugo: Deprecate extended and extended_withdeploy editions a17bdbc @jmooring #14696
- parser/pageparser: Add a parser fuzz test 8f94d65 @bep
- Replace deprecated .Site.Sites/.Page.Sites with hugo.Sites intests 90d8bf3 @bep
- agents: Add a note about having the issue ID in test names bbb42b5 @bep
- build(deps): bump github.com/getkin/kin-openapi from 0.135.0 to 0.137.0 d4ae662 @dependabot[bot]
- build(deps): bump github.com/mattn/go-isatty from 0.0.21 to 0.0.22 9ede5fb @dependabot[bot]
- build(deps): bump github.com/tdewolff/minify/v2 from 2.24.12 to 2.24.13 833a878 @dependabot[bot]
- build(deps): bump github.com/magefile/mage from 1.17.1 to 1.17.2 4c03129 @dependabot[bot]
- deps: Upgrade github.com/bep/imagemeta v0.17.1 => v0.17.2 080970b @bep
- build(deps): bump github.com/aws/aws-sdk-go-v2/service/cloudfront (#14789) 896bc89 @dependabot[bot]
- build(deps): bump github.com/mattn/go-isatty from 0.0.20 to 0.0.21 (#14788) 100dde5 @dependabot[bot]
- build(deps): bump github.com/bep/mclib (#14787) bdebb79 @dependabot[bot]
- build(deps): bump google.golang.org/api from 0.267.0 to 0.276.0 52123ae @dependabot[bot]
- build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.41.5 to 1.41.6 38b8afd @dependabot[bot]
- build(deps): bump github.com/getkin/kin-openapi from 0.134.0 to 0.135.0 (#14781) 9276660 @dependabot[bot]
- build(deps): bump github.com/bep/goportabletext from 0.1.0 to 0.2.0 (#14779) 790f408 @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.38.0 to 0.39.0 (#14780) de6955b @dependabot[bot]
- deps: Upgrade github.com/bep/imagemeta v0.17.0 => v0.17.1 (#14775) a77bd52 @bep #14758
- build(deps): bump golang.org/x/tools from 0.43.0 to 0.44.0 547ab29 @dependabot[bot]
- build(deps): bump github.com/evanw/esbuild from 0.27.4 to 0.28.0 9a5c7e0 @dependabot[bot]
- build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.41.1 to 1.41.5 6613b08 @dependabot[bot]
- build(deps): bump github.com/pelletier/go-toml/v2 from 2.2.4 to 2.3.0 582c26e @dependabot[bot]
- build(deps): bump github.com/tdewolff/minify/v2 from 2.24.11 to 2.24.12 a4f2a8a @dependabot[bot]
v0.160.1
What's Changed
- Fix panic when passthrough elements are used in headings 8b00030 @bep #14677
- Fix panic on edit of legacy mapped template names that's also a valid path in the new setup c485516 @bep #14740
- Fix RenderShortcodes leaking context markers when indented 161d0d4 @bep #12457
- Strip nested page context markers from standalone RenderShortcodes 45e4596 @bep #14732
- Rename deprecated cascade._target to cascade.target in tests 58927aa @bep
- Fix auto-creation of root sections in multilingual sites ce009e3 @bep #14681
- readme: Fix links 0755872 @chicks-net
v0.160.0
Now you can inject CSS vars, e.g. from the configuration, into your stylesheets when building with css.Build. Also, now all the render hooks has a .Position method, now also more accurate and effective.
Bug fixes
- Fix some recently introduced Position issues 4e91e14 @bep #14710
- markup/goldmark: Fix double-escaping of ampersands in link URLs dc9b51d @bep #14715
- tpl: Fix stray quotes from partial decorator in script context 43aad71 @bep #14711
Improvements
- all: Replace NewIntegrationTestBuilder with Test/TestE/TestRunning 481baa0 @bep
- tpl/css: Support @import "hugo:vars" for CSS custom properties in css.Build 5d09b5e @bep #14699
- Improve and extend .Position handling in Goldmark render hooks 303e443 @bep #14663
- markup/goldmark: Clean up test 638262c @bep
Dependency Updates
- build(deps): bump github.com/magefile/mage from 1.16.1 to 1.17.1 bf6e35a @dependabot[bot]
- build(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 0eda24e @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.37.0 to 0.38.0 beb57a6 @dependabot[bot]
Documentation
v0.159.2
Note that the security fix below is not a potential threat if you either:
- Trust your Markdown content files.
- Have custom render hook template for links and images.
EDIT IN: This release also adds release archives for non-extended-withdeploy builds.
What's Changed
v0.159.1
The regression fixed in this release isn't new, but it's so subtle that we thought we'd release this sooner rather than later. For some time now, the minifier we use have stripped namespaced attributes in SVGs, which broke dynamic constructs using e.g. AlpineJS' x-bind: namespace (library used by Hugo's documentation site).
To fix this, the upstream library has hadded a keepNamespaces slice option. It was not possible to find a default that would make all happy, so we opted for an option that at least would make AlpineJS sites work out of the box:
[minify.tdewolff.svg]
keepNamespaces = ['', 'x-bind']What's Changed
v0.159.0
This release greatly improves and simplifies management of Node.js/npm dependencies in a multi-module setup. See this page for more information.
Note
- Replace deprecated site.Data with hugo.Data in tests a8fca59 @bep
- Replace deprecated excludeFiles and includeFiles with files in tests 182b104 @bep
- Replace deprecated :filename with :contentbasename in the permalinks test eb11c3d @bep
Bug fixes
Improvements
- create: Return error instead of panic when page not found 807cae1 @mango766 #14112
- commands: Preserve non-content files in convert output c4fb61d @xndvaz #4621
- npm: Use workspaces to simplify
hugo mod npm packd88a29e @bep - commands: Close cpu profile file when StartCPUProfile fails 9dd9c76 @buley
- Remove the AI Watchdog workflow for now 3315a86 @bep
- Remove 'bep' from PR user logins skip list 3824484 @bep
- tpl/tplimpl: Comment out the Vimeo simple shortcode tests 7813c5c @bep #14649
Dependency Updates
- build(deps): bump github.com/olekukonko/tablewriter from 1.1.3 to 1.1.4 (#14641) 3ff9b7f @dependabot[bot]
- build(deps): bump github.com/yuin/goldmark from 1.7.16 to 1.7.17 be93ccd @dependabot[bot]
- build(deps): bump github.com/magefile/mage from 1.15.0 to 1.16.1 2669bca @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.36.0 to 0.37.0 753d447 @dependabot[bot]
- build(deps): bump google.golang.org/grpc from 1.78.0 to 1.79.3 4f39d72 @dependabot[bot]