hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit b80853de90b10171155b8f3fde47d64ec7bfa0dd
parent 423594e03a906ef4150f433666ff588b022c3c92
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Thu, 17 Mar 2022 22:03:27 +0100

all: gofmt -w -r 'interface{} -> any' .

Updates #9687

Diffstat:
Mbufferpool/bufpool.go | 2+-
Mcache/namedmemcache/named_cache.go | 4++--
Mcache/namedmemcache/named_cache_test.go | 6+++---
Mcodegen/methods.go | 2+-
Mcodegen/methods_test.go | 2+-
Mcommands/commandeer.go | 6+++---
Mcommands/config.go | 14+++++++-------
Mcommands/convert.go | 2+-
Mcommands/deploy.go | 1+
Mcommands/helpers.go | 6+++---
Mcommands/import_jekyll.go | 10+++++-----
Mcommands/import_jekyll_test.go | 46+++++++++++++++++++++++-----------------------
Mcommands/limit_others.go | 1+
Mcommands/list.go | 10+++++-----
Mcommands/nodeploy.go | 1+
Mcommands/release.go | 1+
Mcommands/release_noop.go | 1+
Mcommands/server.go | 4++--
Mcommon/collections/append.go | 10+++++-----
Mcommon/collections/append_test.go | 38+++++++++++++++++++-------------------
Mcommon/collections/collections.go | 2+-
Mcommon/collections/slice.go | 8++++----
Mcommon/collections/slice_test.go | 32++++++++++++++++----------------
Mcommon/herrors/errors.go | 2+-
Mcommon/hexec/exec.go | 8++++----
Mcommon/hreflect/helpers.go | 2+-
Mcommon/htime/time.go | 2+-
Mcommon/hugo/vars_extended.go | 1+
Mcommon/hugo/vars_regular.go | 1+
Mcommon/hugo/version.go | 10+++++-----
Mcommon/loggers/ignorableLogger.go | 4++--
Mcommon/loggers/loggers.go | 40++++++++++++++++++++--------------------
Mcommon/maps/maps.go | 38+++++++++++++++++++-------------------
Mcommon/maps/maps_test.go | 42+++++++++++++++++++++---------------------
Mcommon/maps/params.go | 22+++++++++++-----------
Mcommon/maps/params_test.go | 14+++++++-------
Mcommon/maps/scratch.go | 28++++++++++++++--------------
Mcommon/maps/scratch_test.go | 8++++----
Mcommon/math/math.go | 2+-
Mcommon/math/math_test.go | 6+++---
Mcommon/paths/path_test.go | 2+-
Mcommon/text/position.go | 2+-
Mcommon/text/transform.go | 2+-
Mcommon/types/convert.go | 14+++++++-------
Mcommon/types/convert_test.go | 2+-
Mcommon/types/types.go | 12++++++------
Mcommon/types/types_test.go | 2+-
Mcommon/urls/ref.go | 4++--
Mcompare/compare.go | 6+++---
Mconfig/commonConfig.go | 4++--
Mconfig/commonConfig_test.go | 4++--
Mconfig/compositeConfig.go | 8++++----
Mconfig/configLoader.go | 12++++++------
Mconfig/configProvider.go | 8++++----
Mconfig/defaultConfigProvider.go | 12++++++------
Mconfig/defaultConfigProvider_test.go | 76++++++++++++++++++++++++++++++++++++++--------------------------------------
Mconfig/docshelper.go | 2+-
Mconfig/security/securityConfig.go | 8++++----
Mconfig/services/servicesConfig_test.go | 1-
Mcreate/content.go | 2+-
Mcreate/content_test.go | 4++--
Mdeploy/cloudfront.go | 1+
Mdeploy/deploy.go | 1+
Mdeploy/deployConfig.go | 2+-
Mdeploy/deploy_azure.go | 1+
Mdeploy/deploy_test.go | 9+++++----
Mdeploy/google.go | 1+
Mdeps/deps.go | 6+++---
Mdocshelper/docs.go | 4++--
Mhelpers/content.go | 2+-
Mhelpers/docshelper.go | 4++--
Mhelpers/general.go | 26+++++++++++++-------------
Mhelpers/testhelpers_test.go | 2+-
Mhtesting/hqt/checkers.go | 8++++----
Mhugofs/fileinfo.go | 2+-
Mhugofs/rootmapping_fs.go | 12++++++------
Mhugolib/alias_test.go | 12++++++------
Mhugolib/cascade_test.go | 50+++++++++++++++++++++++++-------------------------
Mhugolib/collections.go | 4++--
Mhugolib/config_test.go | 34+++++++++++++++++-----------------
Mhugolib/configdir_test.go | 4++--
Mhugolib/content_map.go | 52++++++++++++++++++++++++++--------------------------
Mhugolib/content_map_page.go | 26+++++++++++++-------------
Mhugolib/datafiles_test.go | 98++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mhugolib/embedded_shortcodes_test.go | 24++++++++++++------------
Mhugolib/filesystems/basefs_test.go | 16++++++++--------
Mhugolib/hugo_sites.go | 32++++++++++++++++----------------
Mhugolib/hugo_sites_build_test.go | 10+++++-----
Mhugolib/image_test.go | 2+-
Mhugolib/language_content_dir_test.go | 2+-
Mhugolib/page.go | 10+++++-----
Mhugolib/page__content.go | 2+-
Mhugolib/page__data.go | 2+-
Mhugolib/page__meta.go | 40++++++++++++++++++++--------------------
Mhugolib/page__new.go | 6+++---
Mhugolib/page__paginator.go | 4++--
Mhugolib/page__per_output.go | 20++++++++++----------
Mhugolib/page__ref.go | 14+++++++-------
Mhugolib/page__tree.go | 6+++---
Mhugolib/page_test.go | 30+++++++++++++++---------------
Mhugolib/page_unwrap.go | 4++--
Mhugolib/page_unwrap_test.go | 2+-
Mhugolib/pagebundler_test.go | 16++++++++--------
Mhugolib/pages_capture_test.go | 4++--
Mhugolib/pages_language_merge_test.go | 2+-
Mhugolib/pages_process.go | 14+++++++-------
Mhugolib/paths/paths_test.go | 6+++---
Mhugolib/resource_chain_test.go | 2+-
Mhugolib/shortcode.go | 30+++++++++++++++---------------
Mhugolib/shortcode_test.go | 16++++++++--------
Mhugolib/site.go | 36++++++++++++++++++------------------
Mhugolib/site_output.go | 2+-
Mhugolib/site_output_test.go | 16++++++++--------
Mhugolib/site_render.go | 2+-
Mhugolib/site_test.go | 10+++++-----
Mhugolib/sitemap_test.go | 2+-
Mhugolib/testhelpers_test.go | 10+++++-----
Mlangs/config.go | 4++--
Mlangs/i18n/i18n.go | 12++++++------
Mlangs/i18n/i18n_test.go | 26+++++++++++++-------------
Mlangs/language.go | 16++++++++--------
Mlazy/init.go | 24++++++++++++------------
Mlazy/init_test.go | 20++++++++++----------
Mmagefile.go | 6+++---
Mmarkup/blackfriday/blackfriday_config/config.go | 2+-
Mmarkup/blackfriday/convert_test.go | 2+-
Mmarkup/converter/converter.go | 4++--
Mmarkup/converter/hooks/hooks.go | 14+++++++-------
Mmarkup/goldmark/codeblocks/render.go | 4++--
Mmarkup/goldmark/convert_test.go | 6+++---
Mmarkup/goldmark/render_hooks.go | 10+++++-----
Mmarkup/goldmark/toc_test.go | 2+-
Mmarkup/highlight/config.go | 12++++++------
Mmarkup/highlight/highlight.go | 8++++----
Mmarkup/internal/attributes/attributes.go | 20++++++++++----------
Mmarkup/markup_config/config.go | 4++--
Mmarkup/markup_config/config_test.go | 16++++++++--------
Mmedia/docshelper.go | 2+-
Mmedia/mediaType.go | 2+-
Mmedia/mediaType_test.go | 14+++++++-------
Mmetrics/metrics.go | 10+++++-----
Mmetrics/metrics_test.go | 4++--
Mminifiers/config.go | 2+-
Mminifiers/config_test.go | 6+++---
Mminifiers/minifiers_test.go | 24++++++++++++------------
Mmodules/collect.go | 4++--
Mmodules/config.go | 6+++---
Mmodules/npm/package_builder.go | 28++++++++++++++--------------
Mmodules/npm/package_builder_test.go | 4++--
Mnavigation/menu.go | 4++--
Moutput/docshelper.go | 4++--
Moutput/outputFormat.go | 6+++---
Moutput/outputFormat_test.go | 20++++++++++----------
Mparser/frontmatter.go | 4++--
Mparser/frontmatter_test.go | 16++++++++--------
Mparser/lowercase_camel_json.go | 2+-
Mparser/metadecoders/decoder.go | 72++++++++++++++++++++++++++++++++++++------------------------------------
Mparser/metadecoders/decoder_test.go | 98++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mparser/metadecoders/format_test.go | 2+-
Mparser/pageparser/item.go | 2+-
Mparser/pageparser/pagelexer.go | 2+-
Mparser/pageparser/pageparser.go | 2+-
Mrelated/inverted_index.go | 2+-
Mreleaser/github.go | 2+-
Mresources/errorResource.go | 6+++---
Mresources/image.go | 2+-
Mresources/image_extended_test.go | 1+
Mresources/image_test.go | 4++--
Mresources/images/color_test.go | 2+-
Mresources/images/config.go | 4++--
Mresources/images/config_test.go | 18+++++++++---------
Mresources/images/exif/exif.go | 12++++++------
Mresources/images/filters.go | 32++++++++++++++++----------------
Mresources/images/image.go | 2+-
Mresources/images/webp/webp.go | 1+
Mresources/images/webp/webp_notavailable.go | 1+
Mresources/internal/key.go | 4++--
Mresources/page/page.go | 25++++++++++++-------------
Mresources/page/page_data.go | 2+-
Mresources/page/page_lazy_contentprovider.go | 6+++---
Mresources/page/page_marshaljson.autogen.go | 4++--
Mresources/page/page_matcher.go | 4++--
Mresources/page/page_matcher_test.go | 14+++++++-------
Mresources/page/page_nop.go | 30+++++++++++++++---------------
Mresources/page/pagegroup.go | 16++++++++--------
Mresources/page/pagemeta/page_frontmatter.go | 8++++----
Mresources/page/pagemeta/page_frontmatter_test.go | 14+++++++-------
Mresources/page/pagemeta/pagemeta.go | 2+-
Mresources/page/pagemeta/pagemeta_test.go | 14+++++++-------
Mresources/page/pages.go | 8++++----
Mresources/page/pages_language_merge.go | 4++--
Mresources/page/pages_related.go | 4++--
Mresources/page/pages_related_test.go | 6+++---
Mresources/page/pages_sort.go | 4++--
Mresources/page/pages_sort_test.go | 12++++++------
Mresources/page/pages_test.go | 4++--
Mresources/page/pagination.go | 14+++++++-------
Mresources/page/pagination_test.go | 4++--
Mresources/page/site.go | 8++++----
Mresources/page/testhelpers_test.go | 38+++++++++++++++++++-------------------
Mresources/page/weighted.go | 4++--
Mresources/postpub/fields.go | 8++++----
Mresources/postpub/fields_test.go | 2+-
Mresources/postpub/postpub.go | 14+++++++-------
Mresources/resource.go | 20++++++++++----------
Mresources/resource/params.go | 2+-
Mresources/resource/resource_helpers.go | 10+++++-----
Mresources/resource/resources.go | 2+-
Mresources/resource/resourcetypes.go | 8++++----
Mresources/resource_cache.go | 16++++++++--------
Mresources/resource_factories/create/remote.go | 8++++----
Mresources/resource_factories/create/remote_test.go | 12++++++------
Mresources/resource_metadata.go | 4++--
Mresources/resource_metadata_test.go | 24++++++++++++------------
Mresources/resource_spec.go | 2+-
Mresources/resource_test.go | 2+-
Mresources/resource_transformers/babel/babel.go | 10+++++-----
Mresources/resource_transformers/htesting/testhelpers.go | 2+-
Mresources/resource_transformers/integrity/integrity_test.go | 2+-
Mresources/resource_transformers/js/build.go | 4++--
Mresources/resource_transformers/js/options.go | 8++++----
Mresources/resource_transformers/js/options_test.go | 2+-
Mresources/resource_transformers/postcss/postcss.go | 6+++---
Mresources/resource_transformers/postcss/postcss_test.go | 4++--
Mresources/resource_transformers/templates/execute_as_template.go | 4++--
Mresources/resource_transformers/tocss/dartsass/client.go | 4++--
Mresources/resource_transformers/tocss/dartsass/transform.go | 2+-
Mresources/resource_transformers/tocss/scss/client.go | 2+-
Mresources/resource_transformers/tocss/scss/client_extended.go | 1+
Mresources/resource_transformers/tocss/scss/client_notavailable.go | 1+
Mresources/resource_transformers/tocss/scss/tocss.go | 1+
Mresources/testhelpers_test.go | 2+-
Mresources/transform.go | 18+++++++++---------
Mresources/transform_test.go | 6+++---
Msource/content_directory_test.go | 2+-
Msource/sourceSpec.go | 2+-
Mtpl/cast/cast.go | 8++++----
Mtpl/cast/cast_test.go | 12++++++------
Mtpl/cast/docshelper.go | 2+-
Mtpl/cast/init.go | 2+-
Mtpl/collections/append.go | 2+-
Mtpl/collections/append_test.go | 18+++++++++---------
Mtpl/collections/apply.go | 12++++++------
Mtpl/collections/apply_test.go | 8++++----
Mtpl/collections/collections.go | 66+++++++++++++++++++++++++++++++++---------------------------------
Mtpl/collections/collections_test.go | 300++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtpl/collections/complement.go | 2+-
Mtpl/collections/complement_test.go | 34+++++++++++++++++-----------------
Mtpl/collections/index.go | 4++--
Mtpl/collections/index_test.go | 34+++++++++++++++++-----------------
Mtpl/collections/init.go | 2+-
Mtpl/collections/merge.go | 4++--
Mtpl/collections/merge_test.go | 90++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtpl/collections/reflect_helpers.go | 8++++----
Mtpl/collections/sort.go | 4++--
Mtpl/collections/sort_test.go | 24++++++++++++------------
Mtpl/collections/symdiff.go | 4++--
Mtpl/collections/symdiff_test.go | 8++++----
Mtpl/collections/where.go | 10+++++-----
Mtpl/collections/where_test.go | 74+++++++++++++++++++++++++++++++++++++-------------------------------------
Mtpl/compare/compare.go | 22+++++++++++-----------
Mtpl/compare/compare_test.go | 102++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtpl/compare/init.go | 2+-
Mtpl/crypto/crypto.go | 8++++----
Mtpl/crypto/crypto_test.go | 20++++++++++----------
Mtpl/crypto/init.go | 2+-
Mtpl/data/data.go | 10+++++-----
Mtpl/data/data_test.go | 28++++++++++++++--------------
Mtpl/data/init.go | 2+-
Mtpl/data/resources.go | 2+-
Mtpl/debug/debug.go | 2+-
Mtpl/debug/init.go | 2+-
Mtpl/diagrams/diagrams.go | 2+-
Mtpl/diagrams/init.go | 2+-
Mtpl/encoding/encoding.go | 6+++---
Mtpl/encoding/encoding_test.go | 16++++++++--------
Mtpl/encoding/init.go | 2+-
Mtpl/fmt/fmt.go | 12++++++------
Mtpl/fmt/init.go | 2+-
Mtpl/hugo/init.go | 2+-
Mtpl/images/images.go | 4++--
Mtpl/images/images_test.go | 4++--
Mtpl/images/init.go | 2+-
Mtpl/inflect/inflect.go | 6+++---
Mtpl/inflect/inflect_test.go | 6+++---
Mtpl/inflect/init.go | 2+-
Mtpl/internal/go_templates/texttemplate/hugo_template.go | 6+++---
Mtpl/internal/resourcehelpers/helpers.go | 6+++---
Mtpl/internal/templatefuncsRegistry.go | 8++++----
Mtpl/js/init.go | 2+-
Mtpl/js/js.go | 6+++---
Mtpl/lang/init.go | 2+-
Mtpl/lang/lang.go | 22+++++++++++-----------
Mtpl/math/init.go | 2+-
Mtpl/math/math.go | 28++++++++++++++--------------
Mtpl/math/math_test.go | 58+++++++++++++++++++++++++++++-----------------------------
Mtpl/openapi/openapi3/init.go | 2+-
Mtpl/openapi/openapi3/openapi3.go | 2+-
Mtpl/os/init.go | 2+-
Mtpl/os/os.go | 10+++++-----
Mtpl/os/os_test.go | 6+++---
Mtpl/partials/init.go | 2+-
Mtpl/partials/partials.go | 30+++++++++++++++---------------
Mtpl/partials/partials_test.go | 4++--
Mtpl/path/init.go | 2+-
Mtpl/path/path.go | 14+++++++-------
Mtpl/path/path_test.go | 28++++++++++++++--------------
Mtpl/reflect/init.go | 2+-
Mtpl/reflect/reflect.go | 4++--
Mtpl/reflect/reflect_test.go | 8++++----
Mtpl/resources/init.go | 2+-
Mtpl/resources/resources.go | 30+++++++++++++++---------------
Mtpl/safe/init.go | 2+-
Mtpl/safe/safe.go | 14+++++++-------
Mtpl/safe/safe_test.go | 28++++++++++++++--------------
Mtpl/site/init.go | 2+-
Mtpl/strings/init.go | 2+-
Mtpl/strings/regexp.go | 4++--
Mtpl/strings/regexp_test.go | 18+++++++++---------
Mtpl/strings/strings.go | 46+++++++++++++++++++++++-----------------------
Mtpl/strings/strings_test.go | 114++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtpl/strings/truncate.go | 4++--
Mtpl/strings/truncate_test.go | 8++++----
Mtpl/template.go | 6+++---
Mtpl/templates/init.go | 2+-
Mtpl/time/init.go | 2+-
Mtpl/time/time.go | 8++++----
Mtpl/time/time_test.go | 16++++++++--------
Mtpl/tplimpl/template.go | 10+++++-----
Mtpl/tplimpl/template_ast_transformers_test.go | 4++--
Mtpl/tplimpl/template_funcs.go | 2+-
Mtpl/transform/init.go | 2+-
Mtpl/transform/remarshal.go | 10+++++-----
Mtpl/transform/remarshal_test.go | 2+-
Mtpl/transform/transform.go | 18+++++++++---------
Mtpl/transform/transform_test.go | 26+++++++++++++-------------
Mtpl/transform/unmarshal.go | 14+++++++-------
Mtpl/transform/unmarshal_test.go | 38+++++++++++++++++++-------------------
Mtpl/urls/init.go | 2+-
Mtpl/urls/urls.go | 28++++++++++++++--------------
Mtpl/urls/urls_test.go | 4++--
Mtransform/urlreplacers/absurlreplacer_test.go | 2+-
342 files changed, 2118 insertions(+), 2102 deletions(-)
diff --git a/bufferpool/bufpool.go b/bufferpool/bufpool.go
@@ -20,7 +20,7 @@ import (
 )
 
 var bufferPool = &sync.Pool{
-	New: func() interface{} {
+	New: func() any {
 		return &bytes.Buffer{}
 	},
 }
diff --git a/cache/namedmemcache/named_cache.go b/cache/namedmemcache/named_cache.go
@@ -30,7 +30,7 @@ type Cache struct {
 }
 
 type cacheEntry struct {
-	value interface{}
+	value any
 	err   error
 }
 
@@ -55,7 +55,7 @@ func (c *Cache) Clear() {
 // create will be called and cached.
 // This method is thread safe. It also guarantees that the create func for a given
 // key is invoked only once for this cache.
-func (c *Cache) GetOrCreate(key string, create func() (interface{}, error)) (interface{}, error) {
+func (c *Cache) GetOrCreate(key string, create func() (any, error)) (any, error) {
 	c.mu.RLock()
 	entry, found := c.cache[key]
 	c.mu.RUnlock()
diff --git a/cache/namedmemcache/named_cache_test.go b/cache/namedmemcache/named_cache_test.go
@@ -28,7 +28,7 @@ func TestNamedCache(t *testing.T) {
 	cache := New()
 
 	counter := 0
-	create := func() (interface{}, error) {
+	create := func() (any, error) {
 		counter++
 		return counter, nil
 	}
@@ -58,8 +58,8 @@ func TestNamedCacheConcurrent(t *testing.T) {
 
 	cache := New()
 
-	create := func(i int) func() (interface{}, error) {
-		return func() (interface{}, error) {
+	create := func(i int) func() (any, error) {
+		return func() (any, error) {
 			return i, nil
 		}
 	}
diff --git a/codegen/methods.go b/codegen/methods.go
@@ -505,7 +505,7 @@ func typeName(name, pkg string) string {
 
 func uniqueNonEmptyStrings(s []string) []string {
 	var unique []string
-	set := map[string]interface{}{}
+	set := map[string]any{}
 	for _, val := range s {
 		if val == "" {
 			continue
diff --git a/codegen/methods_test.go b/codegen/methods_test.go
@@ -85,7 +85,7 @@ type I interface {
 	Method3(myint int, mystring string)
 	Method5() (string, error)
 	Method6() *net.IP
-	Method7() interface{}
+	Method7() any
 	Method8() herrors.ErrorContext
 	method2()
 	method9() os.FileInfo
diff --git a/commands/commandeer.go b/commands/commandeer.go
@@ -120,14 +120,14 @@ func (c *commandeer) errCount() int {
 	return int(c.logger.LogCounters().ErrorCounter.Count())
 }
 
-func (c *commandeer) getErrorWithContext() interface{} {
+func (c *commandeer) getErrorWithContext() any {
 	errCount := c.errCount()
 
 	if errCount == 0 {
 		return nil
 	}
 
-	m := make(map[string]interface{})
+	m := make(map[string]any)
 
 	m["Error"] = errors.New(removeErrorPrefixFromLog(c.logger.Errors()))
 	m["Version"] = hugo.BuildVersionString()
@@ -146,7 +146,7 @@ func (c *commandeer) getErrorWithContext() interface{} {
 	return m
 }
 
-func (c *commandeer) Set(key string, value interface{}) {
+func (c *commandeer) Set(key string, value any) {
 	if c.configured {
 		panic("commandeer cannot be changed")
 	}
diff --git a/commands/config.go b/commands/config.go
@@ -145,13 +145,13 @@ func (m *modMounts) MarshalJSON() ([]byte, error) {
 	if m.verbose {
 		config := m.m.Config()
 		return json.Marshal(&struct {
-			Path        string                 `json:"path"`
-			Version     string                 `json:"version"`
-			Time        time.Time              `json:"time"`
-			Owner       string                 `json:"owner"`
-			Dir         string                 `json:"dir"`
-			Meta        map[string]interface{} `json:"meta"`
-			HugoVersion modules.HugoVersion    `json:"hugoVersion"`
+			Path        string              `json:"path"`
+			Version     string              `json:"version"`
+			Time        time.Time           `json:"time"`
+			Owner       string              `json:"owner"`
+			Dir         string              `json:"dir"`
+			Meta        map[string]any      `json:"meta"`
+			HugoVersion modules.HugoVersion `json:"hugoVersion"`
 
 			Mounts []modMount `json:"mounts"`
 		}{
diff --git a/commands/convert.go b/commands/convert.go
@@ -202,7 +202,7 @@ func (cc *convertCmd) convertAndSavePage(p page.Page, site *hugolib.Site, target
 type parsedFile struct {
 	frontMatterFormat metadecoders.Format
 	frontMatterSource []byte
-	frontMatter       map[string]interface{}
+	frontMatter       map[string]any
 
 	// Everything after Front Matter
 	content []byte
diff --git a/commands/deploy.go b/commands/deploy.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !nodeploy
 // +build !nodeploy
 
 package commands
diff --git a/commands/helpers.go b/commands/helpers.go
@@ -53,15 +53,15 @@ func (c commandError) isUserError() bool {
 	return c.userError
 }
 
-func newUserError(a ...interface{}) commandError {
+func newUserError(a ...any) commandError {
 	return commandError{s: fmt.Sprintln(a...), userError: true}
 }
 
-func newSystemError(a ...interface{}) commandError {
+func newSystemError(a ...any) commandError {
 	return commandError{s: fmt.Sprintln(a...), userError: false}
 }
 
-func newSystemErrorF(format string, a ...interface{}) commandError {
+func newSystemErrorF(format string, a ...any) commandError {
 	return commandError{s: fmt.Sprintf(format, a...), userError: false}
 }
 
diff --git a/commands/import_jekyll.go b/commands/import_jekyll.go
@@ -235,7 +235,7 @@ func (i *importCmd) createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPos
 	return nil
 }
 
-func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
+func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]any {
 	path := filepath.Join(jekyllRoot, "_config.yml")
 
 	exists, err := helpers.Exists(path, fs)
@@ -265,7 +265,7 @@ func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]
 	return c
 }
 
-func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind metadecoders.Format, jekyllConfig map[string]interface{}) (err error) {
+func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind metadecoders.Format, jekyllConfig map[string]any) (err error) {
 	title := "My New Hugo Site"
 	baseURL := "http://example.org/"
 
@@ -285,7 +285,7 @@ func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind meta
 		}
 	}
 
-	in := map[string]interface{}{
+	in := map[string]any{
 		"baseURL":            baseURL,
 		"title":              title,
 		"languageCode":       "en-us",
@@ -423,7 +423,7 @@ func convertJekyllPost(path, relPath, targetDir string, draft bool) error {
 	return nil
 }
 
-func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, draft bool) (interface{}, error) {
+func convertJekyllMetaData(m any, postName string, postDate time.Time, draft bool) (any, error) {
 	metadata, err := maps.ToStringMapE(m)
 	if err != nil {
 		return nil, err
@@ -475,7 +475,7 @@ func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, d
 	return metadata, nil
 }
 
-func convertJekyllContent(m interface{}, content string) (string, error) {
+func convertJekyllContent(m any, content string) (string, error) {
 	metadata, _ := maps.ToStringMapE(m)
 
 	lines := strings.Split(content, "\n")
diff --git a/commands/import_jekyll_test.go b/commands/import_jekyll_test.go
@@ -47,44 +47,44 @@ func TestParseJekyllFilename(t *testing.T) {
 func TestConvertJekyllMetadata(t *testing.T) {
 	c := qt.New(t)
 	testDataList := []struct {
-		metadata interface{}
+		metadata any
 		postName string
 		postDate time.Time
 		draft    bool
 		expect   string
 	}{
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"date":"2015-10-01T00:00:00Z"}`,
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true,
 			`{"date":"2015-10-01T00:00:00Z","draft":true}`,
 		},
 		{
-			map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"},
+			map[any]any{"Permalink": "/permalink.html", "layout": "post"},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`,
 		},
 		{
-			map[interface{}]interface{}{"permalink": "/permalink.html"},
+			map[any]any{"permalink": "/permalink.html"},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`,
 		},
 		{
-			map[interface{}]interface{}{"category": nil, "permalink": 123},
+			map[any]any{"category": nil, "permalink": 123},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"date":"2015-10-01T00:00:00Z"}`,
 		},
 		{
-			map[interface{}]interface{}{"Excerpt_Separator": "sep"},
+			map[any]any{"Excerpt_Separator": "sep"},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`,
 		},
 		{
-			map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
+			map[any]any{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
 			"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
 			`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`,
 		},
@@ -102,69 +102,69 @@ func TestConvertJekyllMetadata(t *testing.T) {
 func TestConvertJekyllContent(t *testing.T) {
 	c := qt.New(t)
 	testDataList := []struct {
-		metadata interface{}
+		metadata any
 		content  string
 		expect   string
 	}{
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"Test content\r\n<!-- more -->\npart2 content", "Test content\n<!--more-->\npart2 content",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"Test content\n<!-- More -->\npart2 content", "Test content\n<!--more-->\npart2 content",
 		},
 		{
-			map[interface{}]interface{}{"excerpt_separator": "<!--sep-->"},
+			map[any]any{"excerpt_separator": "<!--sep-->"},
 			"Test content\n<!--sep-->\npart2 content",
 			"---\nexcerpt_separator: <!--sep-->\n---\nTest content\n<!--more-->\npart2 content",
 		},
-		{map[interface{}]interface{}{}, "{% raw %}text{% endraw %}", "text"},
-		{map[interface{}]interface{}{}, "{%raw%} text2 {%endraw %}", "text2"},
+		{map[any]any{}, "{% raw %}text{% endraw %}", "text"},
+		{map[any]any{}, "{%raw%} text2 {%endraw %}", "text2"},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% highlight go %}\nvar s int\n{% endhighlight %}",
 			"{{< highlight go >}}\nvar s int\n{{< / highlight >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% highlight go linenos hl_lines=\"1 2\" %}\nvar s string\nvar i int\n{% endhighlight %}",
 			"{{< highlight go \"linenos=table,hl_lines=1 2\" >}}\nvar s string\nvar i int\n{{< / highlight >}}",
 		},
 
 		// Octopress image tag
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img http://placekitten.com/890/280 %}",
 			"{{< figure src=\"http://placekitten.com/890/280\" >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img left http://placekitten.com/320/250 Place Kitten #2 %}",
 			"{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #3' %}",
 			"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
 			"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
 			"{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
 		},
 		{
-			map[interface{}]interface{}{},
+			map[any]any{},
 			"{% img right /placekitten/300/500 'Place Kitten #4' 'An image of a very cute kitten' %}",
 			"{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
 		},
 		{
-			map[interface{}]interface{}{"category": "book", "layout": "post", "Date": "2015-10-01 12:13:11"},
+			map[any]any{"category": "book", "layout": "post", "Date": "2015-10-01 12:13:11"},
 			"somecontent",
 			"---\nDate: \"2015-10-01 12:13:11\"\ncategory: book\nlayout: post\n---\nsomecontent",
 		},
diff --git a/commands/limit_others.go b/commands/limit_others.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !darwin
 // +build !darwin
 
 package commands
diff --git a/commands/list.go b/commands/list.go
@@ -32,7 +32,7 @@ type listCmd struct {
 	*baseBuilderCmd
 }
 
-func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites, error) {
+func (lc *listCmd) buildSites(config map[string]any) (*hugolib.HugoSites, error) {
 	cfgInit := func(c *commandeer) error {
 		for key, value := range config {
 			c.Set(key, value)
@@ -75,7 +75,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
 			Short: "List all drafts",
 			Long:  `List all of the drafts in your content directory.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				sites, err := cc.buildSites(map[string]interface{}{"buildDrafts": true})
+				sites, err := cc.buildSites(map[string]any{"buildDrafts": true})
 				if err != nil {
 					return newSystemError("Error building sites", err)
 				}
@@ -94,7 +94,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
 			Short: "List all posts dated in the future",
 			Long:  `List all of the posts in your content directory which will be posted in the future.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				sites, err := cc.buildSites(map[string]interface{}{"buildFuture": true})
+				sites, err := cc.buildSites(map[string]any{"buildFuture": true})
 				if err != nil {
 					return newSystemError("Error building sites", err)
 				}
@@ -122,7 +122,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
 			Short: "List all posts already expired",
 			Long:  `List all of the posts in your content directory which has already expired.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				sites, err := cc.buildSites(map[string]interface{}{"buildExpired": true})
+				sites, err := cc.buildSites(map[string]any{"buildExpired": true})
 				if err != nil {
 					return newSystemError("Error building sites", err)
 				}
@@ -150,7 +150,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
 			Short: "List all posts",
 			Long:  `List all of the posts in your content directory, include drafts, future and expired pages.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				sites, err := cc.buildSites(map[string]interface{}{
+				sites, err := cc.buildSites(map[string]any{
 					"buildExpired": true,
 					"buildDrafts":  true,
 					"buildFuture":  true,
diff --git a/commands/nodeploy.go b/commands/nodeploy.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build nodeploy
 // +build nodeploy
 
 package commands
diff --git a/commands/release.go b/commands/release.go
@@ -1,3 +1,4 @@
+//go:build release
 // +build release
 
 // Copyright 2017-present The Hugo Authors. All rights reserved.
diff --git a/commands/release_noop.go b/commands/release_noop.go
@@ -1,3 +1,4 @@
+//go:build !release
 // +build !release
 
 // Copyright 2018 The Hugo Authors. All rights reserved.
diff --git a/commands/server.go b/commands/server.go
@@ -304,7 +304,7 @@ func getRootWatchDirsStr(baseDir string, watchDirs []string) string {
 type fileServer struct {
 	baseURLs      []string
 	roots         []string
-	errorTemplate func(err interface{}) (io.Reader, error)
+	errorTemplate func(err any) (io.Reader, error)
 	c             *commandeer
 	s             *serverCmd
 }
@@ -497,7 +497,7 @@ func (c *commandeer) serve(s *serverCmd) error {
 		roots:    roots,
 		c:        c,
 		s:        s,
-		errorTemplate: func(ctx interface{}) (io.Reader, error) {
+		errorTemplate: func(ctx any) (io.Reader, error) {
 			b := &bytes.Buffer{}
 			err := c.hugo().Tmpl().Execute(templ, b, ctx)
 			return b, err
diff --git a/common/collections/append.go b/common/collections/append.go
@@ -21,7 +21,7 @@ import (
 // Append appends from to a slice to and returns the resulting slice.
 // If length of from is one and the only element is a slice of same type as to,
 // it will be appended.
-func Append(to interface{}, from ...interface{}) (interface{}, error) {
+func Append(to any, from ...any) (any, error) {
 	tov, toIsNil := indirect(reflect.ValueOf(to))
 
 	toIsNil = toIsNil || to == nil
@@ -73,8 +73,8 @@ func Append(to interface{}, from ...interface{}) (interface{}, error) {
 	return tov.Interface(), nil
 }
 
-func appendToInterfaceSliceFromValues(slice1, slice2 reflect.Value) ([]interface{}, error) {
-	var tos []interface{}
+func appendToInterfaceSliceFromValues(slice1, slice2 reflect.Value) ([]any, error) {
+	var tos []any
 
 	for _, slice := range []reflect.Value{slice1, slice2} {
 		for i := 0; i < slice.Len(); i++ {
@@ -85,8 +85,8 @@ func appendToInterfaceSliceFromValues(slice1, slice2 reflect.Value) ([]interface
 	return tos, nil
 }
 
-func appendToInterfaceSlice(tov reflect.Value, from ...interface{}) ([]interface{}, error) {
-	var tos []interface{}
+func appendToInterfaceSlice(tov reflect.Value, from ...any) ([]any, error) {
+	var tos []any
 
 	for i := 0; i < tov.Len(); i++ {
 		tos = append(tos, tov.Index(i).Interface())
diff --git a/common/collections/append_test.go b/common/collections/append_test.go
@@ -25,25 +25,25 @@ func TestAppend(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		start    interface{}
-		addend   []interface{}
-		expected interface{}
+		start    any
+		addend   []any
+		expected any
 	}{
-		{[]string{"a", "b"}, []interface{}{"c"}, []string{"a", "b", "c"}},
-		{[]string{"a", "b"}, []interface{}{"c", "d", "e"}, []string{"a", "b", "c", "d", "e"}},
-		{[]string{"a", "b"}, []interface{}{[]string{"c", "d", "e"}}, []string{"a", "b", "c", "d", "e"}},
-		{[]string{"a"}, []interface{}{"b", template.HTML("c")}, []interface{}{"a", "b", template.HTML("c")}},
-		{nil, []interface{}{"a", "b"}, []string{"a", "b"}},
-		{nil, []interface{}{nil}, []interface{}{nil}},
-		{[]interface{}{}, []interface{}{[]string{"c", "d", "e"}}, []string{"c", "d", "e"}},
+		{[]string{"a", "b"}, []any{"c"}, []string{"a", "b", "c"}},
+		{[]string{"a", "b"}, []any{"c", "d", "e"}, []string{"a", "b", "c", "d", "e"}},
+		{[]string{"a", "b"}, []any{[]string{"c", "d", "e"}}, []string{"a", "b", "c", "d", "e"}},
+		{[]string{"a"}, []any{"b", template.HTML("c")}, []any{"a", "b", template.HTML("c")}},
+		{nil, []any{"a", "b"}, []string{"a", "b"}},
+		{nil, []any{nil}, []any{nil}},
+		{[]any{}, []any{[]string{"c", "d", "e"}}, []string{"c", "d", "e"}},
 		{
 			tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
-			[]interface{}{&tstSlicer{"c"}},
+			[]any{&tstSlicer{"c"}},
 			tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}, &tstSlicer{"c"}},
 		},
 		{
 			&tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
-			[]interface{}{&tstSlicer{"c"}},
+			[]any{&tstSlicer{"c"}},
 			tstSlicers{
 				&tstSlicer{"a"},
 				&tstSlicer{"b"},
@@ -52,26 +52,26 @@ func TestAppend(t *testing.T) {
 		},
 		{
 			testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}},
-			[]interface{}{&tstSlicerIn1{"c"}},
+			[]any{&tstSlicerIn1{"c"}},
 			testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}, &tstSlicerIn1{"c"}},
 		},
 		//https://github.com/gohugoio/hugo/issues/5361
 		{
 			[]string{"a", "b"},
-			[]interface{}{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
-			[]interface{}{"a", "b", &tstSlicer{"a"}, &tstSlicer{"b"}},
+			[]any{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
+			[]any{"a", "b", &tstSlicer{"a"}, &tstSlicer{"b"}},
 		},
 		{
 			[]string{"a", "b"},
-			[]interface{}{&tstSlicer{"a"}},
-			[]interface{}{"a", "b", &tstSlicer{"a"}},
+			[]any{&tstSlicer{"a"}},
+			[]any{"a", "b", &tstSlicer{"a"}},
 		},
 		// Errors
-		{"", []interface{}{[]string{"a", "b"}}, false},
+		{"", []any{[]string{"a", "b"}}, false},
 		// No string concatenation.
 		{
 			"ab",
-			[]interface{}{"c"},
+			[]any{"c"},
 			false,
 		},
 	} {
diff --git a/common/collections/collections.go b/common/collections/collections.go
@@ -17,5 +17,5 @@ package collections
 
 // Grouper defines a very generic way to group items by a given key.
 type Grouper interface {
-	Group(key interface{}, items interface{}) (interface{}, error)
+	Group(key any, items any) (any, error)
 }
diff --git a/common/collections/slice.go b/common/collections/slice.go
@@ -21,11 +21,11 @@ import (
 // in collections.Slice template func to get types such as Pages, PageGroups etc.
 // instead of the less useful []interface{}.
 type Slicer interface {
-	Slice(items interface{}) (interface{}, error)
+	Slice(items any) (any, error)
 }
 
 // Slice returns a slice of all passed arguments.
-func Slice(args ...interface{}) interface{} {
+func Slice(args ...any) any {
 	if len(args) == 0 {
 		return args
 	}
@@ -66,8 +66,8 @@ func Slice(args ...interface{}) interface{} {
 }
 
 // StringSliceToInterfaceSlice converts ss to []interface{}.
-func StringSliceToInterfaceSlice(ss []string) []interface{} {
-	result := make([]interface{}, len(ss))
+func StringSliceToInterfaceSlice(ss []string) []any {
+	result := make([]any, len(ss))
 	for i, s := range ss {
 		result[i] = s
 	}
diff --git a/common/collections/slice_test.go b/common/collections/slice_test.go
@@ -46,8 +46,8 @@ type tstSlicer struct {
 	TheName string
 }
 
-func (p *tstSlicerIn1) Slice(in interface{}) (interface{}, error) {
-	items := in.([]interface{})
+func (p *tstSlicerIn1) Slice(in any) (any, error) {
+	items := in.([]any)
 	result := make(testSlicerInterfaces, len(items))
 	for i, v := range items {
 		switch vv := v.(type) {
@@ -60,8 +60,8 @@ func (p *tstSlicerIn1) Slice(in interface{}) (interface{}, error) {
 	return result, nil
 }
 
-func (p *tstSlicerIn2) Slice(in interface{}) (interface{}, error) {
-	items := in.([]interface{})
+func (p *tstSlicerIn2) Slice(in any) (any, error) {
+	items := in.([]any)
 	result := make(testSlicerInterfaces, len(items))
 	for i, v := range items {
 		switch vv := v.(type) {
@@ -82,8 +82,8 @@ func (p *tstSlicerIn2) Name() string {
 	return p.TheName
 }
 
-func (p *tstSlicer) Slice(in interface{}) (interface{}, error) {
-	items := in.([]interface{})
+func (p *tstSlicer) Slice(in any) (any, error) {
+	items := in.([]any)
 	result := make(tstSlicers, len(items))
 	for i, v := range items {
 		switch vv := v.(type) {
@@ -103,17 +103,17 @@ func TestSlice(t *testing.T) {
 	c := qt.New(t)
 
 	for i, test := range []struct {
-		args     []interface{}
-		expected interface{}
+		args     []any
+		expected any
 	}{
-		{[]interface{}{"a", "b"}, []string{"a", "b"}},
-		{[]interface{}{&tstSlicer{"a"}, &tstSlicer{"b"}}, tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
-		{[]interface{}{&tstSlicer{"a"}, "b"}, []interface{}{&tstSlicer{"a"}, "b"}},
-		{[]interface{}{}, []interface{}{}},
-		{[]interface{}{nil}, []interface{}{nil}},
-		{[]interface{}{5, "b"}, []interface{}{5, "b"}},
-		{[]interface{}{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}, testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}},
-		{[]interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}, []interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}},
+		{[]any{"a", "b"}, []string{"a", "b"}},
+		{[]any{&tstSlicer{"a"}, &tstSlicer{"b"}}, tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
+		{[]any{&tstSlicer{"a"}, "b"}, []any{&tstSlicer{"a"}, "b"}},
+		{[]any{}, []any{}},
+		{[]any{nil}, []any{nil}},
+		{[]any{5, "b"}, []any{5, "b"}},
+		{[]any{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}, testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}},
+		{[]any{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}, []any{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test.args)
 
diff --git a/common/herrors/errors.go b/common/herrors/errors.go
@@ -65,7 +65,7 @@ type ErrorSender interface {
 // Recover is a helper function that can be used to capture panics.
 // Put this at the top of a method/function that crashes in a template:
 //     defer herrors.Recover()
-func Recover(args ...interface{}) {
+func Recover(args ...any) {
 	if r := recover(); r != nil {
 		fmt.Println("ERR:", r)
 		args = append(args, "stacktrace from panic: \n"+string(debug.Stack()), "\n")
diff --git a/common/hexec/exec.go b/common/hexec/exec.go
@@ -128,7 +128,7 @@ type Exec struct {
 
 // New will fail if name is not allowed according to the configured security policy.
 // Else a configured Runner will be returned ready to be Run.
-func (e *Exec) New(name string, arg ...interface{}) (Runner, error) {
+func (e *Exec) New(name string, arg ...any) (Runner, error) {
 	if err := e.sc.CheckAllowedExec(name); err != nil {
 		return nil, err
 	}
@@ -146,8 +146,8 @@ func (e *Exec) New(name string, arg ...interface{}) (Runner, error) {
 }
 
 // Npx is a convenience method to create a Runner running npx --no-install <name> <args.
-func (e *Exec) Npx(name string, arg ...interface{}) (Runner, error) {
-	arg = append(arg[:0], append([]interface{}{"--no-install", name}, arg[0:]...)...)
+func (e *Exec) Npx(name string, arg ...any) (Runner, error) {
+	arg = append(arg[:0], append([]any{"--no-install", name}, arg[0:]...)...)
 	return e.New("npx", arg...)
 }
 
@@ -205,7 +205,7 @@ type commandeer struct {
 	env  []string
 }
 
-func (c *commandeer) command(arg ...interface{}) (*cmdWrapper, error) {
+func (c *commandeer) command(arg ...any) (*cmdWrapper, error) {
 	if c == nil {
 		return nil, nil
 	}
diff --git a/common/hreflect/helpers.go b/common/hreflect/helpers.go
@@ -62,7 +62,7 @@ func IsFloat(kind reflect.Kind) bool {
 
 // IsTruthful returns whether in represents a truthful value.
 // See IsTruthfulValue
-func IsTruthful(in interface{}) bool {
+func IsTruthful(in any) bool {
 	switch v := in.(type) {
 	case reflect.Value:
 		return IsTruthfulValue(v)
diff --git a/common/htime/time.go b/common/htime/time.go
@@ -134,7 +134,7 @@ func (f TimeFormatter) Format(t time.Time, layout string) string {
 	return s
 }
 
-func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
+func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
 	switch vv := i.(type) {
 	case toml.LocalDate:
 		return vv.AsTime(location), nil
diff --git a/common/hugo/vars_extended.go b/common/hugo/vars_extended.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build extended
 // +build extended
 
 package hugo
diff --git a/common/hugo/vars_regular.go b/common/hugo/vars_regular.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !extended
 // +build !extended
 
 package hugo
diff --git a/common/hugo/version.go b/common/hugo/version.go
@@ -58,13 +58,13 @@ func (h VersionString) String() string {
 }
 
 // Compare implements the compare.Comparer interface.
-func (h VersionString) Compare(other interface{}) int {
+func (h VersionString) Compare(other any) int {
 	v := MustParseVersion(h.String())
 	return compareVersionsWithSuffix(v.Number, v.PatchLevel, v.Suffix, other)
 }
 
 // Eq implements the compare.Eqer interface.
-func (h VersionString) Eq(other interface{}) bool {
+func (h VersionString) Eq(other any) bool {
 	s, err := cast.ToStringE(other)
 	if err != nil {
 		return false
@@ -171,15 +171,15 @@ func version(version float32, patchVersion int, suffix string) string {
 // running Hugo version.
 // It returns -1 if the given version is less than, 0 if equal and 1 if greater than
 // the running version.
-func CompareVersion(version interface{}) int {
+func CompareVersion(version any) int {
 	return compareVersionsWithSuffix(CurrentVersion.Number, CurrentVersion.PatchLevel, CurrentVersion.Suffix, version)
 }
 
-func compareVersions(inVersion float32, inPatchVersion int, in interface{}) int {
+func compareVersions(inVersion float32, inPatchVersion int, in any) int {
 	return compareVersionsWithSuffix(inVersion, inPatchVersion, "", in)
 }
 
-func compareVersionsWithSuffix(inVersion float32, inPatchVersion int, suffix string, in interface{}) int {
+func compareVersionsWithSuffix(inVersion float32, inPatchVersion int, suffix string, in any) int {
 	var c int
 	switch d := in.(type) {
 	case float64:
diff --git a/common/loggers/ignorableLogger.go b/common/loggers/ignorableLogger.go
@@ -21,7 +21,7 @@ import (
 // IgnorableLogger is a logger that ignores certain log statements.
 type IgnorableLogger interface {
 	Logger
-	Errorsf(statementID, format string, v ...interface{})
+	Errorsf(statementID, format string, v ...any)
 	Apply(logger Logger) IgnorableLogger
 }
 
@@ -43,7 +43,7 @@ func NewIgnorableLogger(logger Logger, statements ...string) IgnorableLogger {
 }
 
 // Errorsf logs statementID as an ERROR if not configured as ignoreable.
-func (l ignorableLogger) Errorsf(statementID, format string, v ...interface{}) {
+func (l ignorableLogger) Errorsf(statementID, format string, v ...any) {
 	if l.statements[statementID] {
 		// Ignore.
 		return
diff --git a/common/loggers/loggers.go b/common/loggers/loggers.go
@@ -58,21 +58,21 @@ func (w prefixWriter) Write(p []byte) (n int, err error) {
 }
 
 type Logger interface {
-	Printf(format string, v ...interface{})
-	Println(v ...interface{})
+	Printf(format string, v ...any)
+	Println(v ...any)
 	PrintTimerIfDelayed(start time.Time, name string)
 	Debug() *log.Logger
-	Debugf(format string, v ...interface{})
-	Debugln(v ...interface{})
+	Debugf(format string, v ...any)
+	Debugln(v ...any)
 	Info() *log.Logger
-	Infof(format string, v ...interface{})
-	Infoln(v ...interface{})
+	Infof(format string, v ...any)
+	Infoln(v ...any)
 	Warn() *log.Logger
-	Warnf(format string, v ...interface{})
-	Warnln(v ...interface{})
+	Warnf(format string, v ...any)
+	Warnln(v ...any)
 	Error() *log.Logger
-	Errorf(format string, v ...interface{})
-	Errorln(v ...interface{})
+	Errorf(format string, v ...any)
+	Errorln(v ...any)
 	Errors() string
 
 	Out() io.Writer
@@ -101,11 +101,11 @@ type logger struct {
 	errors *bytes.Buffer
 }
 
-func (l *logger) Printf(format string, v ...interface{}) {
+func (l *logger) Printf(format string, v ...any) {
 	l.FEEDBACK.Printf(format, v...)
 }
 
-func (l *logger) Println(v ...interface{}) {
+func (l *logger) Println(v ...any) {
 	l.FEEDBACK.Println(v...)
 }
 
@@ -113,19 +113,19 @@ func (l *logger) Debug() *log.Logger {
 	return l.DEBUG
 }
 
-func (l *logger) Debugf(format string, v ...interface{}) {
+func (l *logger) Debugf(format string, v ...any) {
 	l.DEBUG.Printf(format, v...)
 }
 
-func (l *logger) Debugln(v ...interface{}) {
+func (l *logger) Debugln(v ...any) {
 	l.DEBUG.Println(v...)
 }
 
-func (l *logger) Infof(format string, v ...interface{}) {
+func (l *logger) Infof(format string, v ...any) {
 	l.INFO.Printf(format, v...)
 }
 
-func (l *logger) Infoln(v ...interface{}) {
+func (l *logger) Infoln(v ...any) {
 	l.INFO.Println(v...)
 }
 
@@ -135,14 +135,14 @@ func (l *logger) Info() *log.Logger {
 
 const panicOnWarningMessage = "Warning trapped. Remove the --panicOnWarning flag to continue."
 
-func (l *logger) Warnf(format string, v ...interface{}) {
+func (l *logger) Warnf(format string, v ...any) {
 	l.WARN.Printf(format, v...)
 	if PanicOnWarning {
 		panic(panicOnWarningMessage)
 	}
 }
 
-func (l *logger) Warnln(v ...interface{}) {
+func (l *logger) Warnln(v ...any) {
 	l.WARN.Println(v...)
 	if PanicOnWarning {
 		panic(panicOnWarningMessage)
@@ -153,11 +153,11 @@ func (l *logger) Warn() *log.Logger {
 	return l.WARN
 }
 
-func (l *logger) Errorf(format string, v ...interface{}) {
+func (l *logger) Errorf(format string, v ...any) {
 	l.ERROR.Printf(format, v...)
 }
 
-func (l *logger) Errorln(v ...interface{}) {
+func (l *logger) Errorln(v ...any) {
 	l.ERROR.Println(v...)
 }
 
diff --git a/common/maps/maps.go b/common/maps/maps.go
@@ -24,12 +24,12 @@ import (
 )
 
 // ToStringMapE converts in to map[string]interface{}.
-func ToStringMapE(in interface{}) (map[string]interface{}, error) {
+func ToStringMapE(in any) (map[string]any, error) {
 	switch vv := in.(type) {
 	case Params:
 		return vv, nil
 	case map[string]string:
-		var m = map[string]interface{}{}
+		var m = map[string]any{}
 		for k, v := range vv {
 			m[k] = v
 		}
@@ -43,7 +43,7 @@ func ToStringMapE(in interface{}) (map[string]interface{}, error) {
 // ToParamsAndPrepare converts in to Params and prepares it for use.
 // If in is nil, an empty map is returned.
 // See PrepareParams.
-func ToParamsAndPrepare(in interface{}) (Params, bool) {
+func ToParamsAndPrepare(in any) (Params, bool) {
 	if types.IsNil(in) {
 		return Params{}, true
 	}
@@ -56,7 +56,7 @@ func ToParamsAndPrepare(in interface{}) (Params, bool) {
 }
 
 // MustToParamsAndPrepare calls ToParamsAndPrepare and panics if it fails.
-func MustToParamsAndPrepare(in interface{}) Params {
+func MustToParamsAndPrepare(in any) Params {
 	if p, ok := ToParamsAndPrepare(in); ok {
 		return p
 	} else {
@@ -65,13 +65,13 @@ func MustToParamsAndPrepare(in interface{}) Params {
 }
 
 // ToStringMap converts in to map[string]interface{}.
-func ToStringMap(in interface{}) map[string]interface{} {
+func ToStringMap(in any) map[string]any {
 	m, _ := ToStringMapE(in)
 	return m
 }
 
 // ToStringMapStringE converts in to map[string]string.
-func ToStringMapStringE(in interface{}) (map[string]string, error) {
+func ToStringMapStringE(in any) (map[string]string, error) {
 	m, err := ToStringMapE(in)
 	if err != nil {
 		return nil, err
@@ -80,26 +80,26 @@ func ToStringMapStringE(in interface{}) (map[string]string, error) {
 }
 
 // ToStringMapString converts in to map[string]string.
-func ToStringMapString(in interface{}) map[string]string {
+func ToStringMapString(in any) map[string]string {
 	m, _ := ToStringMapStringE(in)
 	return m
 }
 
 // ToStringMapBool converts in to bool.
-func ToStringMapBool(in interface{}) map[string]bool {
+func ToStringMapBool(in any) map[string]bool {
 	m, _ := ToStringMapE(in)
 	return cast.ToStringMapBool(m)
 }
 
 // ToSliceStringMap converts in to []map[string]interface{}.
-func ToSliceStringMap(in interface{}) ([]map[string]interface{}, error) {
+func ToSliceStringMap(in any) ([]map[string]any, error) {
 	switch v := in.(type) {
-	case []map[string]interface{}:
+	case []map[string]any:
 		return v, nil
-	case []interface{}:
-		var s []map[string]interface{}
+	case []any:
+		var s []map[string]any
 		for _, entry := range v {
-			if vv, ok := entry.(map[string]interface{}); ok {
+			if vv, ok := entry.(map[string]any); ok {
 				s = append(s, vv)
 			}
 		}
@@ -146,7 +146,7 @@ func (r KeyRenamer) getNewKey(keyPath string) string {
 
 // Rename renames the keys in the given map according
 // to the patterns in the current KeyRenamer.
-func (r KeyRenamer) Rename(m map[string]interface{}) {
+func (r KeyRenamer) Rename(m map[string]any) {
 	r.renamePath("", m)
 }
 
@@ -158,15 +158,15 @@ func (KeyRenamer) keyPath(k1, k2 string) string {
 	return k1 + "/" + k2
 }
 
-func (r KeyRenamer) renamePath(parentKeyPath string, m map[string]interface{}) {
+func (r KeyRenamer) renamePath(parentKeyPath string, m map[string]any) {
 	for key, val := range m {
 		keyPath := r.keyPath(parentKeyPath, key)
 		switch val.(type) {
-		case map[interface{}]interface{}:
+		case map[any]any:
 			val = cast.ToStringMap(val)
-			r.renamePath(keyPath, val.(map[string]interface{}))
-		case map[string]interface{}:
-			r.renamePath(keyPath, val.(map[string]interface{}))
+			r.renamePath(keyPath, val.(map[string]any))
+		case map[string]any:
+			r.renamePath(keyPath, val.(map[string]any))
 		}
 
 		newKey := r.getNewKey(keyPath)
diff --git a/common/maps/maps_test.go b/common/maps/maps_test.go
@@ -27,7 +27,7 @@ func TestPrepareParams(t *testing.T) {
 		expected Params
 	}{
 		{
-			map[string]interface{}{
+			map[string]any{
 				"abC": 32,
 			},
 			Params{
@@ -35,16 +35,16 @@ func TestPrepareParams(t *testing.T) {
 			},
 		},
 		{
-			map[string]interface{}{
+			map[string]any{
 				"abC": 32,
-				"deF": map[interface{}]interface{}{
+				"deF": map[any]any{
 					23: "A value",
-					24: map[string]interface{}{
+					24: map[string]any{
 						"AbCDe": "A value",
 						"eFgHi": "Another value",
 					},
 				},
-				"gHi": map[string]interface{}{
+				"gHi": map[string]any{
 					"J": 25,
 				},
 				"jKl": map[string]string{
@@ -85,23 +85,23 @@ func TestToSliceStringMap(t *testing.T) {
 	c := qt.New(t)
 
 	tests := []struct {
-		input    interface{}
-		expected []map[string]interface{}
+		input    any
+		expected []map[string]any
 	}{
 		{
-			input: []map[string]interface{}{
+			input: []map[string]any{
 				{"abc": 123},
 			},
-			expected: []map[string]interface{}{
+			expected: []map[string]any{
 				{"abc": 123},
 			},
 		}, {
-			input: []interface{}{
-				map[string]interface{}{
+			input: []any{
+				map[string]any{
 					"def": 456,
 				},
 			},
-			expected: []map[string]interface{}{
+			expected: []map[string]any{
 				{"def": 456},
 			},
 		},
@@ -116,7 +116,7 @@ func TestToSliceStringMap(t *testing.T) {
 
 func TestToParamsAndPrepare(t *testing.T) {
 	c := qt.New(t)
-	_, ok := ToParamsAndPrepare(map[string]interface{}{"A": "av"})
+	_, ok := ToParamsAndPrepare(map[string]any{"A": "av"})
 	c.Assert(ok, qt.IsTrue)
 
 	params, ok := ToParamsAndPrepare(nil)
@@ -127,33 +127,33 @@ func TestToParamsAndPrepare(t *testing.T) {
 func TestRenameKeys(t *testing.T) {
 	c := qt.New(t)
 
-	m := map[string]interface{}{
+	m := map[string]any{
 		"a":    32,
 		"ren1": "m1",
 		"ren2": "m1_2",
-		"sub": map[string]interface{}{
-			"subsub": map[string]interface{}{
+		"sub": map[string]any{
+			"subsub": map[string]any{
 				"REN1": "m2",
 				"ren2": "m2_2",
 			},
 		},
-		"no": map[string]interface{}{
+		"no": map[string]any{
 			"ren1": "m2",
 			"ren2": "m2_2",
 		},
 	}
 
-	expected := map[string]interface{}{
+	expected := map[string]any{
 		"a":    32,
 		"new1": "m1",
 		"new2": "m1_2",
-		"sub": map[string]interface{}{
-			"subsub": map[string]interface{}{
+		"sub": map[string]any{
+			"subsub": map[string]any{
 				"new1": "m2",
 				"ren2": "m2_2",
 			},
 		},
-		"no": map[string]interface{}{
+		"no": map[string]any{
 			"ren1": "m2",
 			"ren2": "m2_2",
 		},
diff --git a/common/maps/params.go b/common/maps/params.go
@@ -21,11 +21,11 @@ import (
 )
 
 // Params is a map where all keys are lower case.
-type Params map[string]interface{}
+type Params map[string]any
 
 // Get does a lower case and nested search in this map.
 // It will return nil if none found.
-func (p Params) Get(indices ...string) interface{} {
+func (p Params) Get(indices ...string) any {
 	v, _, _ := getNested(p, indices)
 	return v
 }
@@ -142,7 +142,7 @@ func (p Params) SetDefaultMergeStrategy(s ParamsMergeStrategy) {
 	p[mergeStrategyKey] = s
 }
 
-func getNested(m map[string]interface{}, indices []string) (interface{}, string, map[string]interface{}) {
+func getNested(m map[string]any, indices []string) (any, string, map[string]any) {
 	if len(indices) == 0 {
 		return nil, "", nil
 	}
@@ -164,7 +164,7 @@ func getNested(m map[string]interface{}, indices []string) (interface{}, string,
 	switch m2 := v.(type) {
 	case Params:
 		return getNested(m2, indices[1:])
-	case map[string]interface{}:
+	case map[string]any:
 		return getNested(m2, indices[1:])
 	default:
 		return nil, "", nil
@@ -175,7 +175,7 @@ func getNested(m map[string]interface{}, indices []string) (interface{}, string,
 // It will first try the exact match and then try to find it as a nested map value,
 // using the given separator, e.g. "mymap.name".
 // It assumes that all the maps given have lower cased keys.
-func GetNestedParam(keyStr, separator string, candidates ...Params) (interface{}, error) {
+func GetNestedParam(keyStr, separator string, candidates ...Params) (any, error) {
 	keyStr = strings.ToLower(keyStr)
 
 	// Try exact match first
@@ -195,7 +195,7 @@ func GetNestedParam(keyStr, separator string, candidates ...Params) (interface{}
 	return nil, nil
 }
 
-func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) {
+func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) any) (any, string, map[string]any, error) {
 	keySegments := strings.Split(keyStr, separator)
 	if len(keySegments) == 0 {
 		return nil, "", nil, nil
@@ -211,7 +211,7 @@ func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interf
 	}
 
 	switch m := first.(type) {
-	case map[string]interface{}:
+	case map[string]any:
 		v, key, owner := getNested(m, keySegments[1:])
 		return v, key, owner, nil
 	case Params:
@@ -236,7 +236,7 @@ const (
 	mergeStrategyKey = "_merge"
 )
 
-func toMergeStrategy(v interface{}) ParamsMergeStrategy {
+func toMergeStrategy(v any) ParamsMergeStrategy {
 	s := ParamsMergeStrategy(cast.ToString(v))
 	switch s {
 	case ParamsMergeStrategyDeep, ParamsMergeStrategyNone, ParamsMergeStrategyShallow:
@@ -260,13 +260,13 @@ func PrepareParams(m Params) {
 			retyped = true
 		} else {
 			switch vv := v.(type) {
-			case map[interface{}]interface{}:
+			case map[any]any:
 				var p Params = cast.ToStringMap(v)
 				v = p
 				PrepareParams(p)
 				retyped = true
-			case map[string]interface{}:
-				var p Params = v.(map[string]interface{})
+			case map[string]any:
+				var p Params = v.(map[string]any)
 				v = p
 				PrepareParams(p)
 				retyped = true
diff --git a/common/maps/params_test.go b/common/maps/params_test.go
@@ -20,13 +20,13 @@ import (
 )
 
 func TestGetNestedParam(t *testing.T) {
-	m := map[string]interface{}{
+	m := map[string]any{
 		"string":          "value",
 		"first":           1,
 		"with_underscore": 2,
-		"nested": map[string]interface{}{
+		"nested": map[string]any{
 			"color": "blue",
-			"nestednested": map[string]interface{}{
+			"nestednested": map[string]any{
 				"color": "green",
 			},
 		},
@@ -34,7 +34,7 @@ func TestGetNestedParam(t *testing.T) {
 
 	c := qt.New(t)
 
-	must := func(keyStr, separator string, candidates ...Params) interface{} {
+	must := func(keyStr, separator string, candidates ...Params) any {
 		v, err := GetNestedParam(keyStr, separator, candidates...)
 		c.Assert(err, qt.IsNil)
 		return v
@@ -53,14 +53,14 @@ func TestGetNestedParam(t *testing.T) {
 func TestGetNestedParamFnNestedNewKey(t *testing.T) {
 	c := qt.New(t)
 
-	nested := map[string]interface{}{
+	nested := map[string]any{
 		"color": "blue",
 	}
-	m := map[string]interface{}{
+	m := map[string]any{
 		"nested": nested,
 	}
 
-	existing, nestedKey, owner, err := GetNestedParamFn("nested.new", ".", func(key string) interface{} {
+	existing, nestedKey, owner, err := GetNestedParamFn("nested.new", ".", func(key string) any {
 		return m[key]
 	})
 
diff --git a/common/maps/scratch.go b/common/maps/scratch.go
@@ -24,7 +24,7 @@ import (
 
 // Scratch is a writable context used for stateful operations in Page/Node rendering.
 type Scratch struct {
-	values map[string]interface{}
+	values map[string]any
 	mu     sync.RWMutex
 }
 
@@ -50,8 +50,8 @@ func NewScratcher() Scratcher {
 // Supports numeric values and strings.
 //
 // If the first add for a key is an array or slice, then the next value(s) will be appended.
-func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
-	var newVal interface{}
+func (c *Scratch) Add(key string, newAddend any) (string, error) {
+	var newVal any
 	c.mu.RLock()
 	existingAddend, found := c.values[key]
 	c.mu.RUnlock()
@@ -82,7 +82,7 @@ func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
 
 // Set stores a value with the given key in the Node context.
 // This value can later be retrieved with Get.
-func (c *Scratch) Set(key string, value interface{}) string {
+func (c *Scratch) Set(key string, value any) string {
 	c.mu.Lock()
 	c.values[key] = value
 	c.mu.Unlock()
@@ -98,7 +98,7 @@ func (c *Scratch) Delete(key string) string {
 }
 
 // Get returns a value previously set by Add or Set.
-func (c *Scratch) Get(key string) interface{} {
+func (c *Scratch) Get(key string) any {
 	c.mu.RLock()
 	val := c.values[key]
 	c.mu.RUnlock()
@@ -109,7 +109,7 @@ func (c *Scratch) Get(key string) interface{} {
 // Values returns the raw backing map. Note that you should just use
 // this method on the locally scoped Scratch instances you obtain via newScratch, not
 // .Page.Scratch etc., as that will lead to concurrency issues.
-func (c *Scratch) Values() map[string]interface{} {
+func (c *Scratch) Values() map[string]any {
 	c.mu.RLock()
 	defer c.mu.RUnlock()
 	return c.values
@@ -117,14 +117,14 @@ func (c *Scratch) Values() map[string]interface{} {
 
 // SetInMap stores a value to a map with the given key in the Node context.
 // This map can later be retrieved with GetSortedMapValues.
-func (c *Scratch) SetInMap(key string, mapKey string, value interface{}) string {
+func (c *Scratch) SetInMap(key string, mapKey string, value any) string {
 	c.mu.Lock()
 	_, found := c.values[key]
 	if !found {
-		c.values[key] = make(map[string]interface{})
+		c.values[key] = make(map[string]any)
 	}
 
-	c.values[key].(map[string]interface{})[mapKey] = value
+	c.values[key].(map[string]any)[mapKey] = value
 	c.mu.Unlock()
 	return ""
 }
@@ -134,14 +134,14 @@ func (c *Scratch) DeleteInMap(key string, mapKey string) string {
 	c.mu.Lock()
 	_, found := c.values[key]
 	if found {
-		delete(c.values[key].(map[string]interface{}), mapKey)
+		delete(c.values[key].(map[string]any), mapKey)
 	}
 	c.mu.Unlock()
 	return ""
 }
 
 // GetSortedMapValues returns a sorted map previously filled with SetInMap.
-func (c *Scratch) GetSortedMapValues(key string) interface{} {
+func (c *Scratch) GetSortedMapValues(key string) any {
 	c.mu.RLock()
 
 	if c.values[key] == nil {
@@ -149,7 +149,7 @@ func (c *Scratch) GetSortedMapValues(key string) interface{} {
 		return nil
 	}
 
-	unsortedMap := c.values[key].(map[string]interface{})
+	unsortedMap := c.values[key].(map[string]any)
 	c.mu.RUnlock()
 	var keys []string
 	for mapKey := range unsortedMap {
@@ -158,7 +158,7 @@ func (c *Scratch) GetSortedMapValues(key string) interface{} {
 
 	sort.Strings(keys)
 
-	sortedArray := make([]interface{}, len(unsortedMap))
+	sortedArray := make([]any, len(unsortedMap))
 	for i, mapKey := range keys {
 		sortedArray[i] = unsortedMap[mapKey]
 	}
@@ -168,5 +168,5 @@ func (c *Scratch) GetSortedMapValues(key string) interface{} {
 
 // NewScratch returns a new instance of Scratch.
 func NewScratch() *Scratch {
-	return &Scratch{values: make(map[string]interface{})}
+	return &Scratch{values: make(map[string]any)}
 }
diff --git a/common/maps/scratch_test.go b/common/maps/scratch_test.go
@@ -90,7 +90,7 @@ func TestScratchAddTypedSliceToInterfaceSlice(t *testing.T) {
 	c := qt.New(t)
 
 	scratch := NewScratch()
-	scratch.Set("slice", []interface{}{})
+	scratch.Set("slice", []any{})
 
 	_, err := scratch.Add("slice", []int{1, 2})
 	c.Assert(err, qt.IsNil)
@@ -107,7 +107,7 @@ func TestScratchAddDifferentTypedSliceToInterfaceSlice(t *testing.T) {
 
 	_, err := scratch.Add("slice", []int{1, 2})
 	c.Assert(err, qt.IsNil)
-	c.Assert(scratch.Get("slice"), qt.DeepEquals, []interface{}{"foo", 1, 2})
+	c.Assert(scratch.Get("slice"), qt.DeepEquals, []any{"foo", 1, 2})
 }
 
 func TestScratchSet(t *testing.T) {
@@ -185,7 +185,7 @@ func TestScratchSetInMap(t *testing.T) {
 	scratch.SetInMap("key", "zyx", "Zyx")
 	scratch.SetInMap("key", "abc", "Abc (updated)")
 	scratch.SetInMap("key", "def", "Def")
-	c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"})
+	c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []any{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"})
 }
 
 func TestScratchDeleteInMap(t *testing.T) {
@@ -199,7 +199,7 @@ func TestScratchDeleteInMap(t *testing.T) {
 	scratch.DeleteInMap("key", "abc")
 	scratch.SetInMap("key", "def", "Def")
 	scratch.DeleteInMap("key", "lmn") // Do nothing
-	c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Def", 1: "Lux", 2: "Zyx"})
+	c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []any{0: "Def", 1: "Lux", 2: "Zyx"})
 }
 
 func TestScratchGetSortedMapValues(t *testing.T) {
diff --git a/common/math/math.go b/common/math/math.go
@@ -20,7 +20,7 @@ import (
 
 // DoArithmetic performs arithmetic operations (+,-,*,/) using reflection to
 // determine the type of the two terms.
-func DoArithmetic(a, b interface{}, op rune) (interface{}, error) {
+func DoArithmetic(a, b any, op rune) (any, error) {
 	av := reflect.ValueOf(a)
 	bv := reflect.ValueOf(b)
 	var ai, bi int64
diff --git a/common/math/math_test.go b/common/math/math_test.go
@@ -24,10 +24,10 @@ func TestDoArithmetic(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
+		a      any
+		b      any
 		op     rune
-		expect interface{}
+		expect any
 	}{
 		{3, 2, '+', int64(5)},
 		{3, 2, '-', int64(1)},
diff --git a/common/paths/path_test.go b/common/paths/path_test.go
@@ -24,7 +24,7 @@ func TestGetRelativePath(t *testing.T) {
 	tests := []struct {
 		path   string
 		base   string
-		expect interface{}
+		expect any
 	}{
 		{filepath.FromSlash("/a/b"), filepath.FromSlash("/a"), filepath.FromSlash("b")},
 		{filepath.FromSlash("/a/b/c/"), filepath.FromSlash("/a"), filepath.FromSlash("b/c/")},
diff --git a/common/text/position.go b/common/text/position.go
@@ -69,7 +69,7 @@ func createPositionStringFormatter(formatStr string) func(p Position) string {
 	format := replacer.Replace(formatStr)
 
 	f := func(pos Position) string {
-		args := make([]interface{}, len(identifiersFound))
+		args := make([]any, len(identifiersFound))
 		for i, id := range identifiersFound {
 			switch id {
 			case ":file":
diff --git a/common/text/transform.go b/common/text/transform.go
@@ -24,7 +24,7 @@ import (
 )
 
 var accentTransformerPool = &sync.Pool{
-	New: func() interface{} {
+	New: func() any {
 		return transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
 	},
 }
diff --git a/common/types/convert.go b/common/types/convert.go
@@ -25,13 +25,13 @@ import (
 
 // ToDuration converts v to time.Duration.
 // See ToDurationE if you need to handle errors.
-func ToDuration(v interface{}) time.Duration {
+func ToDuration(v any) time.Duration {
 	d, _ := ToDurationE(v)
 	return d
 }
 
 // ToDurationE converts v to time.Duration.
-func ToDurationE(v interface{}) (time.Duration, error) {
+func ToDurationE(v any) (time.Duration, error) {
 	if n := cast.ToInt(v); n > 0 {
 		return time.Duration(n) * time.Millisecond, nil
 	}
@@ -44,14 +44,14 @@ func ToDurationE(v interface{}) (time.Duration, error) {
 
 // ToStringSlicePreserveString is the same as ToStringSlicePreserveStringE,
 // but it never fails.
-func ToStringSlicePreserveString(v interface{}) []string {
+func ToStringSlicePreserveString(v any) []string {
 	vv, _ := ToStringSlicePreserveStringE(v)
 	return vv
 }
 
 // ToStringSlicePreserveStringE converts v to a string slice.
 // If v is a string, it will be wrapped in a string slice.
-func ToStringSlicePreserveStringE(v interface{}) ([]string, error) {
+func ToStringSlicePreserveStringE(v any) ([]string, error) {
 	if v == nil {
 		return nil, nil
 	}
@@ -86,7 +86,7 @@ func ToStringSlicePreserveStringE(v interface{}) ([]string, error) {
 // TypeToString converts v to a string if it's a valid string type.
 // Note that this will not try to convert numeric values etc.,
 // use ToString for that.
-func TypeToString(v interface{}) (string, bool) {
+func TypeToString(v any) (string, bool) {
 	switch s := v.(type) {
 	case string:
 		return s, true
@@ -110,13 +110,13 @@ func TypeToString(v interface{}) (string, bool) {
 }
 
 // ToString converts v to a string.
-func ToString(v interface{}) string {
+func ToString(v any) string {
 	s, _ := ToStringE(v)
 	return s
 }
 
 // ToStringE converts v to a string.
-func ToStringE(v interface{}) (string, error) {
+func ToStringE(v any) (string, error) {
 	if s, ok := TypeToString(v); ok {
 		return s, nil
 	}
diff --git a/common/types/convert_test.go b/common/types/convert_test.go
@@ -26,7 +26,7 @@ func TestToStringSlicePreserveString(t *testing.T) {
 
 	c.Assert(ToStringSlicePreserveString("Hugo"), qt.DeepEquals, []string{"Hugo"})
 	c.Assert(ToStringSlicePreserveString(qt.Commentf("Hugo")), qt.DeepEquals, []string{"Hugo"})
-	c.Assert(ToStringSlicePreserveString([]interface{}{"A", "B"}), qt.DeepEquals, []string{"A", "B"})
+	c.Assert(ToStringSlicePreserveString([]any{"A", "B"}), qt.DeepEquals, []string{"A", "B"})
 	c.Assert(ToStringSlicePreserveString([]int{1, 3}), qt.DeepEquals, []string{"1", "3"})
 	c.Assert(ToStringSlicePreserveString(nil), qt.IsNil)
 }
diff --git a/common/types/types.go b/common/types/types.go
@@ -29,8 +29,8 @@ type RLocker interface {
 
 // KeyValue is a interface{} tuple.
 type KeyValue struct {
-	Key   interface{}
-	Value interface{}
+	Key   any
+	Value any
 }
 
 // KeyValueStr is a string tuple.
@@ -41,8 +41,8 @@ type KeyValueStr struct {
 
 // KeyValues holds an key and a slice of values.
 type KeyValues struct {
-	Key    interface{}
-	Values []interface{}
+	Key    any
+	Values []any
 }
 
 // KeyString returns the key as a string, an empty string if conversion fails.
@@ -57,7 +57,7 @@ func (k KeyValues) String() string {
 // NewKeyValuesStrings takes a given key and slice of values and returns a new
 // KeyValues struct.
 func NewKeyValuesStrings(key string, values ...string) KeyValues {
-	iv := make([]interface{}, len(values))
+	iv := make([]any, len(values))
 	for i := 0; i < len(values); i++ {
 		iv[i] = values[i]
 	}
@@ -71,7 +71,7 @@ type Zeroer interface {
 }
 
 // IsNil reports whether v is nil.
-func IsNil(v interface{}) bool {
+func IsNil(v any) bool {
 	if v == nil {
 		return true
 	}
diff --git a/common/types/types_test.go b/common/types/types_test.go
@@ -25,5 +25,5 @@ func TestKeyValues(t *testing.T) {
 	kv := NewKeyValuesStrings("key", "a1", "a2")
 
 	c.Assert(kv.KeyString(), qt.Equals, "key")
-	c.Assert(kv.Values, qt.DeepEquals, []interface{}{"a1", "a2"})
+	c.Assert(kv.Values, qt.DeepEquals, []any{"a1", "a2"})
 }
diff --git a/common/urls/ref.go b/common/urls/ref.go
@@ -17,6 +17,6 @@ package urls
 // args must contain a path, but can also point to the target
 // language or output format.
 type RefLinker interface {
-	Ref(args map[string]interface{}) (string, error)
-	RelRef(args map[string]interface{}) (string, error)
+	Ref(args map[string]any) (string, error)
+	RelRef(args map[string]any) (string, error)
 }
diff --git a/compare/compare.go b/compare/compare.go
@@ -17,13 +17,13 @@ package compare
 // The semantics of equals is that the two value are interchangeable
 // in the Hugo templates.
 type Eqer interface {
-	Eq(other interface{}) bool
+	Eq(other any) bool
 }
 
 // ProbablyEqer is an equal check that may return false positives, but never
 // a false negative.
 type ProbablyEqer interface {
-	ProbablyEq(other interface{}) bool
+	ProbablyEq(other any) bool
 }
 
 // Comparer can be used to compare two values.
@@ -31,5 +31,5 @@ type ProbablyEqer interface {
 // Compare returns -1 if the given version is less than, 0 if equal and 1 if greater than
 // the running version.
 type Comparer interface {
-	Compare(other interface{}) int
+	Compare(other any) int
 }
diff --git a/config/commonConfig.go b/config/commonConfig.go
@@ -87,7 +87,7 @@ type Sitemap struct {
 	Filename   string
 }
 
-func DecodeSitemap(prototype Sitemap, input map[string]interface{}) Sitemap {
+func DecodeSitemap(prototype Sitemap, input map[string]any) Sitemap {
 	for key, value := range input {
 		switch key {
 		case "changefreq":
@@ -177,7 +177,7 @@ func (s *Server) MatchRedirect(pattern string) Redirect {
 
 type Headers struct {
 	For    string
-	Values map[string]interface{}
+	Values map[string]any
 }
 
 type Redirect struct {
diff --git a/config/commonConfig_test.go b/config/commonConfig_test.go
@@ -27,7 +27,7 @@ func TestBuild(t *testing.T) {
 	c := qt.New(t)
 
 	v := New()
-	v.Set("build", map[string]interface{}{
+	v.Set("build", map[string]any{
 		"useResourceCacheWhen": "always",
 	})
 
@@ -35,7 +35,7 @@ func TestBuild(t *testing.T) {
 
 	c.Assert(b.UseResourceCacheWhen, qt.Equals, "always")
 
-	v.Set("build", map[string]interface{}{
+	v.Set("build", map[string]any{
 		"useResourceCacheWhen": "foo",
 	})
 
diff --git a/config/compositeConfig.go b/config/compositeConfig.go
@@ -47,7 +47,7 @@ func (c *compositeConfig) GetInt(key string) int {
 	return c.base.GetInt(key)
 }
 
-func (c *compositeConfig) Merge(key string, value interface{}) {
+func (c *compositeConfig) Merge(key string, value any) {
 	c.layer.Merge(key, value)
 }
 
@@ -58,7 +58,7 @@ func (c *compositeConfig) GetParams(key string) maps.Params {
 	return c.base.GetParams(key)
 }
 
-func (c *compositeConfig) GetStringMap(key string) map[string]interface{} {
+func (c *compositeConfig) GetStringMap(key string) map[string]any {
 	if c.layer.IsSet(key) {
 		return c.layer.GetStringMap(key)
 	}
@@ -79,7 +79,7 @@ func (c *compositeConfig) GetStringSlice(key string) []string {
 	return c.base.GetStringSlice(key)
 }
 
-func (c *compositeConfig) Get(key string) interface{} {
+func (c *compositeConfig) Get(key string) any {
 	if c.layer.IsSet(key) {
 		return c.layer.Get(key)
 	}
@@ -100,7 +100,7 @@ func (c *compositeConfig) GetString(key string) string {
 	return c.base.GetString(key)
 }
 
-func (c *compositeConfig) Set(key string, value interface{}) {
+func (c *compositeConfig) Set(key string, value any) {
 	c.layer.Set(key, value)
 }
 
diff --git a/config/configLoader.go b/config/configLoader.go
@@ -67,11 +67,11 @@ func FromFile(fs afero.Fs, filename string) (Provider, error) {
 
 // FromFileToMap is the same as FromFile, but it returns the config values
 // as a simple map.
-func FromFileToMap(fs afero.Fs, filename string) (map[string]interface{}, error) {
+func FromFileToMap(fs afero.Fs, filename string) (map[string]any, error) {
 	return loadConfigFromFile(fs, filename)
 }
 
-func readConfig(format metadecoders.Format, data []byte) (map[string]interface{}, error) {
+func readConfig(format metadecoders.Format, data []byte) (map[string]any, error) {
 	m, err := metadecoders.Default.UnmarshalToMap(data, format)
 	if err != nil {
 		return nil, err
@@ -82,7 +82,7 @@ func readConfig(format metadecoders.Format, data []byte) (map[string]interface{}
 	return m, nil
 }
 
-func loadConfigFromFile(fs afero.Fs, filename string) (map[string]interface{}, error) {
+func loadConfigFromFile(fs afero.Fs, filename string) (map[string]any, error) {
 	m, err := metadecoders.Default.UnmarshalFileToMap(fs, filename)
 	if err != nil {
 		return nil, err
@@ -156,13 +156,13 @@ func LoadConfigFromDir(sourceFs afero.Fs, configDir, environment string) (Provid
 
 			root := item
 			if len(keyPath) > 0 {
-				root = make(map[string]interface{})
+				root = make(map[string]any)
 				m := root
 				for i, key := range keyPath {
 					if i >= len(keyPath)-1 {
 						m[key] = item
 					} else {
-						nm := make(map[string]interface{})
+						nm := make(map[string]any)
 						m[key] = nm
 						m = nm
 					}
@@ -203,6 +203,6 @@ func init() {
 
 // RenameKeys renames config keys in m recursively according to a global Hugo
 // alias definition.
-func RenameKeys(m map[string]interface{}) {
+func RenameKeys(m map[string]any) {
 	keyAliases.Rename(m)
 }
diff --git a/config/configProvider.go b/config/configProvider.go
@@ -24,12 +24,12 @@ type Provider interface {
 	GetInt(key string) int
 	GetBool(key string) bool
 	GetParams(key string) maps.Params
-	GetStringMap(key string) map[string]interface{}
+	GetStringMap(key string) map[string]any
 	GetStringMapString(key string) map[string]string
 	GetStringSlice(key string) []string
-	Get(key string) interface{}
-	Set(key string, value interface{})
-	Merge(key string, value interface{})
+	Get(key string) any
+	Set(key string, value any)
+	Merge(key string, value any)
 	SetDefaults(params maps.Params)
 	SetDefaultMergeStrategy()
 	WalkParams(walkFn func(params ...KeyParams) bool)
diff --git a/config/defaultConfigProvider.go b/config/defaultConfigProvider.go
@@ -84,7 +84,7 @@ type defaultConfigProvider struct {
 	keyCache sync.Map
 }
 
-func (c *defaultConfigProvider) Get(k string) interface{} {
+func (c *defaultConfigProvider) Get(k string) any {
 	if k == "" {
 		return c.root
 	}
@@ -133,7 +133,7 @@ func (c *defaultConfigProvider) GetParams(k string) maps.Params {
 	return v.(maps.Params)
 }
 
-func (c *defaultConfigProvider) GetStringMap(k string) map[string]interface{} {
+func (c *defaultConfigProvider) GetStringMap(k string) map[string]any {
 	v := c.Get(k)
 	return maps.ToStringMap(v)
 }
@@ -148,7 +148,7 @@ func (c *defaultConfigProvider) GetStringSlice(k string) []string {
 	return cast.ToStringSlice(v)
 }
 
-func (c *defaultConfigProvider) Set(k string, v interface{}) {
+func (c *defaultConfigProvider) Set(k string, v any) {
 	c.mu.Lock()
 	defer c.mu.Unlock()
 
@@ -166,7 +166,7 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) {
 	}
 
 	switch vv := v.(type) {
-	case map[string]interface{}, map[interface{}]interface{}, map[string]string:
+	case map[string]any, map[any]any, map[string]string:
 		p := maps.MustToParamsAndPrepare(vv)
 		v = p
 	}
@@ -198,7 +198,7 @@ func (c *defaultConfigProvider) SetDefaults(params maps.Params) {
 	}
 }
 
-func (c *defaultConfigProvider) Merge(k string, v interface{}) {
+func (c *defaultConfigProvider) Merge(k string, v any) {
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	k = strings.ToLower(k)
@@ -289,7 +289,7 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) {
 	}
 
 	switch vv := v.(type) {
-	case map[string]interface{}, map[interface{}]interface{}, map[string]string:
+	case map[string]any, map[any]any, map[string]string:
 		p := maps.MustToParamsAndPrepare(vv)
 		v = p
 	}
diff --git a/config/defaultConfigProvider_test.go b/config/defaultConfigProvider_test.go
@@ -34,7 +34,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("Set and get", func(c *qt.C) {
 		cfg := New()
 		var k string
-		var v interface{}
+		var v any
 
 		k, v = "foo", "bar"
 		cfg.Set(k, v)
@@ -55,7 +55,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("Set and get map", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("foo", map[string]interface{}{
+		cfg.Set("foo", map[string]any{
 			"bar": "baz",
 		})
 
@@ -63,14 +63,14 @@ func TestDefaultConfigProvider(t *testing.T) {
 			"bar": "baz",
 		})
 
-		c.Assert(cfg.GetStringMap("foo"), qt.DeepEquals, map[string]interface{}{"bar": string("baz")})
+		c.Assert(cfg.GetStringMap("foo"), qt.DeepEquals, map[string]any{"bar": string("baz")})
 		c.Assert(cfg.GetStringMapString("foo"), qt.DeepEquals, map[string]string{"bar": string("baz")})
 	})
 
 	c.Run("Set and get nested", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("a", map[string]interface{}{
+		cfg.Set("a", map[string]any{
 			"B": "bv",
 		})
 		cfg.Set("a.c", "cv")
@@ -86,7 +86,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 			"a": "av",
 		})
 
-		cfg.Set("b", map[string]interface{}{
+		cfg.Set("b", map[string]any{
 			"b": "bv",
 		})
 
@@ -99,7 +99,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 		cfg.Set("a", "av")
 
-		cfg.Set("", map[string]interface{}{
+		cfg.Set("", map[string]any{
 			"a": "av2",
 			"b": "bv2",
 		})
@@ -113,7 +113,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 		cfg.Set("a", "av")
 
-		cfg.Set("", map[string]interface{}{
+		cfg.Set("", map[string]any{
 			"b": "bv2",
 		})
 
@@ -124,14 +124,14 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 		cfg = New()
 
-		cfg.Set("", map[string]interface{}{
-			"foo": map[string]interface{}{
+		cfg.Set("", map[string]any{
+			"foo": map[string]any{
 				"a": "av",
 			},
 		})
 
-		cfg.Set("", map[string]interface{}{
-			"foo": map[string]interface{}{
+		cfg.Set("", map[string]any{
+			"foo": map[string]any{
 				"b": "bv2",
 			},
 		})
@@ -145,11 +145,11 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("Merge default strategy", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("a", map[string]interface{}{
+		cfg.Set("a", map[string]any{
 			"B": "bv",
 		})
 
-		cfg.Merge("a", map[string]interface{}{
+		cfg.Merge("a", map[string]any{
 			"B": "bv2",
 			"c": "cv2",
 		})
@@ -163,7 +163,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 		cfg.Set("a", "av")
 
-		cfg.Merge("", map[string]interface{}{
+		cfg.Merge("", map[string]any{
 			"a": "av2",
 			"b": "bv2",
 		})
@@ -176,16 +176,16 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("Merge shallow", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("a", map[string]interface{}{
+		cfg.Set("a", map[string]any{
 			"_merge": "shallow",
 			"B":      "bv",
-			"c": map[string]interface{}{
+			"c": map[string]any{
 				"b": "bv",
 			},
 		})
 
-		cfg.Merge("a", map[string]interface{}{
-			"c": map[string]interface{}{
+		cfg.Merge("a", map[string]any{
+			"c": map[string]any{
 				"d": "dv2",
 			},
 			"e": "ev2",
@@ -203,20 +203,20 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 	// Issue #8679
 	c.Run("Merge typed maps", func(c *qt.C) {
-		for _, left := range []interface{}{
+		for _, left := range []any{
 			map[string]string{
 				"c": "cv1",
 			},
-			map[string]interface{}{
+			map[string]any{
 				"c": "cv1",
 			},
-			map[interface{}]interface{}{
+			map[any]any{
 				"c": "cv1",
 			},
 		} {
 			cfg := New()
 
-			cfg.Set("", map[string]interface{}{
+			cfg.Set("", map[string]any{
 				"b": left,
 			})
 
@@ -235,27 +235,27 @@ func TestDefaultConfigProvider(t *testing.T) {
 			})
 		}
 
-		for _, left := range []interface{}{
+		for _, left := range []any{
 			map[string]string{
 				"b": "bv1",
 			},
-			map[string]interface{}{
+			map[string]any{
 				"b": "bv1",
 			},
-			map[interface{}]interface{}{
+			map[any]any{
 				"b": "bv1",
 			},
 		} {
-			for _, right := range []interface{}{
+			for _, right := range []any{
 				map[string]string{
 					"b": "bv2",
 					"c": "cv2",
 				},
-				map[string]interface{}{
+				map[string]any{
 					"b": "bv2",
 					"c": "cv2",
 				},
-				map[interface{}]interface{}{
+				map[any]any{
 					"b": "bv2",
 					"c": "cv2",
 				},
@@ -280,12 +280,12 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("Prevent _merge only maps", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("", map[string]interface{}{
+		cfg.Set("", map[string]any{
 			"B": "bv",
 		})
 
-		cfg.Merge("", map[string]interface{}{
-			"c": map[string]interface{}{
+		cfg.Merge("", map[string]any{
+			"c": map[string]any{
 				"_merge": "shallow",
 				"d":      "dv2",
 			},
@@ -299,7 +299,7 @@ func TestDefaultConfigProvider(t *testing.T) {
 	c.Run("IsSet", func(c *qt.C) {
 		cfg := New()
 
-		cfg.Set("a", map[string]interface{}{
+		cfg.Set("a", map[string]any{
 			"B": "bv",
 		})
 
@@ -357,15 +357,15 @@ func TestDefaultConfigProvider(t *testing.T) {
 
 func BenchmarkDefaultConfigProvider(b *testing.B) {
 	type cfger interface {
-		Get(key string) interface{}
-		Set(key string, value interface{})
+		Get(key string) any
+		Set(key string, value any)
 		IsSet(key string) bool
 	}
 
-	newMap := func() map[string]interface{} {
-		return map[string]interface{}{
-			"a": map[string]interface{}{
-				"b": map[string]interface{}{
+	newMap := func() map[string]any {
+		return map[string]any{
+			"a": map[string]any{
+				"b": map[string]any{
 					"c": 32,
 					"d": 43,
 				},
diff --git a/config/docshelper.go b/config/docshelper.go
@@ -35,7 +35,7 @@ func init() {
 		cfg.Set("languages", lang)
 		cfg.SetDefaultMergeStrategy()
 
-		configHelpers := map[string]interface{}{
+		configHelpers := map[string]any{
 			"mergeStrategy": cfg.Get(""),
 		}
 		return docshelper.DocProvider{"config": configHelpers}
diff --git a/config/security/securityConfig.go b/config/security/securityConfig.go
@@ -147,15 +147,15 @@ func (c Config) CheckAllowedHTTPMethod(method string) error {
 }
 
 // ToSecurityMap converts c to a map with 'security' as the root key.
-func (c Config) ToSecurityMap() map[string]interface{} {
+func (c Config) ToSecurityMap() map[string]any {
 	// Take it to JSON and back to get proper casing etc.
 	asJson, err := json.Marshal(c)
 	herrors.Must(err)
-	m := make(map[string]interface{})
+	m := make(map[string]any)
 	herrors.Must(json.Unmarshal(asJson, &m))
 
 	// Add the root
-	sec := map[string]interface{}{
+	sec := map[string]any{
 		"security": m,
 	}
 	return sec
@@ -196,7 +196,7 @@ func stringSliceToWhitelistHook() mapstructure.DecodeHookFuncType {
 	return func(
 		f reflect.Type,
 		t reflect.Type,
-		data interface{}) (interface{}, error) {
+		data any) (any, error) {
 
 		if t != reflect.TypeOf(Whitelist{}) {
 			return data, nil
diff --git a/config/services/servicesConfig_test.go b/config/services/servicesConfig_test.go
@@ -18,7 +18,6 @@ import (
 
 	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
-	
 )
 
 func TestDecodeConfigFromTOML(t *testing.T) {
diff --git a/create/content.go b/create/content.go
@@ -346,7 +346,7 @@ func (b *contentBuilder) openInEditorIfConfigured(filename string) error {
 	editorExec := strings.Fields(editor)[0]
 	editorFlags := strings.Fields(editor)[1:]
 
-	var args []interface{}
+	var args []any
 	for _, editorFlag := range editorFlags {
 		args = append(args, editorFlag)
 	}
diff --git a/create/content_test.go b/create/content_test.go
@@ -40,7 +40,7 @@ func TestNewContentFromFile(t *testing.T) {
 		name     string
 		kind     string
 		path     string
-		expected interface{}
+		expected any
 	}{
 		{"Post", "post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}},
 		{"Post org-mode", "post", "post/org-1.org", []string{`#+title: ORG-1`}},
@@ -368,7 +368,7 @@ Some text.
 	return nil
 }
 
-func cContains(c *qt.C, v interface{}, matches ...string) {
+func cContains(c *qt.C, v any, matches ...string) {
 	for _, m := range matches {
 		c.Assert(v, qt.Contains, m)
 	}
diff --git a/deploy/cloudfront.go b/deploy/cloudfront.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !nodeploy
 // +build !nodeploy
 
 package deploy
diff --git a/deploy/deploy.go b/deploy/deploy.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !nodeploy
 // +build !nodeploy
 
 package deploy
diff --git a/deploy/deployConfig.go b/deploy/deployConfig.go
@@ -115,7 +115,7 @@ func (m *matcher) Matches(path string) bool {
 // decode creates a config from a given Hugo configuration.
 func decodeConfig(cfg config.Provider) (deployConfig, error) {
 	var (
-		mediaTypesConfig []map[string]interface{}
+		mediaTypesConfig []map[string]any
 		dcfg             deployConfig
 	)
 
diff --git a/deploy/deploy_azure.go b/deploy/deploy_azure.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !solaris && !nodeploy
 // +build !solaris,!nodeploy
 
 package deploy
diff --git a/deploy/deploy_test.go b/deploy/deploy_test.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !nodeploy
 // +build !nodeploy
 
 package deploy
@@ -252,7 +253,7 @@ func TestWalkLocal(t *testing.T) {
 			if got, err := walkLocal(fs, nil, nil, nil, media.DefaultTypes); err != nil {
 				t.Fatal(err)
 			} else {
-				expect := map[string]interface{}{}
+				expect := map[string]any{}
 				for _, path := range tc.Expect {
 					if _, ok := got[path]; !ok {
 						t.Errorf("expected %q in results, but was not found", path)
@@ -290,7 +291,7 @@ func TestLocalFile(t *testing.T) {
 		Description         string
 		Path                string
 		Matcher             *matcher
-		MediaTypesConfig    []map[string]interface{}
+		MediaTypesConfig    []map[string]any
 		WantContent         []byte
 		WantSize            int64
 		WantMD5             []byte
@@ -351,9 +352,9 @@ func TestLocalFile(t *testing.T) {
 		{
 			Description: "Custom MediaType",
 			Path:        "foo.hugo",
-			MediaTypesConfig: []map[string]interface{}{
+			MediaTypesConfig: []map[string]any{
 				{
-					"hugo/custom": map[string]interface{}{
+					"hugo/custom": map[string]any{
 						"suffixes": []string{"hugo"},
 					},
 				},
diff --git a/deploy/google.go b/deploy/google.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !nodeploy
 // +build !nodeploy
 
 package deploy
diff --git a/deps/deps.go b/deps/deps.go
@@ -68,7 +68,7 @@ type Deps struct {
 	FileCaches filecache.Caches
 
 	// The translation func to use
-	Translate func(translationID string, templateData interface{}) string `json:"-"`
+	Translate func(translationID string, templateData any) string `json:"-"`
 
 	// The language in use. TODO(bep) consolidate with site
 	Language *langs.Language
@@ -83,7 +83,7 @@ type Deps struct {
 	WithTemplate     func(templ tpl.TemplateManager) error `json:"-"`
 
 	// Used in tests
-	OverloadedTemplateFuncs map[string]interface{}
+	OverloadedTemplateFuncs map[string]any
 
 	translationProvider ResourceProvider
 
@@ -392,7 +392,7 @@ type DepsCfg struct {
 	TemplateProvider ResourceProvider
 	WithTemplate     func(templ tpl.TemplateManager) error
 	// Used in tests
-	OverloadedTemplateFuncs map[string]interface{}
+	OverloadedTemplateFuncs map[string]any
 
 	// i18n handling.
 	TranslationProvider ResourceProvider
diff --git a/docshelper/docs.go b/docshelper/docs.go
@@ -17,7 +17,7 @@ package docshelper
 
 type (
 	DocProviderFunc = func() DocProvider
-	DocProvider     map[string]map[string]interface{}
+	DocProvider     map[string]map[string]any
 )
 
 var docProviderFuncs []DocProviderFunc
@@ -44,7 +44,7 @@ func GetDocProvider() DocProvider {
 }
 
 // Shallow merge
-func merge(dst, src map[string]interface{}) {
+func merge(dst, src map[string]any) {
 	for k, v := range src {
 		dst[k] = v
 	}
diff --git a/helpers/content.go b/helpers/content.go
@@ -49,7 +49,7 @@ var (
 type ContentSpec struct {
 	Converters          markup.ConverterProvider
 	anchorNameSanitizer converter.AnchorNameSanitizer
-	getRenderer         func(t hooks.RendererType, id interface{}) interface{}
+	getRenderer         func(t hooks.RendererType, id any) any
 
 	// SummaryLength is the length of the summary that Hugo extracts from a content.
 	summaryLength int
diff --git a/helpers/docshelper.go b/helpers/docshelper.go
@@ -12,7 +12,7 @@ import (
 // This is is just some helpers used to create some JSON used in the Hugo docs.
 func init() {
 	docsProvider := func() docshelper.DocProvider {
-		var chromaLexers []interface{}
+		var chromaLexers []any
 
 		sort.Sort(lexers.Registry.Lexers)
 
@@ -47,7 +47,7 @@ func init() {
 
 		}
 
-		return docshelper.DocProvider{"chroma": map[string]interface{}{"lexers": chromaLexers}}
+		return docshelper.DocProvider{"chroma": map[string]any{"lexers": chromaLexers}}
 	}
 
 	docshelper.AddDocProviderFunc(docsProvider)
diff --git a/helpers/general.go b/helpers/general.go
@@ -274,7 +274,7 @@ func (l *DistinctLogger) Reset() {
 
 // Println will log the string returned from fmt.Sprintln given the arguments,
 // but not if it has been logged before.
-func (l *DistinctLogger) Println(v ...interface{}) {
+func (l *DistinctLogger) Println(v ...any) {
 	// fmt.Sprint doesn't add space between string arguments
 	logStatement := strings.TrimSpace(fmt.Sprintln(v...))
 	l.printIfNotPrinted("println", logStatement, func() {
@@ -284,63 +284,63 @@ func (l *DistinctLogger) Println(v ...interface{}) {
 
 // Printf will log the string returned from fmt.Sprintf given the arguments,
 // but not if it has been logged before.
-func (l *DistinctLogger) Printf(format string, v ...interface{}) {
+func (l *DistinctLogger) Printf(format string, v ...any) {
 	logStatement := fmt.Sprintf(format, v...)
 	l.printIfNotPrinted("printf", logStatement, func() {
 		l.Logger.Printf(format, v...)
 	})
 }
 
-func (l *DistinctLogger) Debugf(format string, v ...interface{}) {
+func (l *DistinctLogger) Debugf(format string, v ...any) {
 	logStatement := fmt.Sprintf(format, v...)
 	l.printIfNotPrinted("debugf", logStatement, func() {
 		l.Logger.Debugf(format, v...)
 	})
 }
 
-func (l *DistinctLogger) Debugln(v ...interface{}) {
+func (l *DistinctLogger) Debugln(v ...any) {
 	logStatement := fmt.Sprint(v...)
 	l.printIfNotPrinted("debugln", logStatement, func() {
 		l.Logger.Debugln(v...)
 	})
 }
 
-func (l *DistinctLogger) Infof(format string, v ...interface{}) {
+func (l *DistinctLogger) Infof(format string, v ...any) {
 	logStatement := fmt.Sprintf(format, v...)
 	l.printIfNotPrinted("info", logStatement, func() {
 		l.Logger.Infof(format, v...)
 	})
 }
 
-func (l *DistinctLogger) Infoln(v ...interface{}) {
+func (l *DistinctLogger) Infoln(v ...any) {
 	logStatement := fmt.Sprint(v...)
 	l.printIfNotPrinted("infoln", logStatement, func() {
 		l.Logger.Infoln(v...)
 	})
 }
 
-func (l *DistinctLogger) Warnf(format string, v ...interface{}) {
+func (l *DistinctLogger) Warnf(format string, v ...any) {
 	logStatement := fmt.Sprintf(format, v...)
 	l.printIfNotPrinted("warnf", logStatement, func() {
 		l.Logger.Warnf(format, v...)
 	})
 }
 
-func (l *DistinctLogger) Warnln(v ...interface{}) {
+func (l *DistinctLogger) Warnln(v ...any) {
 	logStatement := fmt.Sprint(v...)
 	l.printIfNotPrinted("warnln", logStatement, func() {
 		l.Logger.Warnln(v...)
 	})
 }
 
-func (l *DistinctLogger) Errorf(format string, v ...interface{}) {
+func (l *DistinctLogger) Errorf(format string, v ...any) {
 	logStatement := fmt.Sprint(v...)
 	l.printIfNotPrinted("errorf", logStatement, func() {
 		l.Logger.Errorf(format, v...)
 	})
 }
 
-func (l *DistinctLogger) Errorln(v ...interface{}) {
+func (l *DistinctLogger) Errorln(v ...any) {
 	logStatement := fmt.Sprint(v...)
 	l.printIfNotPrinted("errorln", logStatement, func() {
 		l.Logger.Errorln(v...)
@@ -507,7 +507,7 @@ func PrintFs(fs afero.Fs, path string, w io.Writer) {
 
 	afero.Walk(fs, path, func(path string, info os.FileInfo, err error) error {
 		var filename string
-		var meta interface{}
+		var meta any
 		if fim, ok := info.(hugofs.FileMetaInfo); ok {
 			filename = fim.Meta().Filename
 			meta = fim.Meta()
@@ -519,8 +519,8 @@ func PrintFs(fs afero.Fs, path string, w io.Writer) {
 
 // HashString returns a hash from the given elements.
 // It will panic if the hash cannot be calculated.
-func HashString(elements ...interface{}) string {
-	var o interface{}
+func HashString(elements ...any) string {
+	var o any
 	if len(elements) == 1 {
 		o = elements[0]
 	} else {
diff --git a/helpers/testhelpers_test.go b/helpers/testhelpers_test.go
@@ -16,7 +16,7 @@ func newTestPathSpec(fs *hugofs.Fs, v config.Provider) *PathSpec {
 	return ps
 }
 
-func newTestDefaultPathSpec(configKeyValues ...interface{}) *PathSpec {
+func newTestDefaultPathSpec(configKeyValues ...any) *PathSpec {
 	v := config.New()
 	fs := hugofs.NewMem(v)
 	cfg := newTestCfg()
diff --git a/htesting/hqt/checkers.go b/htesting/hqt/checkers.go
@@ -49,7 +49,7 @@ type typeChecker struct {
 }
 
 // Check implements Checker.Check by checking that got and args[0] is of the same type.
-func (c *typeChecker) Check(got interface{}, args []interface{}, note func(key string, value interface{})) (err error) {
+func (c *typeChecker) Check(got any, args []any, note func(key string, value any)) (err error) {
 	if want := args[0]; reflect.TypeOf(got) != reflect.TypeOf(want) {
 		if _, ok := got.(error); ok && want == nil {
 			return errors.New("got non-nil error")
@@ -64,7 +64,7 @@ type stringChecker struct {
 }
 
 // Check implements Checker.Check by checking that got and args[0] represents the same normalized text (whitespace etc. removed).
-func (c *stringChecker) Check(got interface{}, args []interface{}, note func(key string, value interface{})) (err error) {
+func (c *stringChecker) Check(got any, args []any, note func(key string, value any)) (err error) {
 	s1, s2 := cast.ToString(got), cast.ToString(args[0])
 
 	if s1 == s2 {
@@ -93,12 +93,12 @@ func normalizeString(s string) string {
 // DeepAllowUnexported creates an option to allow compare of unexported types
 // in the given list of types.
 // see https://github.com/google/go-cmp/issues/40#issuecomment-328615283
-func DeepAllowUnexported(vs ...interface{}) cmp.Option {
+func DeepAllowUnexported(vs ...any) cmp.Option {
 	m := make(map[reflect.Type]struct{})
 	for _, v := range vs {
 		structTypes(reflect.ValueOf(v), m)
 	}
-	var typs []interface{}
+	var typs []any
 	for t := range m {
 		typs = append(typs, reflect.New(t).Elem().Interface())
 	}
diff --git a/hugofs/fileinfo.go b/hugofs/fileinfo.go
@@ -188,7 +188,7 @@ func (fi *dirNameOnlyFileInfo) IsDir() bool {
 	return true
 }
 
-func (fi *dirNameOnlyFileInfo) Sys() interface{} {
+func (fi *dirNameOnlyFileInfo) Sys() any {
 	return nil
 }
 
diff --git a/hugofs/rootmapping_fs.go b/hugofs/rootmapping_fs.go
@@ -203,7 +203,7 @@ func (fs *RootMappingFs) Dirs(base string) ([]FileMetaInfo, error) {
 // Filter creates a copy of this filesystem with only mappings matching a filter.
 func (fs RootMappingFs) Filter(f func(m RootMapping) bool) *RootMappingFs {
 	rootMapToReal := radix.New()
-	fs.rootMapToReal.Walk(func(b string, v interface{}) bool {
+	fs.rootMapToReal.Walk(func(b string, v any) bool {
 		rms := v.([]RootMapping)
 		var nrms []RootMapping
 		for _, rm := range rms {
@@ -250,7 +250,7 @@ func (fs *RootMappingFs) Stat(name string) (os.FileInfo, error) {
 
 func (fs *RootMappingFs) hasPrefix(prefix string) bool {
 	hasPrefix := false
-	fs.rootMapToReal.WalkPrefix(prefix, func(b string, v interface{}) bool {
+	fs.rootMapToReal.WalkPrefix(prefix, func(b string, v any) bool {
 		hasPrefix = true
 		return true
 	})
@@ -277,7 +277,7 @@ func (fs *RootMappingFs) getRoots(key string) (string, []RootMapping) {
 
 func (fs *RootMappingFs) debug() {
 	fmt.Println("debug():")
-	fs.rootMapToReal.Walk(func(s string, v interface{}) bool {
+	fs.rootMapToReal.Walk(func(s string, v any) bool {
 		fmt.Println("Key", s)
 		return false
 	})
@@ -285,7 +285,7 @@ func (fs *RootMappingFs) debug() {
 
 func (fs *RootMappingFs) getRootsWithPrefix(prefix string) []RootMapping {
 	var roots []RootMapping
-	fs.rootMapToReal.WalkPrefix(prefix, func(b string, v interface{}) bool {
+	fs.rootMapToReal.WalkPrefix(prefix, func(b string, v any) bool {
 		roots = append(roots, v.([]RootMapping)...)
 		return false
 	})
@@ -295,7 +295,7 @@ func (fs *RootMappingFs) getRootsWithPrefix(prefix string) []RootMapping {
 
 func (fs *RootMappingFs) getAncestors(prefix string) []keyRootMappings {
 	var roots []keyRootMappings
-	fs.rootMapToReal.WalkPath(prefix, func(s string, v interface{}) bool {
+	fs.rootMapToReal.WalkPath(prefix, func(s string, v any) bool {
 		if strings.HasPrefix(prefix, s+filepathSeparator) {
 			roots = append(roots, keyRootMappings{
 				key:   s,
@@ -416,7 +416,7 @@ func (fs *RootMappingFs) collectDirEntries(prefix string) ([]os.FileInfo, error)
 
 	// Next add any file mounts inside the given directory.
 	prefixInside := prefix + filepathSeparator
-	fs.rootMapToReal.WalkPrefix(prefixInside, func(s string, v interface{}) bool {
+	fs.rootMapToReal.WalkPrefix(prefixInside, func(s string, v any) bool {
 		if (strings.Count(s, filepathSeparator) - level) != 1 {
 			// This directory is not part of the current, but we
 			// need to include the first name part to make it
diff --git a/hugolib/alias_test.go b/hugolib/alias_test.go
@@ -51,13 +51,13 @@ func TestAlias(t *testing.T) {
 		fileSuffix string
 		urlPrefix  string
 		urlSuffix  string
-		settings   map[string]interface{}
+		settings   map[string]any
 	}{
-		{"/index.html", "http://example.com", "/", map[string]interface{}{"baseURL": "http://example.com"}},
-		{"/index.html", "http://example.com/some/path", "/", map[string]interface{}{"baseURL": "http://example.com/some/path"}},
-		{"/index.html", "http://example.com", "/", map[string]interface{}{"baseURL": "http://example.com", "canonifyURLs": true}},
-		{"/index.html", "../..", "/", map[string]interface{}{"relativeURLs": true}},
-		{".html", "", ".html", map[string]interface{}{"uglyURLs": true}},
+		{"/index.html", "http://example.com", "/", map[string]any{"baseURL": "http://example.com"}},
+		{"/index.html", "http://example.com/some/path", "/", map[string]any{"baseURL": "http://example.com/some/path"}},
+		{"/index.html", "http://example.com", "/", map[string]any{"baseURL": "http://example.com", "canonifyURLs": true}},
+		{"/index.html", "../..", "/", map[string]any{"relativeURLs": true}},
+		{".html", "", ".html", map[string]any{"uglyURLs": true}},
 	}
 
 	for _, test := range tests {
diff --git a/hugolib/cascade_test.go b/hugolib/cascade_test.go
@@ -335,7 +335,7 @@ Banner: post.jpg`,
 }
 
 func newCascadeTestBuilder(t testing.TB, langs []string) *sitesBuilder {
-	p := func(m map[string]interface{}) string {
+	p := func(m map[string]any) string {
 		var yamlStr string
 
 		if len(m) > 0 {
@@ -392,76 +392,76 @@ defaultContentLanguageInSubDir = false
 		}
 
 		withContent(
-			"_index.md", p(map[string]interface{}{
+			"_index.md", p(map[string]any{
 				"title": "Home",
-				"cascade": map[string]interface{}{
+				"cascade": map[string]any{
 					"title":   "Cascade Home",
 					"ICoN":    "home.png",
 					"outputs": []string{"HTML"},
 					"weight":  42,
 				},
 			}),
-			"p1.md", p(map[string]interface{}{
+			"p1.md", p(map[string]any{
 				"title": "p1",
 			}),
-			"p2.md", p(map[string]interface{}{}),
-			"sect1/_index.md", p(map[string]interface{}{
+			"p2.md", p(map[string]any{}),
+			"sect1/_index.md", p(map[string]any{
 				"title": "Sect1",
 				"type":  "stype",
-				"cascade": map[string]interface{}{
+				"cascade": map[string]any{
 					"title":      "Cascade Sect1",
 					"icon":       "sect1.png",
 					"type":       "stype",
 					"categories": []string{"catsect1"},
 				},
 			}),
-			"sect1/s1_2/_index.md", p(map[string]interface{}{
+			"sect1/s1_2/_index.md", p(map[string]any{
 				"title": "Sect1_2",
 			}),
-			"sect1/s1_2/p1.md", p(map[string]interface{}{
+			"sect1/s1_2/p1.md", p(map[string]any{
 				"title": "Sect1_2_p1",
 			}),
-			"sect1/s1_2/p2.md", p(map[string]interface{}{
+			"sect1/s1_2/p2.md", p(map[string]any{
 				"title": "Sect1_2_p2",
 			}),
-			"sect2/_index.md", p(map[string]interface{}{
+			"sect2/_index.md", p(map[string]any{
 				"title": "Sect2",
 			}),
-			"sect2/p1.md", p(map[string]interface{}{
+			"sect2/p1.md", p(map[string]any{
 				"title":      "Sect2_p1",
 				"categories": []string{"cool", "funny", "sad"},
 				"tags":       []string{"blue", "green"},
 			}),
-			"sect2/p2.md", p(map[string]interface{}{}),
-			"sect3/p1.md", p(map[string]interface{}{}),
+			"sect2/p2.md", p(map[string]any{}),
+			"sect3/p1.md", p(map[string]any{}),
 
 			// No front matter, see #6855
 			"sect3/nofrontmatter.md", `**Hello**`,
 			"sectnocontent/p1.md", `**Hello**`,
 			"sectnofrontmatter/_index.md", `**Hello**`,
 
-			"sect4/_index.md", p(map[string]interface{}{
+			"sect4/_index.md", p(map[string]any{
 				"title": "Sect4",
-				"cascade": map[string]interface{}{
+				"cascade": map[string]any{
 					"weight":  52,
 					"outputs": []string{"RSS"},
 				},
 			}),
-			"sect4/p1.md", p(map[string]interface{}{}),
-			"p2.md", p(map[string]interface{}{}),
-			"bundle1/index.md", p(map[string]interface{}{}),
-			"bundle1/bp1.md", p(map[string]interface{}{}),
-			"categories/_index.md", p(map[string]interface{}{
+			"sect4/p1.md", p(map[string]any{}),
+			"p2.md", p(map[string]any{}),
+			"bundle1/index.md", p(map[string]any{}),
+			"bundle1/bp1.md", p(map[string]any{}),
+			"categories/_index.md", p(map[string]any{
 				"title": "My Categories",
-				"cascade": map[string]interface{}{
+				"cascade": map[string]any{
 					"title":  "Cascade Category",
 					"icoN":   "cat.png",
 					"weight": 12,
 				},
 			}),
-			"categories/cool/_index.md", p(map[string]interface{}{}),
-			"categories/sad/_index.md", p(map[string]interface{}{
-				"cascade": map[string]interface{}{
+			"categories/cool/_index.md", p(map[string]any{}),
+			"categories/sad/_index.md", p(map[string]any{
+				"cascade": map[string]any{
 					"icon":   "sad.png",
 					"weight": 32,
 				},
diff --git a/hugolib/collections.go b/hugolib/collections.go
@@ -28,7 +28,7 @@ var (
 // implementations have no value on their own.
 
 // Slice is not meant to be used externally. It's a bridge function
-func (p *pageState) Slice(items interface{}) (interface{}, error) {
+func (p *pageState) Slice(items any) (any, error) {
 	return page.ToPages(items)
 }
 
@@ -37,7 +37,7 @@ func (p *pageState) Slice(items interface{}) (interface{}, error) {
 // Group creates a PageGroup from a key and a Pages object
 // This method is not meant for external use. It got its non-typed arguments to satisfy
 // a very generic interface in the tpl package.
-func (p *pageState) Group(key interface{}, in interface{}) (interface{}, error) {
+func (p *pageState) Group(key any, in any) (any, error) {
 	pages, err := page.ToPages(in)
 	if err != nil {
 		return nil, err
diff --git a/hugolib/config_test.go b/hugolib/config_test.go
@@ -250,12 +250,12 @@ name = "menu-theme"
 
 		b.Assert(got["mediatypes"], qt.DeepEquals, maps.Params{
 			"text/m2": maps.Params{
-				"suffixes": []interface{}{
+				"suffixes": []any{
 					"m2theme",
 				},
 			},
 			"text/m1": maps.Params{
-				"suffixes": []interface{}{
+				"suffixes": []any{
 					"m1main",
 				},
 			},
@@ -293,13 +293,13 @@ name = "menu-theme"
 					"pl1": "p1-en-main",
 				},
 				"menus": maps.Params{
-					"main": []interface{}{
-						map[string]interface{}{
+					"main": []any{
+						map[string]any{
 							"name": "menu-lang-en-main",
 						},
 					},
-					"theme": []interface{}{
-						map[string]interface{}{
+					"theme": []any{
+						map[string]any{
 							"name": "menu-lang-en-theme",
 						},
 					},
@@ -313,18 +313,18 @@ name = "menu-theme"
 					"pl2": "p2-nb-theme",
 				},
 				"menus": maps.Params{
-					"main": []interface{}{
-						map[string]interface{}{
+					"main": []any{
+						map[string]any{
 							"name": "menu-lang-nb-main",
 						},
 					},
-					"theme": []interface{}{
-						map[string]interface{}{
+					"theme": []any{
+						map[string]any{
 							"name": "menu-lang-nb-theme",
 						},
 					},
-					"top": []interface{}{
-						map[string]interface{}{
+					"top": []any{
+						map[string]any{
 							"name": "menu-lang-nb-top",
 						},
 					},
@@ -399,8 +399,8 @@ name   = "menu-theme"
 				"en": maps.Params{
 					"languagename": "English",
 					"menus": maps.Params{
-						"main": []interface{}{
-							map[string]interface{}{
+						"main": []any{
+							map[string]any{
 								"name": "menu-theme",
 							},
 						},
@@ -710,9 +710,9 @@ theme_param="themevalue2"
 		c.Assert(cfg.Get("imaging.anchor"), qt.Equals, "top")
 		c.Assert(cfg.Get("imaging.quality"), qt.Equals, int64(75))
 		c.Assert(cfg.Get("imaging.resamplefilter"), qt.Equals, "CatmullRom")
-		c.Assert(cfg.Get("stringSlice"), qt.DeepEquals, []interface{}{"c", "d"})
-		c.Assert(cfg.Get("floatSlice"), qt.DeepEquals, []interface{}{5.32})
-		c.Assert(cfg.Get("intSlice"), qt.DeepEquals, []interface{}{5, 8, 9})
+		c.Assert(cfg.Get("stringSlice"), qt.DeepEquals, []any{"c", "d"})
+		c.Assert(cfg.Get("floatSlice"), qt.DeepEquals, []any{5.32})
+		c.Assert(cfg.Get("intSlice"), qt.DeepEquals, []any{5, 8, 9})
 		c.Assert(cfg.Get("params.api_config.api_key"), qt.Equals, "new_key")
 		c.Assert(cfg.Get("params.api_config.another_key"), qt.Equals, "default another_key")
 		c.Assert(cfg.Get("params.mytheme_section.theme_param"), qt.Equals, "themevalue_changed")
diff --git a/hugolib/configdir_test.go b/hugolib/configdir_test.go
@@ -119,10 +119,10 @@ p3 = "p3params_no_production"
 	c.Assert(cfg.GetString("params.p3"), qt.Equals, "p3params_development")
 	c.Assert(cfg.GetString("languages.no.params.p3"), qt.Equals, "p3params_no_development")
 
-	c.Assert(len(cfg.Get("menus.docs").([]interface{})), qt.Equals, 2)
+	c.Assert(len(cfg.Get("menus.docs").([]any)), qt.Equals, 2)
 	noMenus := cfg.Get("languages.no.menus.docs")
 	c.Assert(noMenus, qt.Not(qt.IsNil))
-	c.Assert(len(noMenus.([]interface{})), qt.Equals, 1)
+	c.Assert(len(noMenus.([]any)), qt.Equals, 1)
 }
 
 func TestLoadConfigDirError(t *testing.T) {
diff --git a/hugolib/content_map.go b/hugolib/content_map.go
@@ -83,7 +83,7 @@ func newContentMap(cfg contentMapConfig) *contentMap {
 		m.sections, m.taxonomies,
 	}
 
-	addToReverseMap := func(k string, n *contentNode, m map[interface{}]*contentNode) {
+	addToReverseMap := func(k string, n *contentNode, m map[any]*contentNode) {
 		k = strings.ToLower(k)
 		existing, found := m[k]
 		if found && existing != ambiguousContentNode {
@@ -96,8 +96,8 @@ func newContentMap(cfg contentMapConfig) *contentMap {
 	m.pageReverseIndex = &contentTreeReverseIndex{
 		t: []*contentTree{m.pages, m.sections, m.taxonomies},
 		contentTreeReverseIndexMap: &contentTreeReverseIndexMap{
-			initFn: func(t *contentTree, m map[interface{}]*contentNode) {
-				t.Walk(func(s string, v interface{}) bool {
+			initFn: func(t *contentTree, m map[any]*contentNode) {
+				t.Walk(func(s string, v any) bool {
 					n := v.(*contentNode)
 					if n.p != nil && !n.p.File().IsZero() {
 						meta := n.p.File().FileInfo().Meta()
@@ -396,7 +396,7 @@ func (m *contentMap) AddFilesBundle(header hugofs.FileMetaInfo, resources ...hug
 
 func (m *contentMap) CreateMissingNodes() error {
 	// Create missing home and root sections
-	rootSections := make(map[string]interface{})
+	rootSections := make(map[string]any)
 	trackRootSection := func(s string, b *contentNode) {
 		parts := strings.Split(s, "/")
 		if len(parts) > 2 {
@@ -409,7 +409,7 @@ func (m *contentMap) CreateMissingNodes() error {
 		}
 	}
 
-	m.sections.Walk(func(s string, v interface{}) bool {
+	m.sections.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 
 		if s == "/" {
@@ -420,7 +420,7 @@ func (m *contentMap) CreateMissingNodes() error {
 		return false
 	})
 
-	m.pages.Walk(func(s string, v interface{}) bool {
+	m.pages.Walk(func(s string, v any) bool {
 		trackRootSection(s, v.(*contentNode))
 		return false
 	})
@@ -614,7 +614,7 @@ func (m *contentMap) deleteBundleMatching(matches func(b *contentNode) bool) {
 func (m *contentMap) deleteOrphanSections() {
 	var sectionsToDelete []string
 
-	m.sections.Walk(func(s string, v interface{}) bool {
+	m.sections.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 
 		if n.fi != nil {
@@ -658,7 +658,7 @@ func (m *contentMap) deleteSectionByPath(s string) {
 }
 
 func (m *contentMap) deletePageByPath(s string) {
-	m.pages.Walk(func(s string, v interface{}) bool {
+	m.pages.Walk(func(s string, v any) bool {
 		fmt.Println("S", s)
 
 		return false
@@ -689,14 +689,14 @@ func (m *contentMap) testDump() string {
 
 	for i, r := range []*contentTree{m.pages, m.sections, m.resources} {
 		sb.WriteString(fmt.Sprintf("Tree %d:\n", i))
-		r.Walk(func(s string, v interface{}) bool {
+		r.Walk(func(s string, v any) bool {
 			sb.WriteString("\t" + s + "\n")
 			return false
 		})
 	}
 
 	for i, r := range []*contentTree{m.pages, m.sections} {
-		r.Walk(func(s string, v interface{}) bool {
+		r.Walk(func(s string, v any) bool {
 			c := v.(*contentNode)
 			cpToString := func(c *contentNode) string {
 				var sb strings.Builder
@@ -715,13 +715,13 @@ func (m *contentMap) testDump() string {
 			if i == 1 {
 				resourcesPrefix += cmLeafSeparator
 
-				m.pages.WalkPrefix(s+cmBranchSeparator, func(s string, v interface{}) bool {
+				m.pages.WalkPrefix(s+cmBranchSeparator, func(s string, v any) bool {
 					sb.WriteString("\t - P: " + filepath.ToSlash((v.(*contentNode).fi.(hugofs.FileMetaInfo)).Meta().Filename) + "\n")
 					return false
 				})
 			}
 
-			m.resources.WalkPrefix(resourcesPrefix, func(s string, v interface{}) bool {
+			m.resources.WalkPrefix(resourcesPrefix, func(s string, v any) bool {
 				sb.WriteString("\t - R: " + filepath.ToSlash((v.(*contentNode).fi.(hugofs.FileMetaInfo)).Meta().Filename) + "\n")
 				return false
 			})
@@ -791,7 +791,7 @@ type contentTrees []*contentTree
 func (t contentTrees) DeletePrefix(prefix string) int {
 	var count int
 	for _, tree := range t {
-		tree.Walk(func(s string, v interface{}) bool {
+		tree.Walk(func(s string, v any) bool {
 			return false
 		})
 		count += tree.DeletePrefix(prefix)
@@ -836,7 +836,7 @@ func (c *contentTree) WalkQuery(query pageMapQuery, walkFn contentTreeNodeCallba
 		filter = contentTreeNoListAlwaysFilter
 	}
 	if query.Prefix != "" {
-		c.WalkBelow(query.Prefix, func(s string, v interface{}) bool {
+		c.WalkBelow(query.Prefix, func(s string, v any) bool {
 			n := v.(*contentNode)
 			if filter != nil && filter(s, n) {
 				return false
@@ -847,7 +847,7 @@ func (c *contentTree) WalkQuery(query pageMapQuery, walkFn contentTreeNodeCallba
 		return
 	}
 
-	c.Walk(func(s string, v interface{}) bool {
+	c.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 		if filter != nil && filter(s, n) {
 			return false
@@ -872,7 +872,7 @@ func (c contentTrees) WalkLinkable(fn contentTreeNodeCallback) {
 
 func (c contentTrees) Walk(fn contentTreeNodeCallback) {
 	for _, tree := range c {
-		tree.Walk(func(s string, v interface{}) bool {
+		tree.Walk(func(s string, v any) bool {
 			n := v.(*contentNode)
 			return fn(s, n)
 		})
@@ -881,7 +881,7 @@ func (c contentTrees) Walk(fn contentTreeNodeCallback) {
 
 func (c contentTrees) WalkPrefix(prefix string, fn contentTreeNodeCallback) {
 	for _, tree := range c {
-		tree.WalkPrefix(prefix, func(s string, v interface{}) bool {
+		tree.WalkPrefix(prefix, func(s string, v any) bool {
 			n := v.(*contentNode)
 			return fn(s, n)
 		})
@@ -891,7 +891,7 @@ func (c contentTrees) WalkPrefix(prefix string, fn contentTreeNodeCallback) {
 // WalkBelow walks the tree below the given prefix, i.e. it skips the
 // node with the given prefix as key.
 func (c *contentTree) WalkBelow(prefix string, fn radix.WalkFn) {
-	c.Tree.WalkPrefix(prefix, func(s string, v interface{}) bool {
+	c.Tree.WalkPrefix(prefix, func(s string, v any) bool {
 		if s == prefix {
 			return false
 		}
@@ -901,7 +901,7 @@ func (c *contentTree) WalkBelow(prefix string, fn radix.WalkFn) {
 
 func (c *contentTree) getMatch(matches func(b *contentNode) bool) string {
 	var match string
-	c.Walk(func(s string, v interface{}) bool {
+	c.Walk(func(s string, v any) bool {
 		n, ok := v.(*contentNode)
 		if !ok {
 			return false
@@ -920,7 +920,7 @@ func (c *contentTree) getMatch(matches func(b *contentNode) bool) string {
 
 func (c *contentTree) hasBelow(s1 string) bool {
 	var t bool
-	c.WalkBelow(s1, func(s2 string, v interface{}) bool {
+	c.WalkBelow(s1, func(s2 string, v any) bool {
 		t = true
 		return true
 	})
@@ -928,14 +928,14 @@ func (c *contentTree) hasBelow(s1 string) bool {
 }
 
 func (c *contentTree) printKeys() {
-	c.Walk(func(s string, v interface{}) bool {
+	c.Walk(func(s string, v any) bool {
 		fmt.Println(s)
 		return false
 	})
 }
 
 func (c *contentTree) printKeysPrefix(prefix string) {
-	c.WalkPrefix(prefix, func(s string, v interface{}) bool {
+	c.WalkPrefix(prefix, func(s string, v any) bool {
 		fmt.Println(s)
 		return false
 	})
@@ -1040,9 +1040,9 @@ type contentTreeReverseIndex struct {
 }
 
 type contentTreeReverseIndexMap struct {
-	m      map[interface{}]*contentNode
+	m      map[any]*contentNode
 	init   sync.Once
-	initFn func(*contentTree, map[interface{}]*contentNode)
+	initFn func(*contentTree, map[any]*contentNode)
 }
 
 func (c *contentTreeReverseIndex) Reset() {
@@ -1051,9 +1051,9 @@ func (c *contentTreeReverseIndex) Reset() {
 	}
 }
 
-func (c *contentTreeReverseIndex) Get(key interface{}) *contentNode {
+func (c *contentTreeReverseIndex) Get(key any) *contentNode {
 	c.init.Do(func() {
-		c.m = make(map[interface{}]*contentNode)
+		c.m = make(map[any]*contentNode)
 		for _, tree := range c.t {
 			c.initFn(tree, c.m)
 		}
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
@@ -66,7 +66,7 @@ func (m *pageMap) createMissingTaxonomyNodes() error {
 	if m.cfg.taxonomyDisabled {
 		return nil
 	}
-	m.taxonomyEntries.Walk(func(s string, v interface{}) bool {
+	m.taxonomyEntries.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 		vi := n.viewInfo
 		k := cleanSectionTreeKey(vi.name.plural + "/" + vi.termKey)
@@ -174,7 +174,7 @@ func (m *pageMap) newPageFromContentNode(n *contentNode, parentBucket *pagesMapB
 		return nil, err
 	}
 
-	ps.init.Add(func() (interface{}, error) {
+	ps.init.Add(func() (any, error) {
 		pp, err := newPagePaths(s, ps, metaProvider)
 		if err != nil {
 			return nil, err
@@ -271,7 +271,7 @@ func (m *pageMap) newResource(fim hugofs.FileMetaInfo, owner *pageState) (resour
 func (m *pageMap) createSiteTaxonomies() error {
 	m.s.taxonomies = make(TaxonomyList)
 	var walkErr error
-	m.taxonomies.Walk(func(s string, v interface{}) bool {
+	m.taxonomies.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 		t := n.viewInfo
 
@@ -285,7 +285,7 @@ func (m *pageMap) createSiteTaxonomies() error {
 				walkErr = errors.Errorf("missing taxonomy: %s", viewName.plural)
 				return true
 			}
-			m.taxonomyEntries.WalkPrefix(s, func(ss string, v interface{}) bool {
+			m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool {
 				b2 := v.(*contentNode)
 				info := b2.viewInfo
 				taxonomy.add(info.termKey, page.NewWeightedPage(info.weight, info.ref.p, n.p))
@@ -337,7 +337,7 @@ func (m *pageMap) assemblePages() error {
 		return err
 	}
 
-	m.pages.Walk(func(s string, v interface{}) bool {
+	m.pages.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 
 		var shouldBuild bool
@@ -397,7 +397,7 @@ func (m *pageMap) assemblePages() error {
 func (m *pageMap) assembleResources(s string, p *pageState, parentBucket *pagesMapBucket) error {
 	var err error
 
-	m.resources.WalkPrefix(s, func(s string, v interface{}) bool {
+	m.resources.WalkPrefix(s, func(s string, v any) bool {
 		n := v.(*contentNode)
 		meta := n.fi.Meta()
 		classifier := meta.Classifier
@@ -432,7 +432,7 @@ func (m *pageMap) assembleSections() error {
 	var sectionsToDelete []string
 	var err error
 
-	m.sections.Walk(func(s string, v interface{}) bool {
+	m.sections.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 		var shouldBuild bool
 
@@ -517,7 +517,7 @@ func (m *pageMap) assembleTaxonomies() error {
 	var taxonomiesToDelete []string
 	var err error
 
-	m.taxonomies.Walk(func(s string, v interface{}) bool {
+	m.taxonomies.Walk(func(s string, v any) bool {
 		n := v.(*contentNode)
 
 		if n.p != nil {
@@ -861,7 +861,7 @@ func (b *pagesMapBucket) getTaxonomyEntries() page.Pages {
 	ref := b.owner.treeRef
 	viewInfo := ref.n.viewInfo
 	prefix := strings.ToLower("/" + viewInfo.name.plural + "/" + viewInfo.termKey + "/")
-	ref.m.taxonomyEntries.WalkPrefix(prefix, func(s string, v interface{}) bool {
+	ref.m.taxonomyEntries.WalkPrefix(prefix, func(s string, v any) bool {
 		n := v.(*contentNode)
 		pas = append(pas, n.viewInfo.ref.p)
 		return false
@@ -967,7 +967,7 @@ func (w *sectionWalker) walkLevel(prefix string, createVisitor func() sectionWal
 
 	visitor := createVisitor()
 
-	w.m.taxonomies.WalkBelow(prefix, func(s string, v interface{}) bool {
+	w.m.taxonomies.WalkBelow(prefix, func(s string, v any) bool {
 		currentLevel := strings.Count(s, "/")
 
 		if currentLevel > level+1 {
@@ -986,7 +986,7 @@ func (w *sectionWalker) walkLevel(prefix string, createVisitor func() sectionWal
 				return true
 			}
 		} else {
-			w.m.taxonomyEntries.WalkPrefix(s, func(ss string, v interface{}) bool {
+			w.m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool {
 				n := v.(*contentNode)
 				w.err = visitor.handlePage(ss, n)
 				return w.err != nil
@@ -998,7 +998,7 @@ func (w *sectionWalker) walkLevel(prefix string, createVisitor func() sectionWal
 		return w.err != nil
 	})
 
-	w.m.sections.WalkBelow(prefix, func(s string, v interface{}) bool {
+	w.m.sections.WalkBelow(prefix, func(s string, v any) bool {
 		currentLevel := strings.Count(s, "/")
 		if currentLevel > level+1 {
 			return false
@@ -1010,7 +1010,7 @@ func (w *sectionWalker) walkLevel(prefix string, createVisitor func() sectionWal
 			return true
 		}
 
-		w.m.pages.WalkPrefix(s+cmBranchSeparator, func(s string, v interface{}) bool {
+		w.m.pages.WalkPrefix(s+cmBranchSeparator, func(s string, v any) bool {
 			w.err = visitor.handlePage(s, v.(*contentNode))
 			return w.err != nil
 		})
diff --git a/hugolib/datafiles_test.go b/hugolib/datafiles_test.go
@@ -33,10 +33,10 @@ func TestDataDir(t *testing.T) {
 	equivDataDirs[0].addSource("data/test/a.json", `{ "b" : { "c1": "red" , "c2": "blue" } }`)
 	equivDataDirs[1].addSource("data/test/a.yaml", "b:\n  c1: red\n  c2: blue")
 	equivDataDirs[2].addSource("data/test/a.toml", "[b]\nc1 = \"red\"\nc2 = \"blue\"\n")
-	expected := map[string]interface{}{
-		"test": map[string]interface{}{
-			"a": map[string]interface{}{
-				"b": map[string]interface{}{
+	expected := map[string]any{
+		"test": map[string]any{
+			"a": map[string]any{
+				"b": map[string]any{
 					"c1": "red",
 					"c2": "blue",
 				},
@@ -56,10 +56,10 @@ func TestDataDirNumeric(t *testing.T) {
 	equivDataDirs[0].addSource("data/test/a.json", `{ "b" : { "c1": 1.7 , "c2": 2.9 } }`)
 	equivDataDirs[1].addSource("data/test/a.yaml", "b:\n  c1: 1.7\n  c2: 2.9")
 	equivDataDirs[2].addSource("data/test/a.toml", "[b]\nc1 = 1.7\nc2 = 2.9\n")
-	expected := map[string]interface{}{
-		"test": map[string]interface{}{
-			"a": map[string]interface{}{
-				"b": map[string]interface{}{
+	expected := map[string]any{
+		"test": map[string]any{
+			"a": map[string]any{
+				"b": map[string]any{
 					"c1": 1.7,
 					"c2": 2.9,
 				},
@@ -75,10 +75,10 @@ func TestDataDirBoolean(t *testing.T) {
 	equivDataDirs[0].addSource("data/test/a.json", `{ "b" : { "c1": true , "c2": false } }`)
 	equivDataDirs[1].addSource("data/test/a.yaml", "b:\n  c1: true\n  c2: false")
 	equivDataDirs[2].addSource("data/test/a.toml", "[b]\nc1 = true\nc2 = false\n")
-	expected := map[string]interface{}{
-		"test": map[string]interface{}{
-			"a": map[string]interface{}{
-				"b": map[string]interface{}{
+	expected := map[string]any{
+		"test": map[string]any{
+			"a": map[string]any{
+				"b": map[string]any{
 					"c1": true,
 					"c2": false,
 				},
@@ -102,13 +102,13 @@ func TestDataDirTwoFiles(t *testing.T) {
 	equivDataDirs[2].addSource("data/test.toml", "hello = [\"world\", \"foo\"]")
 
 	expected :=
-		map[string]interface{}{
-			"test": map[string]interface{}{
-				"hello": []interface{}{
+		map[string]any{
+			"test": map[string]any{
+				"hello": []any{
 					"world",
 					"foo",
 				},
-				"foo": map[string]interface{}{
+				"foo": map[string]any{
 					"bar": "foofoo",
 				},
 			},
@@ -138,11 +138,11 @@ func TestDataDirOverriddenValue(t *testing.T) {
 	equivDataDirs[2].addSource("data/test.toml", "v1 = \"1\"")
 
 	expected :=
-		map[string]interface{}{
-			"a": map[string]interface{}{"a": "1"},
-			"test": map[string]interface{}{
-				"v1": map[string]interface{}{"v1-2": "2"},
-				"v2": map[string]interface{}{"v2": []interface{}{"2", "3"}},
+		map[string]any{
+			"a": map[string]any{"a": "1"},
+			"test": map[string]any{
+				"v1": map[string]any{"v1-2": "2"},
+				"v2": map[string]any{"v2": []any{"2", "3"}},
 			},
 		}
 
@@ -162,11 +162,11 @@ func TestDataDirArrayAtTopLevelOfFile(t *testing.T) {
 `)
 
 	expected :=
-		map[string]interface{}{
-			"test": []interface{}{
-				map[string]interface{}{"hello": "world"},
-				map[string]interface{}{"what": "time"},
-				map[string]interface{}{"is": "lunch?"},
+		map[string]any{
+			"test": []any{
+				map[string]any{"hello": "world"},
+				map[string]any{"what": "time"},
+				map[string]any{"is": "lunch?"},
 			},
 		}
 
@@ -183,12 +183,12 @@ func TestDataDirMultipleSources(t *testing.T) {
 	dd.addSource("data/test/second.yaml", "tender: 2")
 
 	expected :=
-		map[string]interface{}{
-			"test": map[string]interface{}{
-				"first": map[string]interface{}{
+		map[string]any{
+			"test": map[string]any{
+				"first": map[string]any{
 					"bar": 1,
 				},
-				"second": map[string]interface{}{
+				"second": map[string]any{
 					"tender": 2,
 				},
 			},
@@ -213,14 +213,14 @@ func TestDataDirMultipleSourcesCommingled(t *testing.T) {
 	// 1. A theme uses the same key; the main data folder wins
 	// 2. A sub folder uses the same key: the sub folder wins
 	expected :=
-		map[string]interface{}{
-			"a": map[string]interface{}{
-				"b1": map[string]interface{}{
+		map[string]any{
+			"a": map[string]any{
+				"b1": map[string]any{
 					"c1": "data/a/b1",
 					"c2": "mytheme/data/a/b1",
 				},
 				"b2": "data/a",
-				"b3": []interface{}{"x", "y", "z"},
+				"b3": []any{"x", "y", "z"},
 			},
 		}
 
@@ -239,10 +239,10 @@ func TestDataDirCollidingChildArrays(t *testing.T) {
 	// 1. A theme uses the same key; the main data folder wins
 	// 2. A sub folder uses the same key: the sub folder wins
 	expected :=
-		map[string]interface{}{
-			"a": map[string]interface{}{
+		map[string]any{
+			"a": map[string]any{
 				"b1": "data/a",
-				"b2": []interface{}{"1", "2", "3"},
+				"b2": []any{"1", "2", "3"},
 			},
 		}
 
@@ -257,9 +257,9 @@ func TestDataDirCollidingTopLevelArrays(t *testing.T) {
 	dd.addSource("data/a/b1.json", `["1", "2", "3"]`)
 
 	expected :=
-		map[string]interface{}{
-			"a": map[string]interface{}{
-				"b1": []interface{}{"1", "2", "3"},
+		map[string]any{
+			"a": map[string]any{
+				"b1": []any{"1", "2", "3"},
 			},
 		}
 
@@ -277,11 +277,11 @@ func TestDataDirCollidingMapsAndArrays(t *testing.T) {
 	dd.addSource("data/b.json", `["x", "y", "z"]`)
 
 	expected :=
-		map[string]interface{}{
-			"a": map[string]interface{}{
+		map[string]any{
+			"a": map[string]any{
 				"music": "Queen's Rebuke",
 			},
-			"b": []interface{}{"x", "y", "z"},
+			"b": []any{"x", "y", "z"},
 		}
 
 	doTestDataDir(t, dd, expected, "theme", "mytheme")
@@ -297,9 +297,9 @@ func TestDataDirNestedDirectories(t *testing.T) {
 	dd.addSource("data/test1/20/05/b.json", `{ "artist" : "Charlie Parker" }`)
 
 	expected :=
-		map[string]interface{}{
-			"a":     []interface{}{"1", "2", "3"},
-			"test1": map[string]interface{}{"20": map[string]interface{}{"05": map[string]interface{}{"b": map[string]interface{}{"artist": "Charlie Parker"}}, "06": map[string]interface{}{"a": map[string]interface{}{"artist": "Michael Brecker"}}}},
+		map[string]any{
+			"a":     []any{"1", "2", "3"},
+			"test1": map[string]any{"20": map[string]any{"05": map[string]any{"b": map[string]any{"artist": "Charlie Parker"}}, "06": map[string]any{"a": map[string]any{"artist": "Michael Brecker"}}}},
 		}
 
 	doTestDataDir(t, dd, expected, "theme", "mytheme")
@@ -313,7 +313,7 @@ func (d *dataDir) addSource(path, content string) {
 	d.sources = append(d.sources, [2]string{path, content})
 }
 
-func doTestEquivalentDataDirs(t *testing.T, equivDataDirs []dataDir, expected interface{}, configKeyValues ...interface{}) {
+func doTestEquivalentDataDirs(t *testing.T, equivDataDirs []dataDir, expected any, configKeyValues ...any) {
 	for i, dd := range equivDataDirs {
 		err := doTestDataDirImpl(t, dd, expected, configKeyValues...)
 		if err != "" {
@@ -322,14 +322,14 @@ func doTestEquivalentDataDirs(t *testing.T, equivDataDirs []dataDir, expected in
 	}
 }
 
-func doTestDataDir(t *testing.T, dd dataDir, expected interface{}, configKeyValues ...interface{}) {
+func doTestDataDir(t *testing.T, dd dataDir, expected any, configKeyValues ...any) {
 	err := doTestDataDirImpl(t, dd, expected, configKeyValues...)
 	if err != "" {
 		t.Error(err)
 	}
 }
 
-func doTestDataDirImpl(t *testing.T, dd dataDir, expected interface{}, configKeyValues ...interface{}) (err string) {
+func doTestDataDirImpl(t *testing.T, dd dataDir, expected any, configKeyValues ...any) (err string) {
 	cfg, fs := newTestCfg()
 
 	for i := 0; i < len(configKeyValues); i += 2 {
diff --git a/hugolib/embedded_shortcodes_test.go b/hugolib/embedded_shortcodes_test.go
@@ -294,12 +294,12 @@ func TestShortcodeTweet(t *testing.T) {
 	t.Parallel()
 
 	for i, this := range []struct {
-		privacy            map[string]interface{}
+		privacy            map[string]any
 		in, resp, expected string
 	}{
 		{
-			map[string]interface{}{
-				"twitter": map[string]interface{}{
+			map[string]any{
+				"twitter": map[string]any{
 					"simple": true,
 				},
 			},
@@ -308,8 +308,8 @@ func TestShortcodeTweet(t *testing.T) {
 			`.twitter-tweet a`,
 		},
 		{
-			map[string]interface{}{
-				"twitter": map[string]interface{}{
+			map[string]any{
+				"twitter": map[string]any{
 					"simple": false,
 				},
 			},
@@ -318,8 +318,8 @@ func TestShortcodeTweet(t *testing.T) {
 			`(?s)<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Hugo 0.15 will have 30%\+ faster render times thanks to this commit <a href="https://t.co/FfzhM8bNhT">https://t.co/FfzhM8bNhT</a>  <a href="https://twitter.com/hashtag/gohugo\?src=hash&amp;ref_src=twsrc%5Etfw">#gohugo</a> <a href="https://twitter.com/hashtag/golang\?src=hash&amp;ref_src=twsrc%5Etfw">#golang</a> <a href="https://t.co/ITbMNU2BUf">https://t.co/ITbMNU2BUf</a></p>&mdash; Steve Francia \(@spf13\) <a href="https://twitter.com/spf13/status/666616452582129664\?ref_src=twsrc%5Etfw">November 17, 2015</a></blockquote>\s*<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>`,
 		},
 		{
-			map[string]interface{}{
-				"twitter": map[string]interface{}{
+			map[string]any{
+				"twitter": map[string]any{
 					"simple": false,
 				},
 			},
@@ -330,8 +330,8 @@ func TestShortcodeTweet(t *testing.T) {
 	} {
 		// overload getJSON to return mock API response from Twitter
 		tweetFuncMap := template.FuncMap{
-			"getJSON": func(urlParts ...interface{}) interface{} {
-				var v interface{}
+			"getJSON": func(urlParts ...any) any {
+				var v any
 				err := json.Unmarshal([]byte(this.resp), &v)
 				if err != nil {
 					t.Fatalf("[%d] unexpected error in json.Unmarshal: %s", i, err)
@@ -382,13 +382,13 @@ func TestShortcodeInstagram(t *testing.T) {
 	} {
 		// overload getJSON to return mock API response from Instagram
 		instagramFuncMap := template.FuncMap{
-			"getJSON": func(args ...interface{}) interface{} {
-				headers := args[len(args)-1].(map[string]interface{})
+			"getJSON": func(args ...any) any {
+				headers := args[len(args)-1].(map[string]any)
 				auth := headers["Authorization"]
 				if auth != "Bearer dummytoken" {
 					return fmt.Errorf("invalid access token: %q", auth)
 				}
-				var v interface{}
+				var v any
 				err := json.Unmarshal([]byte(this.resp), &v)
 				if err != nil {
 					return fmt.Errorf("[%d] unexpected error in json.Unmarshal: %s", i, err)
diff --git a/hugolib/filesystems/basefs_test.go b/hugolib/filesystems/basefs_test.go
@@ -314,12 +314,12 @@ func TestStaticFsMultiHost(t *testing.T) {
 	v.Set("theme", "t1")
 	v.Set("defaultContentLanguage", "en")
 
-	langConfig := map[string]interface{}{
-		"no": map[string]interface{}{
+	langConfig := map[string]any{
+		"no": map[string]any{
 			"staticDir": "static_no",
 			"baseURL":   "https://example.org/no/",
 		},
-		"en": map[string]interface{}{
+		"en": map[string]any{
 			"baseURL": "https://example.org/en/",
 		},
 	}
@@ -362,17 +362,17 @@ func TestMakePathRelative(t *testing.T) {
 	c.Assert(fs.Source.MkdirAll(filepath.Join(workDir, "static", "d2"), 0777), qt.IsNil)
 	c.Assert(fs.Source.MkdirAll(filepath.Join(workDir, "dust", "d2"), 0777), qt.IsNil)
 
-	moduleCfg := map[string]interface{}{
-		"mounts": []interface{}{
-			map[string]interface{}{
+	moduleCfg := map[string]any{
+		"mounts": []any{
+			map[string]any{
 				"source": "dist",
 				"target": "static/mydist",
 			},
-			map[string]interface{}{
+			map[string]any{
 				"source": "dust",
 				"target": "static/foo/bar",
 			},
-			map[string]interface{}{
+			map[string]any{
 				"source": "static",
 				"target": "static",
 			},
diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
@@ -79,7 +79,7 @@ type HugoSites struct {
 	codeownerInfo *codeownerInfo
 
 	// As loaded from the /data dirs
-	data map[string]interface{}
+	data map[string]any
 
 	contentInit sync.Once
 	content     *pageMaps
@@ -189,7 +189,7 @@ func (h *hugoSitesInit) Reset() {
 	h.translations.Reset()
 }
 
-func (h *HugoSites) Data() map[string]interface{} {
+func (h *HugoSites) Data() map[string]any {
 	if _, err := h.init.data.Do(); err != nil {
 		h.SendError(errors.Wrap(err, "failed to load data"))
 		return nil
@@ -359,7 +359,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
 		donec: make(chan bool),
 	}
 
-	h.init.data.Add(func() (interface{}, error) {
+	h.init.data.Add(func() (any, error) {
 		err := h.loadData(h.PathSpec.BaseFs.Data.Dirs)
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to load data")
@@ -367,7 +367,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
 		return nil, nil
 	})
 
-	h.init.layouts.Add(func() (interface{}, error) {
+	h.init.layouts.Add(func() (any, error) {
 		for _, s := range h.Sites {
 			if err := s.Tmpl().(tpl.TemplateManager).MarkReady(); err != nil {
 				return nil, err
@@ -376,7 +376,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
 		return nil, nil
 	})
 
-	h.init.translations.Add(func() (interface{}, error) {
+	h.init.translations.Add(func() (any, error) {
 		if len(h.Sites) > 1 {
 			allTranslations := pagesToTranslationsMap(h.Sites)
 			assignTranslationsToPages(allTranslations, h.Sites)
@@ -385,7 +385,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
 		return nil, nil
 	})
 
-	h.init.gitInfo.Add(func() (interface{}, error) {
+	h.init.gitInfo.Add(func() (any, error) {
 		err := h.loadGitInfo()
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to load Git info")
@@ -857,7 +857,7 @@ func (h *HugoSites) Pages() page.Pages {
 func (h *HugoSites) loadData(fis []hugofs.FileMetaInfo) (err error) {
 	spec := source.NewSourceSpec(h.PathSpec, nil, nil)
 
-	h.data = make(map[string]interface{})
+	h.data = make(map[string]any)
 	for _, fi := range fis {
 		fileSystem := spec.NewFilesystemFromFileMetaInfo(fi)
 		files, err := fileSystem.Files()
@@ -875,7 +875,7 @@ func (h *HugoSites) loadData(fis []hugofs.FileMetaInfo) (err error) {
 }
 
 func (h *HugoSites) handleDataFile(r source.File) error {
-	var current map[string]interface{}
+	var current map[string]any
 
 	f, err := r.FileInfo().Meta().Open()
 	if err != nil {
@@ -890,9 +890,9 @@ func (h *HugoSites) handleDataFile(r source.File) error {
 	for _, key := range keyParts {
 		if key != "" {
 			if _, ok := current[key]; !ok {
-				current[key] = make(map[string]interface{})
+				current[key] = make(map[string]any)
 			}
-			current = current[key].(map[string]interface{})
+			current = current[key].(map[string]any)
 		}
 	}
 
@@ -910,16 +910,16 @@ func (h *HugoSites) handleDataFile(r source.File) error {
 
 	switch data.(type) {
 	case nil:
-	case map[string]interface{}:
+	case map[string]any:
 
 		switch higherPrecedentData.(type) {
 		case nil:
 			current[r.BaseFileName()] = data
-		case map[string]interface{}:
+		case map[string]any:
 			// merge maps: insert entries from data for keys that
 			// don't already exist in higherPrecedentData
-			higherPrecedentMap := higherPrecedentData.(map[string]interface{})
-			for key, value := range data.(map[string]interface{}) {
+			higherPrecedentMap := higherPrecedentData.(map[string]any)
+			for key, value := range data.(map[string]any) {
 				if _, exists := higherPrecedentMap[key]; exists {
 					// this warning could happen if
 					// 1. A theme uses the same key; the main data folder wins
@@ -936,7 +936,7 @@ func (h *HugoSites) handleDataFile(r source.File) error {
 				"higher precedence %T data already in the data tree", data, r.Path(), higherPrecedentData)
 		}
 
-	case []interface{}:
+	case []any:
 		if higherPrecedentData == nil {
 			current[r.BaseFileName()] = data
 		} else {
@@ -970,7 +970,7 @@ func (h *HugoSites) errWithFileContext(err error, f source.File) error {
 	return err
 }
 
-func (h *HugoSites) readData(f source.File) (interface{}, error) {
+func (h *HugoSites) readData(f source.File) (any, error) {
 	file, err := f.FileInfo().Meta().Open()
 	if err != nil {
 		return nil, errors.Wrap(err, "readData: failed to open data file")
diff --git a/hugolib/hugo_sites_build_test.go b/hugolib/hugo_sites_build_test.go
@@ -28,7 +28,7 @@ func TestMultiSitesMainLangInRoot(t *testing.T) {
 func doTestMultiSitesMainLangInRoot(t *testing.T, defaultInSubDir bool) {
 	c := qt.New(t)
 
-	siteConfig := map[string]interface{}{
+	siteConfig := map[string]any{
 		"DefaultContentLanguage":         "fr",
 		"DefaultContentLanguageInSubdir": defaultInSubDir,
 	}
@@ -1235,7 +1235,7 @@ func writeNewContentFile(t *testing.T, fs afero.Fs, title, date, filename string
 }
 
 type multiSiteTestBuilder struct {
-	configData   interface{}
+	configData   any
 	config       string
 	configFormat string
 
@@ -1251,14 +1251,14 @@ func (b *multiSiteTestBuilder) WithNewConfig(config string) *multiSiteTestBuilde
 	return b
 }
 
-func (b *multiSiteTestBuilder) WithNewConfigData(data interface{}) *multiSiteTestBuilder {
+func (b *multiSiteTestBuilder) WithNewConfigData(data any) *multiSiteTestBuilder {
 	b.WithConfigTemplate(data, b.configFormat, b.config)
 	return b
 }
 
-func newMultiSiteTestBuilder(t testing.TB, configFormat, config string, configData interface{}) *multiSiteTestBuilder {
+func newMultiSiteTestBuilder(t testing.TB, configFormat, config string, configData any) *multiSiteTestBuilder {
 	if configData == nil {
-		configData = map[string]interface{}{
+		configData = map[string]any{
 			"DefaultContentLanguage":         "fr",
 			"DefaultContentLanguageInSubdir": true,
 		}
diff --git a/hugolib/image_test.go b/hugolib/image_test.go
@@ -37,7 +37,7 @@ func TestImageOps(t *testing.T) {
 	c.Assert(err, qt.IsNil)
 	defer clean()
 
-	newBuilder := func(timeout interface{}) *sitesBuilder {
+	newBuilder := func(timeout any) *sitesBuilder {
 		v := config.New()
 		v.Set("workingDir", workDir)
 		v.Set("baseURL", "https://example.org")
diff --git a/hugolib/language_content_dir_test.go b/hugolib/language_content_dir_test.go
@@ -251,7 +251,7 @@ Content.
 	c.Assert(contentStr, qt.Contains, "SVP3-RELREF: /sv/sect/p-sv-3/")
 
 	// Test RelRef with and without language indicator.
-	nn3RefArgs := map[string]interface{}{
+	nn3RefArgs := map[string]any{
 		"path": "/sect/page3.md",
 		"lang": "nn",
 	}
diff --git a/hugolib/page.go b/hugolib/page.go
@@ -79,7 +79,7 @@ type pageContext interface {
 }
 
 // wrapErr adds some context to the given error if possible.
-func wrapErr(err error, ctx interface{}) error {
+func wrapErr(err error, ctx any) error {
 	if pc, ok := ctx.(pageContext); ok {
 		return pc.wrapError(err)
 	}
@@ -139,7 +139,7 @@ func (p *pageState) Err() error {
 
 // Eq returns whether the current page equals the given page.
 // This is what's invoked when doing `{{ if eq $page $otherPage }}`
-func (p *pageState) Eq(other interface{}) bool {
+func (p *pageState) Eq(other any) bool {
 	pp, err := unwrapPage(other)
 	if err != nil {
 		return false
@@ -600,7 +600,7 @@ func (p *pageState) mapContent(bucket *pagesMapBucket, meta *pageMeta) error {
 	s := p.shortcodeState
 
 	rn := &pageContentMap{
-		items: make([]interface{}, 0, 20),
+		items: make([]any, 0, 20),
 	}
 
 	iter := p.source.parsed.Iterator()
@@ -737,12 +737,12 @@ Loop:
 	return nil
 }
 
-func (p *pageState) errorf(err error, format string, a ...interface{}) error {
+func (p *pageState) errorf(err error, format string, a ...any) error {
 	if herrors.UnwrapErrorWithFileContext(err) != nil {
 		// More isn't always better.
 		return err
 	}
-	args := append([]interface{}{p.Language().Lang, p.pathOrTitle()}, a...)
+	args := append([]any{p.Language().Lang, p.pathOrTitle()}, a...)
 	format = "[%s] page %q: " + format
 	if err == nil {
 		errors.Errorf(format, args...)
diff --git a/hugolib/page__content.go b/hugolib/page__content.go
@@ -111,7 +111,7 @@ type pageContentMap struct {
 	hasNonMarkdownShortcode bool
 
 	//  *shortcode, pageContentReplacement or pageparser.Item
-	items []interface{}
+	items []any
 }
 
 func (p *pageContentMap) AddBytes(item pageparser.Item) {
diff --git a/hugolib/page__data.go b/hugolib/page__data.go
@@ -26,7 +26,7 @@ type pageData struct {
 	data     page.Data
 }
 
-func (p *pageData) Data() interface{} {
+func (p *pageData) Data() any {
 	p.dataInit.Do(func() {
 		p.data = make(page.Data)
 
diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go
@@ -70,7 +70,7 @@ type pageMeta struct {
 	bundleType files.ContentClass
 
 	// Params contains configuration defined in the params section of page frontmatter.
-	params map[string]interface{}
+	params map[string]any
 
 	title     string
 	linkTitle string
@@ -110,7 +110,7 @@ type pageMeta struct {
 
 	// This is the raw front matter metadata that is going to be assigned to
 	// the Resources above.
-	resourcesMetadata []map[string]interface{}
+	resourcesMetadata []map[string]any
 
 	f source.File
 
@@ -121,7 +121,7 @@ type pageMeta struct {
 
 	s *Site
 
-	renderingConfigOverrides map[string]interface{}
+	renderingConfigOverrides map[string]any
 	contentConverterInit     sync.Once
 	contentConverter         converter.Converter
 }
@@ -223,7 +223,7 @@ func (p *pageMeta) IsPage() bool {
 //
 // This method is also implemented on SiteInfo.
 // TODO(bep) interface
-func (p *pageMeta) Param(key interface{}) (interface{}, error) {
+func (p *pageMeta) Param(key any) (any, error) {
 	return resource.Param(p, p.s.Info.Params(), key)
 }
 
@@ -347,7 +347,7 @@ func (pm *pageMeta) mergeBucketCascades(b1, b2 *pagesMapBucket) {
 	}
 }
 
-func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, frontmatter map[string]interface{}) error {
+func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, frontmatter map[string]any) error {
 	pm.params = make(maps.Params)
 
 	if frontmatter == nil && (parentBucket == nil || parentBucket.cascade == nil) {
@@ -368,7 +368,7 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
 			}
 		}
 	} else {
-		frontmatter = make(map[string]interface{})
+		frontmatter = make(map[string]any)
 	}
 
 	var cascade map[page.PageMatcher]maps.Params
@@ -546,22 +546,22 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
 			pm.translationKey = cast.ToString(v)
 			pm.params[loki] = pm.translationKey
 		case "resources":
-			var resources []map[string]interface{}
+			var resources []map[string]any
 			handled := true
 
 			switch vv := v.(type) {
-			case []map[interface{}]interface{}:
+			case []map[any]any:
 				for _, vvv := range vv {
 					resources = append(resources, maps.ToStringMap(vvv))
 				}
-			case []map[string]interface{}:
+			case []map[string]any:
 				resources = append(resources, vv...)
-			case []interface{}:
+			case []any:
 				for _, vvv := range vv {
 					switch vvvv := vvv.(type) {
-					case map[interface{}]interface{}:
+					case map[any]any:
 						resources = append(resources, maps.ToStringMap(vvvv))
-					case map[string]interface{}:
+					case map[string]any:
 						resources = append(resources, vvvv)
 					}
 				}
@@ -591,14 +591,14 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
 				pm.params[loki] = vv
 			default: // handle array of strings as well
 				switch vvv := vv.(type) {
-				case []interface{}:
+				case []any:
 					if len(vvv) > 0 {
 						switch vvv[0].(type) {
-						case map[interface{}]interface{}: // Proper parsing structured array from YAML based FrontMatter
+						case map[any]any:
 							pm.params[loki] = vvv
-						case map[string]interface{}: // Proper parsing structured array from JSON based FrontMatter
+						case map[string]any:
 							pm.params[loki] = vvv
-						case []interface{}:
+						case []any:
 							pm.params[loki] = vvv
 						default:
 							a := make([]string, len(vvv))
@@ -744,7 +744,7 @@ func (p *pageMeta) applyDefaultValues(n *contentNode) error {
 	}
 
 	if !p.f.IsZero() {
-		var renderingConfigOverrides map[string]interface{}
+		var renderingConfigOverrides map[string]any
 		bfParam := getParamToLower(p, "blackfriday")
 		if bfParam != nil {
 			renderingConfigOverrides = maps.ToStringMap(bfParam)
@@ -757,7 +757,7 @@ func (p *pageMeta) applyDefaultValues(n *contentNode) error {
 	return nil
 }
 
-func (p *pageMeta) newContentConverter(ps *pageState, markup string, renderingConfigOverrides map[string]interface{}) (converter.Converter, error) {
+func (p *pageMeta) newContentConverter(ps *pageState, markup string, renderingConfigOverrides map[string]any) (converter.Converter, error) {
 	if ps == nil {
 		panic("no Page provided")
 	}
@@ -806,7 +806,7 @@ func (p *pageMeta) Slug() string {
 	return p.urlPaths.Slug
 }
 
-func getParam(m resource.ResourceParamsProvider, key string, stringToLower bool) interface{} {
+func getParam(m resource.ResourceParamsProvider, key string, stringToLower bool) any {
 	v := m.Params()[strings.ToLower(key)]
 
 	if v == nil {
@@ -837,6 +837,6 @@ func getParam(m resource.ResourceParamsProvider, key string, stringToLower bool)
 	}
 }
 
-func getParamToLower(m resource.ResourceParamsProvider, key string) interface{} {
+func getParamToLower(m resource.ResourceParamsProvider, key string) any {
 	return getParam(m, key, true)
 }
diff --git a/hugolib/page__new.go b/hugolib/page__new.go
@@ -92,7 +92,7 @@ func newPageBucket(p *pageState) *pagesMapBucket {
 func newPageFromMeta(
 	n *contentNode,
 	parentBucket *pagesMapBucket,
-	meta map[string]interface{},
+	meta map[string]any,
 	metaProvider *pageMeta) (*pageState, error) {
 	if metaProvider.f == nil {
 		metaProvider.f = page.NewZeroFile(metaProvider.s.LogDistinct)
@@ -119,7 +119,7 @@ func newPageFromMeta(
 		return nil, err
 	}
 
-	ps.init.Add(func() (interface{}, error) {
+	ps.init.Add(func() (any, error) {
 		pp, err := newPagePaths(metaProvider.s, ps, metaProvider)
 		if err != nil {
 			return nil, err
@@ -189,7 +189,7 @@ type pageDeprecatedWarning struct {
 func (p *pageDeprecatedWarning) IsDraft() bool          { return p.p.m.draft }
 func (p *pageDeprecatedWarning) Hugo() hugo.Info        { return p.p.s.Info.Hugo() }
 func (p *pageDeprecatedWarning) LanguagePrefix() string { return p.p.s.Info.LanguagePrefix }
-func (p *pageDeprecatedWarning) GetParam(key string) interface{} {
+func (p *pageDeprecatedWarning) GetParam(key string) any {
 	return p.p.m.params[strings.ToLower(key)]
 }
 
diff --git a/hugolib/page__paginator.go b/hugolib/page__paginator.go
@@ -41,7 +41,7 @@ func (p *pagePaginator) reset() {
 	p.pagePaginatorInit = &pagePaginatorInit{}
 }
 
-func (p *pagePaginator) Paginate(seq interface{}, options ...interface{}) (*page.Pager, error) {
+func (p *pagePaginator) Paginate(seq any, options ...any) (*page.Pager, error) {
 	var initErr error
 	p.init.Do(func() {
 		pagerSize, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
@@ -68,7 +68,7 @@ func (p *pagePaginator) Paginate(seq interface{}, options ...interface{}) (*page
 	return p.current, nil
 }
 
-func (p *pagePaginator) Paginator(options ...interface{}) (*page.Pager, error) {
+func (p *pagePaginator) Paginator(options ...any) (*page.Pager, error) {
 	var initErr error
 	p.init.Do(func() {
 		pagerSize, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
diff --git a/hugolib/page__per_output.go b/hugolib/page__per_output.go
@@ -195,11 +195,11 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err
 	}
 
 	// There may be recursive loops in shortcodes and render hooks.
-	cp.initMain = parent.BranchWithTimeout(p.s.siteCfg.timeout, func(ctx context.Context) (interface{}, error) {
+	cp.initMain = parent.BranchWithTimeout(p.s.siteCfg.timeout, func(ctx context.Context) (any, error) {
 		return nil, initContent()
 	})
 
-	cp.initPlain = cp.initMain.Branch(func() (interface{}, error) {
+	cp.initPlain = cp.initMain.Branch(func() (any, error) {
 		cp.plain = helpers.StripHTML(string(cp.content))
 		cp.plainWords = strings.Fields(cp.plain)
 		cp.setWordCounts(p.m.isCJKLanguage)
@@ -272,7 +272,7 @@ func (p *pageContentOutput) Reset() {
 	p.renderHooks = &renderHooks{}
 }
 
-func (p *pageContentOutput) Content() (interface{}, error) {
+func (p *pageContentOutput) Content() (any, error) {
 	if p.p.s.initInit(p.initMain, p.p) {
 		return p.content, nil
 	}
@@ -330,7 +330,7 @@ func (p *pageContentOutput) WordCount() int {
 	return p.wordCount
 }
 
-func (p *pageContentOutput) RenderString(args ...interface{}) (template.HTML, error) {
+func (p *pageContentOutput) RenderString(args ...any) (template.HTML, error) {
 	if len(args) < 1 || len(args) > 2 {
 		return "", errors.New("want 1 or 2 arguments")
 	}
@@ -342,7 +342,7 @@ func (p *pageContentOutput) RenderString(args ...interface{}) (template.HTML, er
 	if len(args) == 1 {
 		sidx = 0
 	} else {
-		m, ok := args[0].(map[string]interface{})
+		m, ok := args[0].(map[string]any)
 		if !ok {
 			return "", errors.New("first argument must be a map")
 		}
@@ -433,14 +433,14 @@ func (p *pageContentOutput) initRenderHooks() error {
 
 		type cacheKey struct {
 			tp hooks.RendererType
-			id interface{}
+			id any
 			f  output.Format
 		}
 
-		renderCache := make(map[cacheKey]interface{})
+		renderCache := make(map[cacheKey]any)
 		var renderCacheMu sync.Mutex
 
-		resolvePosition := func(ctx interface{}) text.Position {
+		resolvePosition := func(ctx any) text.Position {
 			var offset int
 
 			switch v := ctx.(type) {
@@ -459,7 +459,7 @@ func (p *pageContentOutput) initRenderHooks() error {
 			return pos
 		}
 
-		p.renderHooks.getRenderer = func(tp hooks.RendererType, id interface{}) interface{} {
+		p.renderHooks.getRenderer = func(tp hooks.RendererType, id any) any {
 			renderCacheMu.Lock()
 			defer renderCacheMu.Unlock()
 
@@ -650,7 +650,7 @@ func (t targetPathsHolder) targetPaths() page.TargetPaths {
 	return t.paths
 }
 
-func executeToString(h tpl.TemplateHandler, templ tpl.Template, data interface{}) (string, error) {
+func executeToString(h tpl.TemplateHandler, templ tpl.Template, data any) (string, error) {
 	b := bp.GetBuffer()
 	defer bp.PutBuffer(b)
 	if err := h.Execute(templ, b, data); err != nil {
diff --git a/hugolib/page__ref.go b/hugolib/page__ref.go
@@ -30,23 +30,23 @@ type pageRef struct {
 	p *pageState
 }
 
-func (p pageRef) Ref(argsm map[string]interface{}) (string, error) {
+func (p pageRef) Ref(argsm map[string]any) (string, error) {
 	return p.ref(argsm, p.p)
 }
 
-func (p pageRef) RefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p pageRef) RefFrom(argsm map[string]any, source any) (string, error) {
 	return p.ref(argsm, source)
 }
 
-func (p pageRef) RelRef(argsm map[string]interface{}) (string, error) {
+func (p pageRef) RelRef(argsm map[string]any) (string, error) {
 	return p.relRef(argsm, p.p)
 }
 
-func (p pageRef) RelRefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p pageRef) RelRefFrom(argsm map[string]any, source any) (string, error) {
 	return p.relRef(argsm, source)
 }
 
-func (p pageRef) decodeRefArgs(args map[string]interface{}) (refArgs, *Site, error) {
+func (p pageRef) decodeRefArgs(args map[string]any) (refArgs, *Site, error) {
 	var ra refArgs
 	err := mapstructure.WeakDecode(args, &ra)
 	if err != nil {
@@ -74,7 +74,7 @@ func (p pageRef) decodeRefArgs(args map[string]interface{}) (refArgs, *Site, err
 	return ra, s, nil
 }
 
-func (p pageRef) ref(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p pageRef) ref(argsm map[string]any, source any) (string, error) {
 	args, s, err := p.decodeRefArgs(argsm)
 	if err != nil {
 		return "", errors.Wrap(err, "invalid arguments to Ref")
@@ -91,7 +91,7 @@ func (p pageRef) ref(argsm map[string]interface{}, source interface{}) (string, 
 	return s.refLink(args.Path, source, false, args.OutputFormat)
 }
 
-func (p pageRef) relRef(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p pageRef) relRef(argsm map[string]any, source any) (string, error) {
 	args, s, err := p.decodeRefArgs(argsm)
 	if err != nil {
 		return "", errors.Wrap(err, "invalid arguments to Ref")
diff --git a/hugolib/page__tree.go b/hugolib/page__tree.go
@@ -25,7 +25,7 @@ type pageTree struct {
 	p *pageState
 }
 
-func (pt pageTree) IsAncestor(other interface{}) (bool, error) {
+func (pt pageTree) IsAncestor(other any) (bool, error) {
 	if pt.p == nil {
 		return false, nil
 	}
@@ -71,7 +71,7 @@ func (pt pageTree) CurrentSection() page.Page {
 	return p.Parent()
 }
 
-func (pt pageTree) IsDescendant(other interface{}) (bool, error) {
+func (pt pageTree) IsDescendant(other any) (bool, error) {
 	if pt.p == nil {
 		return false, nil
 	}
@@ -125,7 +125,7 @@ func (pt pageTree) FirstSection() page.Page {
 	return b.p
 }
 
-func (pt pageTree) InSection(other interface{}) (bool, error) {
+func (pt pageTree) InSection(other any) (bool, error) {
 	if pt.p == nil || types.IsNil(other) {
 		return false, nil
 	}
diff --git a/hugolib/page_test.go b/hugolib/page_test.go
@@ -298,7 +298,7 @@ func checkPageTitle(t *testing.T, page page.Page, title string) {
 	}
 }
 
-func checkPageContent(t *testing.T, page page.Page, expected string, msg ...interface{}) {
+func checkPageContent(t *testing.T, page page.Page, expected string, msg ...any) {
 	t.Helper()
 	a := normalizeContent(expected)
 	b := normalizeContent(content(page))
@@ -325,7 +325,7 @@ func checkPageTOC(t *testing.T, page page.Page, toc string) {
 	}
 }
 
-func checkPageSummary(t *testing.T, page page.Page, summary string, msg ...interface{}) {
+func checkPageSummary(t *testing.T, page page.Page, summary string, msg ...any) {
 	a := normalizeContent(string(page.Summary()))
 	b := normalizeContent(summary)
 	if a != b {
@@ -369,7 +369,7 @@ func normalizeExpected(ext, str string) string {
 }
 
 func testAllMarkdownEnginesForPages(t *testing.T,
-	assertFunc func(t *testing.T, ext string, pages page.Pages), settings map[string]interface{}, pageSources ...string) {
+	assertFunc func(t *testing.T, ext string, pages page.Pages), settings map[string]any, pageSources ...string) {
 
 	engines := []struct {
 		ext           string
@@ -399,8 +399,8 @@ func testAllMarkdownEnginesForPages(t *testing.T,
 				contentDir = s
 			}
 
-			cfg.Set("security", map[string]interface{}{
-				"exec": map[string]interface{}{
+			cfg.Set("security", map[string]any{
+				"exec": map[string]any{
 					"allow": []string{"^python$", "^rst2html.*", "^asciidoctor$"},
 				},
 			})
@@ -572,7 +572,7 @@ func TestCreateNewPage(t *testing.T) {
 		checkPageType(t, p, "page")
 	}
 
-	settings := map[string]interface{}{
+	settings := map[string]any{
 		"contentDir": "mycontent",
 	}
 
@@ -697,7 +697,7 @@ func TestPageWithShortCodeInSummary(t *testing.T) {
 func TestPageWithAdditionalExtension(t *testing.T) {
 	t.Parallel()
 	cfg, fs := newTestCfg()
-	cfg.Set("markup", map[string]interface{}{
+	cfg.Set("markup", map[string]any{
 		"defaultMarkdownHandler": "blackfriday", // TODO(bep)
 	})
 
@@ -1039,18 +1039,18 @@ func TestPageWithLastmodFromGitInfo(t *testing.T) {
 	wd, err := os.Getwd()
 	c.Assert(err, qt.IsNil)
 
-	cfg.Set("frontmatter", map[string]interface{}{
+	cfg.Set("frontmatter", map[string]any{
 		"lastmod": []string{":git", "lastmod"},
 	})
 	cfg.Set("defaultContentLanguage", "en")
 
-	langConfig := map[string]interface{}{
-		"en": map[string]interface{}{
+	langConfig := map[string]any{
+		"en": map[string]any{
 			"weight":       1,
 			"languageName": "English",
 			"contentDir":   "content",
 		},
-		"nn": map[string]interface{}{
+		"nn": map[string]any{
 			"weight":       2,
 			"languageName": "Nynorsk",
 			"contentDir":   "content_nn",
@@ -1102,7 +1102,7 @@ lastMod: 2018-02-28
 Content
 `
 
-			cfg.Set("frontmatter", map[string]interface{}{
+			cfg.Set("frontmatter", map[string]any{
 				"date": []string{dateHandler, "date"},
 			})
 
@@ -1163,7 +1163,7 @@ func TestWordCountWithAllCJKRunesWithoutHasCJKLanguage(t *testing.T) {
 
 func TestWordCountWithAllCJKRunesHasCJKLanguage(t *testing.T) {
 	t.Parallel()
-	settings := map[string]interface{}{"hasCJKLanguage": true}
+	settings := map[string]any{"hasCJKLanguage": true}
 
 	assertFunc := func(t *testing.T, ext string, pages page.Pages) {
 		p := pages[0]
@@ -1176,7 +1176,7 @@ func TestWordCountWithAllCJKRunesHasCJKLanguage(t *testing.T) {
 
 func TestWordCountWithMainEnglishWithCJKRunes(t *testing.T) {
 	t.Parallel()
-	settings := map[string]interface{}{"hasCJKLanguage": true}
+	settings := map[string]any{"hasCJKLanguage": true}
 
 	assertFunc := func(t *testing.T, ext string, pages page.Pages) {
 		p := pages[0]
@@ -1195,7 +1195,7 @@ func TestWordCountWithMainEnglishWithCJKRunes(t *testing.T) {
 
 func TestWordCountWithIsCJKLanguageFalse(t *testing.T) {
 	t.Parallel()
-	settings := map[string]interface{}{
+	settings := map[string]any{
 		"hasCJKLanguage": true,
 	}
 
diff --git a/hugolib/page_unwrap.go b/hugolib/page_unwrap.go
@@ -25,7 +25,7 @@ type pageWrapper interface {
 }
 
 // unwrapPage is used in equality checks and similar.
-func unwrapPage(in interface{}) (page.Page, error) {
+func unwrapPage(in any) (page.Page, error) {
 	switch v := in.(type) {
 	case *pageState:
 		return v, nil
@@ -40,7 +40,7 @@ func unwrapPage(in interface{}) (page.Page, error) {
 	}
 }
 
-func mustUnwrapPage(in interface{}) page.Page {
+func mustUnwrapPage(in any) page.Page {
 	p, err := unwrapPage(in)
 	if err != nil {
 		panic(err)
diff --git a/hugolib/page_unwrap_test.go b/hugolib/page_unwrap_test.go
@@ -29,7 +29,7 @@ func TestUnwrapPage(t *testing.T) {
 	c.Assert(mustUnwrap(newPageForRenderHook(p)), qt.Equals, p)
 }
 
-func mustUnwrap(v interface{}) page.Page {
+func mustUnwrap(v any) page.Page {
 	p, err := unwrapPage(v)
 	if err != nil {
 		panic(err)
diff --git a/hugolib/pagebundler_test.go b/hugolib/pagebundler_test.go
@@ -73,8 +73,8 @@ func TestPageBundlerSiteRegular(t *testing.T) {
 							"/": ":filename/",
 						})
 
-						cfg.Set("outputFormats", map[string]interface{}{
-							"CUSTOMO": map[string]interface{}{
+						cfg.Set("outputFormats", map[string]any{
+							"CUSTOMO": map[string]any{
 								"mediaType":     "text/html",
 								"baseName":      "cindex",
 								"path":          "cpath",
@@ -82,7 +82,7 @@ func TestPageBundlerSiteRegular(t *testing.T) {
 							},
 						})
 
-						cfg.Set("outputs", map[string]interface{}{
+						cfg.Set("outputs", map[string]any{
 							"home":    []string{"HTML", "CUSTOMO"},
 							"page":    []string{"HTML", "CUSTOMO"},
 							"section": []string{"HTML", "CUSTOMO"},
@@ -705,8 +705,8 @@ func newTestBundleSources(t testing.TB) (*hugofs.Fs, config.Provider) {
 	cfg.Set("workingDir", workDir)
 	cfg.Set("contentDir", "base")
 	cfg.Set("baseURL", "https://example.com")
-	cfg.Set("mediaTypes", map[string]interface{}{
-		"bepsays/bep": map[string]interface{}{
+	cfg.Set("mediaTypes", map[string]any{
+		"bepsays/bep": map[string]any{
 			"suffixes": []string{"bep"},
 		},
 	})
@@ -873,12 +873,12 @@ func newTestBundleSourcesMultilingual(t *testing.T) (*hugofs.Fs, config.Provider
 	cfg.Set("baseURL", "https://example.com")
 	cfg.Set("defaultContentLanguage", "en")
 
-	langConfig := map[string]interface{}{
-		"en": map[string]interface{}{
+	langConfig := map[string]any{
+		"en": map[string]any{
 			"weight":       1,
 			"languageName": "English",
 		},
-		"nn": map[string]interface{}{
+		"nn": map[string]any{
 			"weight":       2,
 			"languageName": "Nynorsk",
 		},
diff --git a/hugolib/pages_capture_test.go b/hugolib/pages_capture_test.go
@@ -63,11 +63,11 @@ func TestPagesCapture(t *testing.T) {
 }
 
 type testPagesCollectorProcessor struct {
-	items   []interface{}
+	items   []any
 	waitErr error
 }
 
-func (proc *testPagesCollectorProcessor) Process(item interface{}) error {
+func (proc *testPagesCollectorProcessor) Process(item any) error {
 	proc.items = append(proc.items, item)
 	return nil
 }
diff --git a/hugolib/pages_language_merge_test.go b/hugolib/pages_language_merge_test.go
@@ -76,7 +76,7 @@ func TestMergeLanguages(t *testing.T) {
 	c.Assert(len(enBundle.Resources()), qt.Equals, 6)
 	c.Assert(len(nnBundle.Resources()), qt.Equals, 2)
 
-	var ri interface{} = nnBundle.Resources()
+	var ri any = nnBundle.Resources()
 
 	// This looks less ugly in the templates ...
 	mergedNNResources := ri.(resource.ResourcesLanguageMerger).MergeByLanguage(enBundle.Resources())
diff --git a/hugolib/pages_process.go b/hugolib/pages_process.go
@@ -35,7 +35,7 @@ func newPagesProcessor(h *HugoSites, sp *source.SourceSpec) *pagesProcessor {
 		procs[s.Lang()] = &sitePagesProcessor{
 			m:           s.pageMap,
 			errorSender: s.h,
-			itemChan:    make(chan interface{}, config.GetNumWorkerMultiplier()*2),
+			itemChan:    make(chan any, config.GetNumWorkerMultiplier()*2),
 		}
 	}
 	return &pagesProcessor{
@@ -44,7 +44,7 @@ func newPagesProcessor(h *HugoSites, sp *source.SourceSpec) *pagesProcessor {
 }
 
 type pagesCollectorProcessorProvider interface {
-	Process(item interface{}) error
+	Process(item any) error
 	Start(ctx context.Context) context.Context
 	Wait() error
 }
@@ -54,7 +54,7 @@ type pagesProcessor struct {
 	procs map[string]pagesCollectorProcessorProvider
 }
 
-func (proc *pagesProcessor) Process(item interface{}) error {
+func (proc *pagesProcessor) Process(item any) error {
 	switch v := item.(type) {
 	// Page bundles mapped to their language.
 	case pageBundles:
@@ -97,7 +97,7 @@ func (proc *pagesProcessor) getProcFromFi(fi hugofs.FileMetaInfo) pagesCollector
 
 type nopPageProcessor int
 
-func (nopPageProcessor) Process(item interface{}) error {
+func (nopPageProcessor) Process(item any) error {
 	return nil
 }
 
@@ -116,11 +116,11 @@ type sitePagesProcessor struct {
 	errorSender herrors.ErrorSender
 
 	ctx       context.Context
-	itemChan  chan interface{}
+	itemChan  chan any
 	itemGroup *errgroup.Group
 }
 
-func (p *sitePagesProcessor) Process(item interface{}) error {
+func (p *sitePagesProcessor) Process(item any) error {
 	select {
 	case <-p.ctx.Done():
 		return nil
@@ -165,7 +165,7 @@ func (p *sitePagesProcessor) copyFile(fim hugofs.FileMetaInfo) error {
 	return s.publish(&s.PathSpec.ProcessingStats.Files, target, f)
 }
 
-func (p *sitePagesProcessor) doProcess(item interface{}) error {
+func (p *sitePagesProcessor) doProcess(item any) error {
 	m := p.m
 	switch v := item.(type) {
 	case *fileinfoBundle:
diff --git a/hugolib/paths/paths_test.go b/hugolib/paths/paths_test.go
@@ -28,9 +28,9 @@ func TestNewPaths(t *testing.T) {
 	v := config.New()
 	fs := hugofs.NewMem(v)
 
-	v.Set("languages", map[string]interface{}{
-		"no": map[string]interface{}{},
-		"en": map[string]interface{}{},
+	v.Set("languages", map[string]any{
+		"no": map[string]any{},
+		"en": map[string]any{},
 	})
 	v.Set("defaultContentLanguageInSubdir", true)
 	v.Set("defaultContentLanguage", "no")
diff --git a/hugolib/resource_chain_test.go b/hugolib/resource_chain_test.go
@@ -107,7 +107,7 @@ PRINT PROTOCOL ERROR1: error calling resources.GetRemote: Get "gopher://example.
 PRINT PROTOCOL ERROR2: error calling resources.GetRemote: Get "gopher://example.org": unsupported protocol scheme "gopher"
 
 
-`, helpers.HashString(ts.URL+"/sunset.jpg", map[string]interface{}{})))
+`, helpers.HashString(ts.URL+"/sunset.jpg", map[string]any{})))
 
 		b.AssertFileContent("public/styles.min.a1df58687c3c9cc38bf26532f7b4b2f2c2b0315dcde212376959995c04f11fef.css", "body{background-color:#add8e6}")
 		b.AssertFileContent("public//styles2.min.1cfc52986836405d37f9998a63fd6dd8608e8c410e5e3db1daaa30f78bc273ba.css", "body{background-color:orange}")
diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go
@@ -50,7 +50,7 @@ var (
 
 // ShortcodeWithPage is the "." context in a shortcode template.
 type ShortcodeWithPage struct {
-	Params        interface{}
+	Params        any
 	Inner         template.HTML
 	Page          page.Page
 	Parent        *ShortcodeWithPage
@@ -87,13 +87,13 @@ func (scp *ShortcodeWithPage) Site() page.Site {
 
 // Ref is a shortcut to the Ref method on Page. It passes itself as a context
 // to get better error messages.
-func (scp *ShortcodeWithPage) Ref(args map[string]interface{}) (string, error) {
+func (scp *ShortcodeWithPage) Ref(args map[string]any) (string, error) {
 	return scp.Page.RefFrom(args, scp)
 }
 
 // RelRef is a shortcut to the RelRef method on Page. It passes itself as a context
 // to get better error messages.
-func (scp *ShortcodeWithPage) RelRef(args map[string]interface{}) (string, error) {
+func (scp *ShortcodeWithPage) RelRef(args map[string]any) (string, error) {
 	return scp.Page.RelRefFrom(args, scp)
 }
 
@@ -107,7 +107,7 @@ func (scp *ShortcodeWithPage) Scratch() *maps.Scratch {
 }
 
 // Get is a convenience method to look up shortcode parameters by its key.
-func (scp *ShortcodeWithPage) Get(key interface{}) interface{} {
+func (scp *ShortcodeWithPage) Get(key any) any {
 	if scp.Params == nil {
 		return nil
 	}
@@ -162,10 +162,10 @@ func createShortcodePlaceholder(id string, ordinal int) string {
 
 type shortcode struct {
 	name      string
-	isInline  bool          // inline shortcode. Any inner will be a Go template.
-	isClosing bool          // whether a closing tag was provided
-	inner     []interface{} // string or nested shortcode
-	params    interface{}   // map or array
+	isInline  bool  // inline shortcode. Any inner will be a Go template.
+	isClosing bool  // whether a closing tag was provided
+	inner     []any // string or nested shortcode
+	params    any   // map or array
 	ordinal   int
 	err       error
 
@@ -214,16 +214,16 @@ func (s shortcode) innerString() string {
 
 func (sc shortcode) String() string {
 	// for testing (mostly), so any change here will break tests!
-	var params interface{}
+	var params any
 	switch v := sc.params.(type) {
-	case map[string]interface{}:
+	case map[string]any:
 		// sort the keys so test assertions won't fail
 		var keys []string
 		for k := range v {
 			keys = append(keys, k)
 		}
 		sort.Strings(keys)
-		tmp := make(map[string]interface{})
+		tmp := make(map[string]any)
 
 		for _, k := range keys {
 			tmp[k] = v[k]
@@ -552,11 +552,11 @@ Loop:
 			} else if pt.Peek().IsShortcodeParamVal() {
 				// named params
 				if sc.params == nil {
-					params := make(map[string]interface{})
+					params := make(map[string]any)
 					params[currItem.ValStr()] = pt.Next().ValTyped()
 					sc.params = params
 				} else {
-					if params, ok := sc.params.(map[string]interface{}); ok {
+					if params, ok := sc.params.(map[string]any); ok {
 						params[currItem.ValStr()] = pt.Next().ValTyped()
 					} else {
 						return sc, errShortCodeIllegalState
@@ -565,11 +565,11 @@ Loop:
 			} else {
 				// positional params
 				if sc.params == nil {
-					var params []interface{}
+					var params []any
 					params = append(params, currItem.ValTyped())
 					sc.params = params
 				} else {
-					if params, ok := sc.params.([]interface{}); ok {
+					if params, ok := sc.params.([]any); ok {
 						params = append(params, currItem.ValTyped())
 						sc.params = params
 					} else {
diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go
@@ -43,7 +43,7 @@ func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTempl
 	t.Helper()
 	cfg, fs := newTestCfg()
 
-	cfg.Set("markup", map[string]interface{}{
+	cfg.Set("markup", map[string]any{
 		"defaultMarkdownHandler": "blackfriday", // TODO(bep)
 	})
 
@@ -458,7 +458,7 @@ func TestShortcodesInSite(t *testing.T) {
 		contentPath string
 		content     string
 		outFile     string
-		expected    interface{}
+		expected    any
 	}{
 		{
 			"sect/doc1.md", `a{{< b >}}c`,
@@ -612,15 +612,15 @@ title: "Foo"
 	cfg.Set("uglyURLs", false)
 	cfg.Set("verbose", true)
 
-	cfg.Set("security", map[string]interface{}{
-		"exec": map[string]interface{}{
+	cfg.Set("security", map[string]any{
+		"exec": map[string]any{
 			"allow": []string{"^python$", "^rst2html.*", "^asciidoctor$"},
 		},
 	})
 
 	cfg.Set("markup.highlight.noClasses", false)
 	cfg.Set("markup.highlight.codeFences", true)
-	cfg.Set("markup", map[string]interface{}{
+	cfg.Set("markup", map[string]any{
 		"defaultMarkdownHandler": "blackfriday", // TODO(bep)
 	})
 
@@ -821,7 +821,7 @@ func TestReplaceShortcodeTokens(t *testing.T) {
 		input        string
 		prefix       string
 		replacements map[string]string
-		expect       interface{}
+		expect       any
 	}{
 		{"Hello HAHAHUGOSHORTCODE-1HBHB.", "PREFIX", map[string]string{"HAHAHUGOSHORTCODE-1HBHB": "World"}, "Hello World."},
 		{"Hello HAHAHUGOSHORTCODE-1@}@.", "PREFIX", map[string]string{"HAHAHUGOSHORTCODE-1HBHB": "World"}, false},
@@ -1279,10 +1279,10 @@ func TestShortcodeRef(t *testing.T) {
 
 			v := config.New()
 			v.Set("baseURL", "https://example.org")
-			v.Set("blackfriday", map[string]interface{}{
+			v.Set("blackfriday", map[string]any{
 				"plainIDAnchors": plainIDAnchors,
 			})
-			v.Set("markup", map[string]interface{}{
+			v.Set("markup", map[string]any{
 				"defaultMarkdownHandler": "blackfriday", // TODO(bep)
 			})
 
diff --git a/hugolib/site.go b/hugolib/site.go
@@ -228,7 +228,7 @@ func (s *Site) prepareInits() {
 
 	var init lazy.Init
 
-	s.init.prevNext = init.Branch(func() (interface{}, error) {
+	s.init.prevNext = init.Branch(func() (any, error) {
 		regularPages := s.RegularPages()
 		for i, p := range regularPages {
 			np, ok := p.(nextPrevProvider)
@@ -255,7 +255,7 @@ func (s *Site) prepareInits() {
 		return nil, nil
 	})
 
-	s.init.prevNextInSection = init.Branch(func() (interface{}, error) {
+	s.init.prevNextInSection = init.Branch(func() (any, error) {
 		var sections page.Pages
 		s.home.treeRef.m.collectSectionsRecursiveIncludingSelf(pageMapQuery{Prefix: s.home.treeRef.key}, func(n *contentNode) {
 			sections = append(sections, n.p)
@@ -312,12 +312,12 @@ func (s *Site) prepareInits() {
 		return nil, nil
 	})
 
-	s.init.menus = init.Branch(func() (interface{}, error) {
+	s.init.menus = init.Branch(func() (any, error) {
 		s.assembleMenus()
 		return nil, nil
 	})
 
-	s.init.taxonomies = init.Branch(func() (interface{}, error) {
+	s.init.taxonomies = init.Branch(func() (any, error) {
 		err := s.pageMap.assembleTaxonomies()
 		return nil, err
 	})
@@ -433,8 +433,8 @@ But this also means that your site configuration may not do what you expect. If 
 	}
 
 	var (
-		mediaTypesConfig    []map[string]interface{}
-		outputFormatsConfig []map[string]interface{}
+		mediaTypesConfig    []map[string]any
+		outputFormatsConfig []map[string]any
 
 		siteOutputFormatsConfig output.Formats
 		siteMediaTypesConfig    media.Types
@@ -473,7 +473,7 @@ But this also means that your site configuration may not do what you expect. If 
 		siteOutputFormatsConfig = tmp
 	}
 
-	var siteOutputs map[string]interface{}
+	var siteOutputs map[string]any
 	if cfg.Language.IsSet("outputs") {
 		siteOutputs = cfg.Language.GetStringMap("outputs")
 
@@ -654,7 +654,7 @@ type SiteInfo struct {
 	hugoInfo     hugo.Info
 	title        string
 	RSSLink      string
-	Author       map[string]interface{}
+	Author       map[string]any
 	LanguageCode string
 	Copyright    string
 
@@ -709,7 +709,7 @@ func (s *SiteInfo) Menus() navigation.Menus {
 }
 
 // TODO(bep) type
-func (s *SiteInfo) Taxonomies() interface{} {
+func (s *SiteInfo) Taxonomies() any {
 	return s.s.Taxonomies()
 }
 
@@ -717,7 +717,7 @@ func (s *SiteInfo) Params() maps.Params {
 	return s.s.Language().Params()
 }
 
-func (s *SiteInfo) Data() map[string]interface{} {
+func (s *SiteInfo) Data() map[string]any {
 	return s.s.h.Data()
 }
 
@@ -786,7 +786,7 @@ type SiteSocial map[string]string
 // Param is a convenience method to do lookups in SiteInfo's Params map.
 //
 // This method is also implemented on Page.
-func (s *SiteInfo) Param(key interface{}) (interface{}, error) {
+func (s *SiteInfo) Param(key any) (any, error) {
 	return resource.Param(s, nil, key)
 }
 
@@ -826,7 +826,7 @@ func (s siteRefLinker) logNotFound(ref, what string, p page.Page, position text.
 	}
 }
 
-func (s *siteRefLinker) refLink(ref string, source interface{}, relative bool, outputFormat string) (string, error) {
+func (s *siteRefLinker) refLink(ref string, source any, relative bool, outputFormat string) (string, error) {
 	p, err := unwrapPage(source)
 	if err != nil {
 		return "", err
@@ -1493,7 +1493,7 @@ func (s *Site) assembleMenus() {
 	sectionPagesMenu := s.Info.sectionPagesMenu
 
 	if sectionPagesMenu != "" {
-		s.pageMap.sections.Walk(func(s string, v interface{}) bool {
+		s.pageMap.sections.Walk(func(s string, v any) bool {
 			p := v.(*contentNode).p
 			if p.IsHome() {
 				return false
@@ -1695,7 +1695,7 @@ func (s *Site) lookupLayouts(layouts ...string) tpl.Template {
 	return nil
 }
 
-func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath string, d interface{}, templ tpl.Template) error {
+func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath string, d any, templ tpl.Template) error {
 	s.Log.Debugf("Render XML for %q to %q", name, targetPath)
 	renderBuffer := bp.GetBuffer()
 	defer bp.PutBuffer(renderBuffer)
@@ -1779,7 +1779,7 @@ type hookRendererTemplate struct {
 	templateHandler tpl.TemplateHandler
 	identity.SearchProvider
 	templ           tpl.Template
-	resolvePosition func(ctx interface{}) text.Position
+	resolvePosition func(ctx any) text.Position
 }
 
 func (hr hookRendererTemplate) RenderLink(w io.Writer, ctx hooks.LinkContext) error {
@@ -1794,7 +1794,7 @@ func (hr hookRendererTemplate) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.Co
 	return hr.templateHandler.Execute(hr.templ, w, ctx)
 }
 
-func (hr hookRendererTemplate) ResolvePosition(ctx interface{}) text.Position {
+func (hr hookRendererTemplate) ResolvePosition(ctx any) text.Position {
 	return hr.resolvePosition(ctx)
 }
 
@@ -1802,7 +1802,7 @@ func (hr hookRendererTemplate) IsDefaultCodeBlockRenderer() bool {
 	return false
 }
 
-func (s *Site) renderForTemplate(name, outputFormat string, d interface{}, w io.Writer, templ tpl.Template) (err error) {
+func (s *Site) renderForTemplate(name, outputFormat string, d any, w io.Writer, templ tpl.Template) (err error) {
 	if templ == nil {
 		s.logMissingLayout(name, "", "", outputFormat)
 		return nil
@@ -1871,7 +1871,7 @@ func (s *Site) newPage(
 	parentbBucket *pagesMapBucket,
 	kind, title string,
 	sections ...string) *pageState {
-	m := map[string]interface{}{}
+	m := map[string]any{}
 	if title != "" {
 		m["title"] = title
 	}
diff --git a/hugolib/site_output.go b/hugolib/site_output.go
@@ -53,7 +53,7 @@ func createDefaultOutputFormats(allFormats output.Formats) map[string]output.For
 	return m
 }
 
-func createSiteOutputFormats(allFormats output.Formats, outputs map[string]interface{}, rssDisabled bool) (map[string]output.Formats, error) {
+func createSiteOutputFormats(allFormats output.Formats, outputs map[string]any, rssDisabled bool) (map[string]output.Formats, error) {
 	defaultOutputFormats := createDefaultOutputFormats(allFormats)
 
 	if outputs == nil {
diff --git a/hugolib/site_output_test.go b/hugolib/site_output_test.go
@@ -327,9 +327,9 @@ baseName = "customdelimbase"
 // Issue 8030
 func TestGetOutputFormatRel(t *testing.T) {
 	b := newTestSitesBuilder(t).
-		WithSimpleConfigFileAndSettings(map[string]interface{}{
-			"outputFormats": map[string]interface{}{
-				"humansTXT": map[string]interface{}{
+		WithSimpleConfigFileAndSettings(map[string]any{
+			"outputFormats": map[string]any{
+				"humansTXT": map[string]any{
 					"name":        "HUMANS",
 					"mediaType":   "text/plain",
 					"baseName":    "humans",
@@ -358,7 +358,7 @@ func TestCreateSiteOutputFormats(t *testing.T) {
 	t.Run("Basic", func(t *testing.T) {
 		c := qt.New(t)
 
-		outputsConfig := map[string]interface{}{
+		outputsConfig := map[string]any{
 			page.KindHome:    []string{"HTML", "JSON"},
 			page.KindSection: []string{"JSON"},
 		}
@@ -390,7 +390,7 @@ func TestCreateSiteOutputFormats(t *testing.T) {
 		c := qt.New(t)
 		cfg := config.New()
 
-		outputsConfig := map[string]interface{}{
+		outputsConfig := map[string]any{
 			// Note that we in Hugo 0.53.0 renamed this Kind to "taxonomy",
 			// but keep this test to test the legacy mapping.
 			"taxonomyterm": []string{"JSON"},
@@ -406,7 +406,7 @@ func TestCreateSiteOutputFormats(t *testing.T) {
 func TestCreateSiteOutputFormatsInvalidConfig(t *testing.T) {
 	c := qt.New(t)
 
-	outputsConfig := map[string]interface{}{
+	outputsConfig := map[string]any{
 		page.KindHome: []string{"FOO", "JSON"},
 	}
 
@@ -420,7 +420,7 @@ func TestCreateSiteOutputFormatsInvalidConfig(t *testing.T) {
 func TestCreateSiteOutputFormatsEmptyConfig(t *testing.T) {
 	c := qt.New(t)
 
-	outputsConfig := map[string]interface{}{
+	outputsConfig := map[string]any{
 		page.KindHome: []string{},
 	}
 
@@ -435,7 +435,7 @@ func TestCreateSiteOutputFormatsEmptyConfig(t *testing.T) {
 func TestCreateSiteOutputFormatsCustomFormats(t *testing.T) {
 	c := qt.New(t)
 
-	outputsConfig := map[string]interface{}{
+	outputsConfig := map[string]any{
 		page.KindHome: []string{},
 	}
 
diff --git a/hugolib/site_render.go b/hugolib/site_render.go
@@ -153,7 +153,7 @@ func (s *Site) logMissingLayout(name, layout, kind, outputFormat string) {
 	}
 
 	errMsg := "You should create a template file which matches Hugo Layouts Lookup Rules for this combination."
-	var args []interface{}
+	var args []any
 	msg := "found no layout file for"
 	if outputFormat != "" {
 		msg += " %q"
diff --git a/hugolib/site_test.go b/hugolib/site_test.go
@@ -56,7 +56,7 @@ func TestDraftAndFutureRender(t *testing.T) {
 		{filepath.FromSlash("sect/doc4.md"), "---\ntitle: doc4\ndraft: false\npublishdate: \"2012-05-29\"\n---\n# doc4\n*some content*"},
 	}
 
-	siteSetup := func(t *testing.T, configKeyValues ...interface{}) *Site {
+	siteSetup := func(t *testing.T, configKeyValues ...any) *Site {
 		cfg, fs := newTestCfg()
 
 		cfg.Set("baseURL", "http://auth/bub")
@@ -288,7 +288,7 @@ func doTestShouldAlwaysHaveUglyURLs(t *testing.T, uglyURLs bool) {
 	cfg.Set("verbose", true)
 	cfg.Set("baseURL", "http://auth/bub")
 	cfg.Set("blackfriday",
-		map[string]interface{}{
+		map[string]any{
 			"plainIDAnchors": true,
 		})
 
@@ -364,7 +364,7 @@ func TestMainSections(t *testing.T) {
 		c.Run(fmt.Sprintf("param-%t", paramSet), func(c *qt.C) {
 			v := config.New()
 			if paramSet {
-				v.Set("params", map[string]interface{}{
+				v.Set("params", map[string]any{
 					"mainSections": []string{"a1", "a2"},
 				})
 			}
@@ -882,13 +882,13 @@ func setupLinkingMockSite(t *testing.T) *Site {
 
 	cfg.Set("baseURL", "http://auth/")
 	cfg.Set("uglyURLs", false)
-	cfg.Set("outputs", map[string]interface{}{
+	cfg.Set("outputs", map[string]any{
 		"page": []string{"HTML", "AMP"},
 	})
 	cfg.Set("pluralizeListTitles", false)
 	cfg.Set("canonifyURLs", false)
 	cfg.Set("blackfriday",
-		map[string]interface{}{})
+		map[string]any{})
 	writeSourcesToSource(t, "content", fs, sources...)
 	return buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 }
diff --git a/hugolib/sitemap_test.go b/hugolib/sitemap_test.go
@@ -88,7 +88,7 @@ func doTestSitemapOutput(t *testing.T, internal bool) {
 func TestParseSitemap(t *testing.T) {
 	t.Parallel()
 	expected := config.Sitemap{Priority: 3.0, Filename: "doo.xml", ChangeFreq: "3"}
-	input := map[string]interface{}{
+	input := map[string]any{
 		"changefreq": "3",
 		"priority":   3.0,
 		"filename":   "doo.xml",
diff --git a/hugolib/testhelpers_test.go b/hugolib/testhelpers_test.go
@@ -173,7 +173,7 @@ func (s *sitesBuilder) WithEnviron(env ...string) *sitesBuilder {
 	return s
 }
 
-func (s *sitesBuilder) WithConfigTemplate(data interface{}, format, configTemplate string) *sitesBuilder {
+func (s *sitesBuilder) WithConfigTemplate(data any, format, configTemplate string) *sitesBuilder {
 	s.T.Helper()
 
 	if format == "" {
@@ -279,10 +279,10 @@ func (s *sitesBuilder) WithSimpleConfigFile() *sitesBuilder {
 
 func (s *sitesBuilder) WithSimpleConfigFileAndBaseURL(baseURL string) *sitesBuilder {
 	s.T.Helper()
-	return s.WithSimpleConfigFileAndSettings(map[string]interface{}{"baseURL": baseURL})
+	return s.WithSimpleConfigFileAndSettings(map[string]any{"baseURL": baseURL})
 }
 
-func (s *sitesBuilder) WithSimpleConfigFileAndSettings(settings interface{}) *sitesBuilder {
+func (s *sitesBuilder) WithSimpleConfigFileAndSettings(settings any) *sitesBuilder {
 	s.T.Helper()
 	var buf bytes.Buffer
 	parser.InterfaceToConfig(settings, metadecoders.TOML, &buf)
@@ -690,7 +690,7 @@ hello:
 	}
 }
 
-func (s *sitesBuilder) Fatalf(format string, args ...interface{}) {
+func (s *sitesBuilder) Fatalf(format string, args ...any) {
 	s.T.Helper()
 	s.T.Fatalf(format, args...)
 }
@@ -784,7 +784,7 @@ func (s *sitesBuilder) FileContent(filename string) string {
 	return readDestination(s.T, s.Fs, filename)
 }
 
-func (s *sitesBuilder) AssertObject(expected string, object interface{}) {
+func (s *sitesBuilder) AssertObject(expected string, object any) {
 	s.T.Helper()
 	got := s.dumper.Sdump(object)
 	expected = strings.TrimSpace(expected)
diff --git a/langs/config.go b/langs/config.go
@@ -41,7 +41,7 @@ func LoadLanguageSettings(cfg config.Provider, oldLangs Languages) (c LanguagesC
 		cfg.Set("defaultContentLanguage", defaultLang)
 	}
 
-	var languages map[string]interface{}
+	var languages map[string]any
 
 	languagesFromConfig := cfg.GetParams("languages")
 	disableLanguages := cfg.GetStringSlice("disableLanguages")
@@ -170,7 +170,7 @@ func LoadLanguageSettings(cfg config.Provider, oldLangs Languages) (c LanguagesC
 	return c, nil
 }
 
-func toSortedLanguages(cfg config.Provider, l map[string]interface{}) (Languages, error) {
+func toSortedLanguages(cfg config.Provider, l map[string]any) (Languages, error) {
 	languages := make(Languages, len(l))
 	i := 0
 
diff --git a/langs/i18n/i18n.go b/langs/i18n/i18n.go
@@ -28,7 +28,7 @@ import (
 	"github.com/gohugoio/go-i18n/v2/i18n"
 )
 
-type translateFunc func(translationID string, templateData interface{}) string
+type translateFunc func(translationID string, templateData any) string
 
 var i18nWarningLogger = helpers.NewDistinctErrorLogger()
 
@@ -58,7 +58,7 @@ func (t Translator) Func(lang string) translateFunc {
 	}
 
 	t.logger.Infoln("i18n not initialized; if you need string translations, check that you have a bundle in /i18n that matches the site language or the default language.")
-	return func(translationID string, args interface{}) string {
+	return func(translationID string, args any) string {
 		return ""
 	}
 }
@@ -71,7 +71,7 @@ func (t Translator) initFuncs(bndl *i18n.Bundle) {
 		// This may be pt-BR; make it case insensitive.
 		currentLangKey := strings.ToLower(strings.TrimPrefix(currentLangStr, artificialLangTagPrefix))
 		localizer := i18n.NewLocalizer(bndl, currentLangStr)
-		t.translateFuncs[currentLangKey] = func(translationID string, templateData interface{}) string {
+		t.translateFuncs[currentLangKey] = func(translationID string, templateData any) string {
 			pluralCount := getPluralCount(templateData)
 
 			if templateData != nil {
@@ -134,7 +134,7 @@ const countFieldName = "Count"
 
 // getPluralCount gets the plural count as a string (floats) or an integer.
 // If v is nil, nil is returned.
-func getPluralCount(v interface{}) interface{} {
+func getPluralCount(v any) any {
 	if v == nil {
 		// i18n called without any argument, make sure it does not
 		// get any plural count.
@@ -142,7 +142,7 @@ func getPluralCount(v interface{}) interface{} {
 	}
 
 	switch v := v.(type) {
-	case map[string]interface{}:
+	case map[string]any:
 		for k, vv := range v {
 			if strings.EqualFold(k, countFieldName) {
 				return toPluralCountValue(vv)
@@ -172,7 +172,7 @@ func getPluralCount(v interface{}) interface{} {
 }
 
 // go-i18n expects floats to be represented by string.
-func toPluralCountValue(in interface{}) interface{} {
+func toPluralCountValue(in any) any {
 	k := reflect.TypeOf(in).Kind()
 	switch {
 	case hreflect.IsFloat(k):
diff --git a/langs/i18n/i18n_test.go b/langs/i18n/i18n_test.go
@@ -41,7 +41,7 @@ var logger = loggers.NewErrorLogger()
 type i18nTest struct {
 	name                             string
 	data                             map[string][]byte
-	args                             interface{}
+	args                             any
 	lang, id, expected, expectedFlag string
 }
 
@@ -179,7 +179,7 @@ one = "One minute to read"
 other = "{{ .Count }} minutes to read"
 `),
 		},
-		args:         map[string]interface{}{"Count": 1},
+		args:         map[string]any{"Count": 1},
 		lang:         "en",
 		id:           "readingTime",
 		expected:     "One minute to read",
@@ -207,7 +207,7 @@ one = "One minute to read"
 other = "{{ .Count }} minutes to read"
 `),
 		},
-		args:         map[string]interface{}{"Count": 21},
+		args:         map[string]any{"Count": 21},
 		lang:         "en",
 		id:           "readingTime",
 		expected:     "21 minutes to read",
@@ -426,7 +426,7 @@ func doTestI18nTranslate(t testing.TB, test i18nTest, cfg config.Provider) strin
 }
 
 type countField struct {
-	Count interface{}
+	Count any
 }
 
 type noCountField struct {
@@ -436,21 +436,21 @@ type noCountField struct {
 type countMethod struct {
 }
 
-func (c countMethod) Count() interface{} {
+func (c countMethod) Count() any {
 	return 32.5
 }
 
 func TestGetPluralCount(t *testing.T) {
 	c := qt.New(t)
 
-	c.Assert(getPluralCount(map[string]interface{}{"Count": 32}), qt.Equals, 32)
-	c.Assert(getPluralCount(map[string]interface{}{"Count": 1}), qt.Equals, 1)
-	c.Assert(getPluralCount(map[string]interface{}{"Count": 1.5}), qt.Equals, "1.5")
-	c.Assert(getPluralCount(map[string]interface{}{"Count": "32"}), qt.Equals, "32")
-	c.Assert(getPluralCount(map[string]interface{}{"Count": "32.5"}), qt.Equals, "32.5")
-	c.Assert(getPluralCount(map[string]interface{}{"count": 32}), qt.Equals, 32)
-	c.Assert(getPluralCount(map[string]interface{}{"Count": "32"}), qt.Equals, "32")
-	c.Assert(getPluralCount(map[string]interface{}{"Counts": 32}), qt.Equals, nil)
+	c.Assert(getPluralCount(map[string]any{"Count": 32}), qt.Equals, 32)
+	c.Assert(getPluralCount(map[string]any{"Count": 1}), qt.Equals, 1)
+	c.Assert(getPluralCount(map[string]any{"Count": 1.5}), qt.Equals, "1.5")
+	c.Assert(getPluralCount(map[string]any{"Count": "32"}), qt.Equals, "32")
+	c.Assert(getPluralCount(map[string]any{"Count": "32.5"}), qt.Equals, "32.5")
+	c.Assert(getPluralCount(map[string]any{"count": 32}), qt.Equals, 32)
+	c.Assert(getPluralCount(map[string]any{"Count": "32"}), qt.Equals, "32")
+	c.Assert(getPluralCount(map[string]any{"Counts": 32}), qt.Equals, nil)
 	c.Assert(getPluralCount("foo"), qt.Equals, nil)
 	c.Assert(getPluralCount(countField{Count: 22}), qt.Equals, 22)
 	c.Assert(getPluralCount(countField{Count: 1.5}), qt.Equals, "1.5")
diff --git a/langs/language.go b/langs/language.go
@@ -21,10 +21,10 @@ import (
 
 	"github.com/pkg/errors"
 
-	translators "github.com/gohugoio/localescompressed"
-	"github.com/gohugoio/locales"
 	"github.com/gohugoio/hugo/common/maps"
 	"github.com/gohugoio/hugo/config"
+	"github.com/gohugoio/locales"
+	translators "github.com/gohugoio/localescompressed"
 )
 
 // These are the settings that should only be looked up in the global Viper
@@ -70,7 +70,7 @@ type Language struct {
 
 	// These are params declared in the [params] section of the language merged with the
 	// site's params, the most specific (language) wins on duplicate keys.
-	params    map[string]interface{}
+	params    map[string]any
 	paramsMu  sync.Mutex
 	paramsSet bool
 
@@ -93,7 +93,7 @@ func (l *Language) String() string {
 func NewLanguage(lang string, cfg config.Provider) *Language {
 	// Note that language specific params will be overridden later.
 	// We should improve that, but we need to make a copy:
-	params := make(map[string]interface{})
+	params := make(map[string]any)
 	for k, v := range cfg.GetStringMap("params") {
 		params[k] = v
 	}
@@ -212,7 +212,7 @@ func (l Languages) IsMultihost() bool {
 
 // SetParam sets a param with the given key and value.
 // SetParam is case-insensitive.
-func (l *Language) SetParam(k string, v interface{}) {
+func (l *Language) SetParam(k string, v any) {
 	l.paramsMu.Lock()
 	defer l.paramsMu.Unlock()
 	if l.paramsSet {
@@ -224,7 +224,7 @@ func (l *Language) SetParam(k string, v interface{}) {
 // GetLocal gets a configuration value set on language level. It will
 // not fall back to any global value.
 // It will return nil if a value with the given key cannot be found.
-func (l *Language) GetLocal(key string) interface{} {
+func (l *Language) GetLocal(key string) any {
 	if l == nil {
 		panic("language not set")
 	}
@@ -235,7 +235,7 @@ func (l *Language) GetLocal(key string) interface{} {
 	return nil
 }
 
-func (l *Language) Set(k string, v interface{}) {
+func (l *Language) Set(k string, v any) {
 	k = strings.ToLower(k)
 	if globalOnlySettings[k] {
 		return
@@ -244,7 +244,7 @@ func (l *Language) Set(k string, v interface{}) {
 }
 
 // Merge is currently not supported for Language.
-func (l *Language) Merge(key string, value interface{}) {
+func (l *Language) Merge(key string, value any) {
 	panic("Not supported")
 }
 
diff --git a/lazy/init.go b/lazy/init.go
@@ -38,13 +38,13 @@ type Init struct {
 	children []*Init
 
 	init onceMore
-	out  interface{}
+	out  any
 	err  error
-	f    func() (interface{}, error)
+	f    func() (any, error)
 }
 
 // Add adds a func as a new child dependency.
-func (ini *Init) Add(initFn func() (interface{}, error)) *Init {
+func (ini *Init) Add(initFn func() (any, error)) *Init {
 	if ini == nil {
 		ini = New()
 	}
@@ -58,15 +58,15 @@ func (ini *Init) InitCount() int {
 }
 
 // AddWithTimeout is same as Add, but with a timeout that aborts initialization.
-func (ini *Init) AddWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init {
-	return ini.Add(func() (interface{}, error) {
+func (ini *Init) AddWithTimeout(timeout time.Duration, f func(ctx context.Context) (any, error)) *Init {
+	return ini.Add(func() (any, error) {
 		return ini.withTimeout(timeout, f)
 	})
 }
 
 // Branch creates a new dependency branch based on an existing and adds
 // the given dependency as a child.
-func (ini *Init) Branch(initFn func() (interface{}, error)) *Init {
+func (ini *Init) Branch(initFn func() (any, error)) *Init {
 	if ini == nil {
 		ini = New()
 	}
@@ -74,14 +74,14 @@ func (ini *Init) Branch(initFn func() (interface{}, error)) *Init {
 }
 
 // BranchdWithTimeout is same as Branch, but with a timeout.
-func (ini *Init) BranchWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init {
-	return ini.Branch(func() (interface{}, error) {
+func (ini *Init) BranchWithTimeout(timeout time.Duration, f func(ctx context.Context) (any, error)) *Init {
+	return ini.Branch(func() (any, error) {
 		return ini.withTimeout(timeout, f)
 	})
 }
 
 // Do initializes the entire dependency graph.
-func (ini *Init) Do() (interface{}, error) {
+func (ini *Init) Do() (any, error) {
 	if ini == nil {
 		panic("init is nil")
 	}
@@ -154,7 +154,7 @@ func (ini *Init) Reset() {
 	}
 }
 
-func (ini *Init) add(branch bool, initFn func() (interface{}, error)) *Init {
+func (ini *Init) add(branch bool, initFn func() (any, error)) *Init {
 	ini.mu.Lock()
 	defer ini.mu.Unlock()
 
@@ -179,7 +179,7 @@ func (ini *Init) checkDone() {
 	}
 }
 
-func (ini *Init) withTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) (interface{}, error) {
+func (ini *Init) withTimeout(timeout time.Duration, f func(ctx context.Context) (any, error)) (any, error) {
 	ctx, cancel := context.WithTimeout(context.Background(), timeout)
 	defer cancel()
 	c := make(chan verr, 1)
@@ -203,6 +203,6 @@ func (ini *Init) withTimeout(timeout time.Duration, f func(ctx context.Context) 
 }
 
 type verr struct {
-	v   interface{}
+	v   any
 	err error
 }
diff --git a/lazy/init_test.go b/lazy/init_test.go
@@ -48,16 +48,16 @@ func TestInit(t *testing.T) {
 
 	var result string
 
-	f1 := func(name string) func() (interface{}, error) {
-		return func() (interface{}, error) {
+	f1 := func(name string) func() (any, error) {
+		return func() (any, error) {
 			result += name + "|"
 			doWork()
 			return name, nil
 		}
 	}
 
-	f2 := func() func() (interface{}, error) {
-		return func() (interface{}, error) {
+	f2 := func() func() (any, error) {
+		return func() (any, error) {
 			doWork()
 			return nil, nil
 		}
@@ -110,7 +110,7 @@ func TestInit(t *testing.T) {
 func TestInitAddWithTimeout(t *testing.T) {
 	c := qt.New(t)
 
-	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
+	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (any, error) {
 		return nil, nil
 	})
 
@@ -122,7 +122,7 @@ func TestInitAddWithTimeout(t *testing.T) {
 func TestInitAddWithTimeoutTimeout(t *testing.T) {
 	c := qt.New(t)
 
-	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
+	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (any, error) {
 		time.Sleep(500 * time.Millisecond)
 		select {
 		case <-ctx.Done():
@@ -145,7 +145,7 @@ func TestInitAddWithTimeoutTimeout(t *testing.T) {
 func TestInitAddWithTimeoutError(t *testing.T) {
 	c := qt.New(t)
 
-	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
+	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (any, error) {
 		return nil, errors.New("failed")
 	})
 
@@ -178,8 +178,8 @@ func TestInitBranchOrder(t *testing.T) {
 
 	base := New()
 
-	work := func(size int, f func()) func() (interface{}, error) {
-		return func() (interface{}, error) {
+	work := func(size int, f func()) func() (any, error) {
+		return func() (any, error) {
 			doWorkOfSize(size)
 			if f != nil {
 				f()
@@ -225,7 +225,7 @@ func TestInitBranchOrder(t *testing.T) {
 func TestResetError(t *testing.T) {
 	c := qt.New(t)
 	r := false
-	i := New().Add(func() (interface{}, error) {
+	i := New().Add(func() (any, error) {
 		if r {
 			return nil, nil
 		}
diff --git a/magefile.go b/magefile.go
@@ -43,7 +43,7 @@ func init() {
 	os.Setenv("GO111MODULE", "on")
 }
 
-func runWith(env map[string]string, cmd string, inArgs ...interface{}) error {
+func runWith(env map[string]string, cmd string, inArgs ...any) error {
 	s := argsToStrings(inArgs...)
 	return sh.RunWith(env, cmd, s...)
 }
@@ -324,7 +324,7 @@ func TestCoverHTML() error {
 	return sh.Run(goexe, "tool", "cover", "-html="+coverAll)
 }
 
-func runCmd(env map[string]string, cmd string, args ...interface{}) error {
+func runCmd(env map[string]string, cmd string, args ...any) error {
 	if mg.Verbose() {
 		return runWith(env, cmd, args...)
 	}
@@ -361,7 +361,7 @@ func buildTags() string {
 	return "none"
 }
 
-func argsToStrings(v ...interface{}) []string {
+func argsToStrings(v ...any) []string {
 	var args []string
 	for _, arg := range v {
 		switch v := arg.(type) {
diff --git a/markup/blackfriday/blackfriday_config/config.go b/markup/blackfriday/blackfriday_config/config.go
@@ -62,7 +62,7 @@ type Config struct {
 	FootnoteReturnLinkContents string
 }
 
-func UpdateConfig(b Config, m map[string]interface{}) (Config, error) {
+func UpdateConfig(b Config, m map[string]any) (Config, error) {
 	if err := mapstructure.Decode(m, &b); err != nil {
 		return b, errors.WithMessage(err, "failed to decode rendering config")
 	}
diff --git a/markup/blackfriday/convert_test.go b/markup/blackfriday/convert_test.go
@@ -158,7 +158,7 @@ func TestGetHTMLRendererAnchors(t *testing.T) {
 	c.Assert(err, qt.IsNil)
 	conv, err := p.New(converter.DocumentContext{
 		DocumentID: "testid",
-		ConfigOverrides: map[string]interface{}{
+		ConfigOverrides: map[string]any{
 			"plainIDAnchors": false,
 			"footnotes":      true,
 		},
diff --git a/markup/converter/converter.go b/markup/converter/converter.go
@@ -119,11 +119,11 @@ func (b Bytes) Bytes() []byte {
 
 // DocumentContext holds contextual information about the document to convert.
 type DocumentContext struct {
-	Document        interface{} // May be nil. Usually a page.Page
+	Document        any // May be nil. Usually a page.Page
 	DocumentID      string
 	DocumentName    string
 	Filename        string
-	ConfigOverrides map[string]interface{}
+	ConfigOverrides map[string]any
 }
 
 // RenderContext holds contextual information about the content to render.
diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go
@@ -26,11 +26,11 @@ import (
 var _ AttributesOptionsSliceProvider = (*attributes.AttributesHolder)(nil)
 
 type AttributesProvider interface {
-	Attributes() map[string]interface{}
+	Attributes() map[string]any
 }
 
 type LinkContext interface {
-	Page() interface{}
+	Page() any
 	Destination() string
 	Title() string
 	Text() hstring.RenderedString
@@ -40,11 +40,11 @@ type LinkContext interface {
 type CodeblockContext interface {
 	AttributesProvider
 	text.Positioner
-	Options() map[string]interface{}
+	Options() map[string]any
 	Type() string
 	Inner() string
 	Ordinal() int
-	Page() interface{}
+	Page() any
 }
 
 type AttributesOptionsSliceProvider interface {
@@ -70,7 +70,7 @@ type IsDefaultCodeBlockRendererProvider interface {
 // can use to render a heading.
 type HeadingContext interface {
 	// Page is the page containing the heading.
-	Page() interface{}
+	Page() any
 	// Level is the level of the header (i.e. 1 for top-level, 2 for sub-level, etc.).
 	Level() int
 	// Anchor is the HTML id assigned to the heading.
@@ -96,7 +96,7 @@ type HeadingRenderer interface {
 // This may be both slow and aproximate, so should only be
 // used for error logging.
 type ElementPositionResolver interface {
-	ResolvePosition(ctx interface{}) text.Position
+	ResolvePosition(ctx any) text.Position
 }
 
 type RendererType int
@@ -108,4 +108,4 @@ const (
 	CodeBlockRendererType
 )
 
-type GetRendererFunc func(t RendererType, id interface{}) interface{}
+type GetRendererFunc func(t RendererType, id any) any
diff --git a/markup/goldmark/codeblocks/render.go b/markup/goldmark/codeblocks/render.go
@@ -132,7 +132,7 @@ func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.No
 }
 
 type codeBlockContext struct {
-	page    interface{}
+	page    any
 	lang    string
 	code    string
 	ordinal int
@@ -146,7 +146,7 @@ type codeBlockContext struct {
 	*attributes.AttributesHolder
 }
 
-func (c *codeBlockContext) Page() interface{} {
+func (c *codeBlockContext) Page() any {
 	return c.page
 }
 
diff --git a/markup/goldmark/convert_test.go b/markup/goldmark/convert_test.go
@@ -44,7 +44,7 @@ func convert(c *qt.C, mconf markup_config.Config, content string) converter.Resu
 	c.Assert(err, qt.IsNil)
 	h := highlight.New(mconf.Highlight)
 
-	getRenderer := func(t hooks.RendererType, id interface{}) interface{} {
+	getRenderer := func(t hooks.RendererType, id any) any {
 		if t == hooks.CodeBlockRendererType {
 			return h
 		}
@@ -233,7 +233,7 @@ func TestConvertAttributes(t *testing.T) {
 		name       string
 		withConfig func(conf *markup_config.Config)
 		input      string
-		expect     interface{}
+		expect     any
 	}{
 		{
 			"Title",
@@ -408,7 +408,7 @@ LINE5
 
 		h := highlight.New(conf)
 
-		getRenderer := func(t hooks.RendererType, id interface{}) interface{} {
+		getRenderer := func(t hooks.RendererType, id any) any {
 			if t == hooks.CodeBlockRendererType {
 				return h
 			}
diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go
@@ -47,7 +47,7 @@ func newLinks(cfg goldmark_config.Config) goldmark.Extender {
 }
 
 type linkContext struct {
-	page        interface{}
+	page        any
 	destination string
 	title       string
 	text        hstring.RenderedString
@@ -62,7 +62,7 @@ func (ctx linkContext) Resolved() bool {
 	return false
 }
 
-func (ctx linkContext) Page() interface{} {
+func (ctx linkContext) Page() any {
 	return ctx.page
 }
 
@@ -79,7 +79,7 @@ func (ctx linkContext) Title() string {
 }
 
 type headingContext struct {
-	page      interface{}
+	page      any
 	level     int
 	anchor    string
 	text      hstring.RenderedString
@@ -87,7 +87,7 @@ type headingContext struct {
 	*attributes.AttributesHolder
 }
 
-func (ctx headingContext) Page() interface{} {
+func (ctx headingContext) Page() any {
 	return ctx.page
 }
 
@@ -112,7 +112,7 @@ type hookedRenderer struct {
 	html.Config
 }
 
-func (r *hookedRenderer) SetOption(name renderer.OptionName, value interface{}) {
+func (r *hookedRenderer) SetOption(name renderer.OptionName, value any) {
 	r.Config.SetOption(name, value)
 }
 
diff --git a/markup/goldmark/toc_test.go b/markup/goldmark/toc_test.go
@@ -28,7 +28,7 @@ import (
 	qt "github.com/frankban/quicktest"
 )
 
-var nopGetRenderer = func(t hooks.RendererType, id interface{}) interface{} { return nil }
+var nopGetRenderer = func(t hooks.RendererType, id any) any { return nil }
 
 func TestToc(t *testing.T) {
 	c := qt.New(t)
diff --git a/markup/highlight/config.go b/markup/highlight/config.go
@@ -115,12 +115,12 @@ func (cfg Config) ToHTMLOptions() []html.Option {
 	return options
 }
 
-func applyOptions(opts interface{}, cfg *Config) error {
+func applyOptions(opts any, cfg *Config) error {
 	if opts == nil {
 		return nil
 	}
 	switch vv := opts.(type) {
-	case map[string]interface{}:
+	case map[string]any:
 		return applyOptionsFromMap(vv, cfg)
 	default:
 		s, err := cast.ToStringE(opts)
@@ -139,7 +139,7 @@ func applyOptionsFromString(opts string, cfg *Config) error {
 	return mapstructure.WeakDecode(optsm, cfg)
 }
 
-func applyOptionsFromMap(optsm map[string]interface{}, cfg *Config) error {
+func applyOptionsFromMap(optsm map[string]any, cfg *Config) error {
 	normalizeHighlightOptions(optsm)
 	return mapstructure.WeakDecode(optsm, cfg)
 }
@@ -184,9 +184,9 @@ func ApplyLegacyConfig(cfg config.Provider, conf *Config) error {
 	return nil
 }
 
-func parseHightlightOptions(in string) (map[string]interface{}, error) {
+func parseHightlightOptions(in string) (map[string]any, error) {
 	in = strings.Trim(in, " ")
-	opts := make(map[string]interface{})
+	opts := make(map[string]any)
 
 	if in == "" {
 		return opts, nil
@@ -207,7 +207,7 @@ func parseHightlightOptions(in string) (map[string]interface{}, error) {
 	return opts, nil
 }
 
-func normalizeHighlightOptions(m map[string]interface{}) {
+func normalizeHighlightOptions(m map[string]any) {
 	if m == nil {
 		return
 	}
diff --git a/markup/highlight/highlight.go b/markup/highlight/highlight.go
@@ -58,8 +58,8 @@ func New(cfg Config) Highlighter {
 }
 
 type Highlighter interface {
-	Highlight(code, lang string, opts interface{}) (string, error)
-	HighlightCodeBlock(ctx hooks.CodeblockContext, opts interface{}) (HightlightResult, error)
+	Highlight(code, lang string, opts any) (string, error)
+	HighlightCodeBlock(ctx hooks.CodeblockContext, opts any) (HightlightResult, error)
 	hooks.CodeBlockRenderer
 	hooks.IsDefaultCodeBlockRendererProvider
 }
@@ -68,7 +68,7 @@ type chromaHighlighter struct {
 	cfg Config
 }
 
-func (h chromaHighlighter) Highlight(code, lang string, opts interface{}) (string, error) {
+func (h chromaHighlighter) Highlight(code, lang string, opts any) (string, error) {
 	cfg := h.cfg
 	if err := applyOptions(opts, &cfg); err != nil {
 		return "", err
@@ -82,7 +82,7 @@ func (h chromaHighlighter) Highlight(code, lang string, opts interface{}) (strin
 	return b.String(), nil
 }
 
-func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts interface{}) (HightlightResult, error) {
+func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts any) (HightlightResult, error) {
 	cfg := h.cfg
 
 	var b strings.Builder
diff --git a/markup/internal/attributes/attributes.go b/markup/internal/attributes/attributes.go
@@ -64,11 +64,11 @@ func New(astAttributes []ast.Attribute, ownerType AttributesOwnerType) *Attribut
 		if strings.HasPrefix(string(nameLower), "on") {
 			continue
 		}
-		var vv interface{}
+		var vv any
 		switch vvv := v.Value.(type) {
 		case bool, float64:
 			vv = vvv
-		case []interface{}:
+		case []any:
 			// Highlight line number hlRanges.
 			var hlRanges [][2]int
 			for _, l := range vvv {
@@ -118,7 +118,7 @@ func New(astAttributes []ast.Attribute, ownerType AttributesOwnerType) *Attribut
 
 type Attribute struct {
 	Name  string
-	Value interface{}
+	Value any
 }
 
 func (a Attribute) ValueString() string {
@@ -134,16 +134,16 @@ type AttributesHolder struct {
 
 	// What we send to the the render hooks.
 	attributesMapInit sync.Once
-	attributesMap     map[string]interface{}
+	attributesMap     map[string]any
 	optionsMapInit    sync.Once
-	optionsMap        map[string]interface{}
+	optionsMap        map[string]any
 }
 
-type Attributes map[string]interface{}
+type Attributes map[string]any
 
-func (a *AttributesHolder) Attributes() map[string]interface{} {
+func (a *AttributesHolder) Attributes() map[string]any {
 	a.attributesMapInit.Do(func() {
-		a.attributesMap = make(map[string]interface{})
+		a.attributesMap = make(map[string]any)
 		for _, v := range a.attributes {
 			a.attributesMap[v.Name] = v.Value
 		}
@@ -151,9 +151,9 @@ func (a *AttributesHolder) Attributes() map[string]interface{} {
 	return a.attributesMap
 }
 
-func (a *AttributesHolder) Options() map[string]interface{} {
+func (a *AttributesHolder) Options() map[string]any {
 	a.optionsMapInit.Do(func() {
-		a.optionsMap = make(map[string]interface{})
+		a.optionsMap = make(map[string]any)
 		for _, v := range a.options {
 			a.optionsMap[v.Name] = v.Value
 		}
diff --git a/markup/markup_config/config.go b/markup/markup_config/config.go
@@ -67,7 +67,7 @@ func Decode(cfg config.Provider) (conf Config, err error) {
 	return
 }
 
-func normalizeConfig(m map[string]interface{}) {
+func normalizeConfig(m map[string]any) {
 	v, err := maps.GetNestedParam("goldmark.parser", ".", m)
 	if err != nil {
 		return
@@ -117,7 +117,7 @@ var Default = Config{
 
 func init() {
 	docsProvider := func() docshelper.DocProvider {
-		return docshelper.DocProvider{"config": map[string]interface{}{"markup": parser.LowerCaseCamelJSONMarshaller{Value: Default}}}
+		return docshelper.DocProvider{"config": map[string]any{"markup": parser.LowerCaseCamelJSONMarshaller{Value: Default}}}
 	}
 	docshelper.AddDocProviderFunc(docsProvider)
 }
diff --git a/markup/markup_config/config_test.go b/markup/markup_config/config_test.go
@@ -28,13 +28,13 @@ func TestConfig(t *testing.T) {
 		c.Parallel()
 		v := config.New()
 
-		v.Set("markup", map[string]interface{}{
-			"goldmark": map[string]interface{}{
-				"renderer": map[string]interface{}{
+		v.Set("markup", map[string]any{
+			"goldmark": map[string]any{
+				"renderer": map[string]any{
 					"unsafe": true,
 				},
 			},
-			"asciidocext": map[string]interface{}{
+			"asciidocext": map[string]any{
 				"workingFolderCurrent": true,
 				"safeMode":             "save",
 				"extensions":           []string{"asciidoctor-html5s"},
@@ -57,7 +57,7 @@ func TestConfig(t *testing.T) {
 		c.Parallel()
 		v := config.New()
 
-		v.Set("blackfriday", map[string]interface{}{
+		v.Set("blackfriday", map[string]any{
 			"angledQuotes": true,
 		})
 
@@ -66,9 +66,9 @@ func TestConfig(t *testing.T) {
 		v.Set("pygmentsStyle", "hugo")
 		v.Set("pygmentsCodefencesGuessSyntax", true)
 
-		v.Set("markup", map[string]interface{}{
-			"goldmark": map[string]interface{}{
-				"parser": map[string]interface{}{
+		v.Set("markup", map[string]any{
+			"goldmark": map[string]any{
+				"parser": map[string]any{
 					"attribute": false, // Was changed to a struct in 0.81.0
 				},
 			},
diff --git a/media/docshelper.go b/media/docshelper.go
@@ -7,7 +7,7 @@ import (
 // This is is just some helpers used to create some JSON used in the Hugo docs.
 func init() {
 	docsProvider := func() docshelper.DocProvider {
-		return docshelper.DocProvider{"media": map[string]interface{}{"types": DefaultTypes}}
+		return docshelper.DocProvider{"media": map[string]any{"types": DefaultTypes}}
 	}
 	docshelper.AddDocProviderFunc(docsProvider)
 }
diff --git a/media/mediaType.go b/media/mediaType.go
@@ -450,7 +450,7 @@ Note that you can still get the Media Type's suffix from a template: {{ $mediaTy
 
 // DecodeTypes takes a list of media type configurations and merges those,
 // in the order given, with the Hugo defaults as the last resort.
-func DecodeTypes(mms ...map[string]interface{}) (Types, error) {
+func DecodeTypes(mms ...map[string]any) (Types, error) {
 	var m Types
 
 	// Maps type string to Type. Type string is the full application/svg+xml.
diff --git a/media/mediaType_test.go b/media/mediaType_test.go
@@ -231,15 +231,15 @@ func TestDecodeTypes(t *testing.T) {
 
 	tests := []struct {
 		name        string
-		maps        []map[string]interface{}
+		maps        []map[string]any
 		shouldError bool
 		assert      func(t *testing.T, name string, tt Types)
 	}{
 		{
 			"Redefine JSON",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"application/json": map[string]interface{}{
+					"application/json": map[string]any{
 						"suffixes": []string{"jasn"},
 					},
 				},
@@ -255,9 +255,9 @@ func TestDecodeTypes(t *testing.T) {
 		},
 		{
 			"MIME suffix in key, multiple file suffixes, custom delimiter",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"application/hugo+hg": map[string]interface{}{
+					"application/hugo+hg": map[string]any{
 						"suffixes":  []string{"hg1", "hG2"},
 						"Delimiter": "_",
 					},
@@ -281,9 +281,9 @@ func TestDecodeTypes(t *testing.T) {
 		},
 		{
 			"Add custom media type",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"text/hugo+hgo": map[string]interface{}{
+					"text/hugo+hgo": map[string]any{
 						"Suffixes": []string{"hgo2"},
 					},
 				},
diff --git a/metrics/metrics.go b/metrics/metrics.go
@@ -40,19 +40,19 @@ type Provider interface {
 	WriteMetrics(w io.Writer)
 
 	// TrackValue tracks the value for diff calculations etc.
-	TrackValue(key string, value interface{}, cached bool)
+	TrackValue(key string, value any, cached bool)
 
 	// Reset clears the metric store.
 	Reset()
 }
 
 type diff struct {
-	baseline interface{}
+	baseline any
 	count    int
 	simSum   int
 }
 
-func (d *diff) add(v interface{}) *diff {
+func (d *diff) add(v any) *diff {
 	if types.IsNil(d.baseline) {
 		d.baseline = v
 		d.count = 1
@@ -103,7 +103,7 @@ func (s *Store) Reset() {
 }
 
 // TrackValue tracks the value for diff calculations etc.
-func (s *Store) TrackValue(key string, value interface{}, cached bool) {
+func (s *Store) TrackValue(key string, value any, cached bool) {
 	if !s.calculateHints {
 		return
 	}
@@ -207,7 +207,7 @@ func (b bySum) Less(i, j int) bool { return b[i].sum > b[j].sum }
 
 // howSimilar is a naive diff implementation that returns
 // a number between 0-100 indicating how similar a and b are.
-func howSimilar(a, b interface{}) int {
+func howSimilar(a, b any) int {
 	t1, t2 := reflect.TypeOf(a), reflect.TypeOf(b)
 	if t1 != t2 {
 		return 0
diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go
@@ -41,8 +41,8 @@ func TestSimilarPercentage(t *testing.T) {
 	c.Assert(howSimilar("Totally different", "Not Same"), qt.Equals, 0)
 	c.Assert(howSimilar(sentence, sentenceReversed), qt.Equals, 14)
 	c.Assert(howSimilar(template.HTML("Hugo Rules"), template.HTML("Hugo Rules")), qt.Equals, 100)
-	c.Assert(howSimilar(map[string]interface{}{"a": 32, "b": 33}, map[string]interface{}{"a": 32, "b": 33}), qt.Equals, 100)
-	c.Assert(howSimilar(map[string]interface{}{"a": 32, "b": 33}, map[string]interface{}{"a": 32, "b": 34}), qt.Equals, 0)
+	c.Assert(howSimilar(map[string]any{"a": 32, "b": 33}, map[string]any{"a": 32, "b": 33}), qt.Equals, 100)
+	c.Assert(howSimilar(map[string]any{"a": 32, "b": 33}, map[string]any{"a": 32, "b": 34}), qt.Equals, 0)
 }
 
 type testStruct struct {
diff --git a/minifiers/config.go b/minifiers/config.go
@@ -124,7 +124,7 @@ func decodeConfig(cfg config.Provider) (conf minifyConfig, err error) {
 
 func init() {
 	docsProvider := func() docshelper.DocProvider {
-		return docshelper.DocProvider{"config": map[string]interface{}{"minify": parser.LowerCaseCamelJSONMarshaller{Value: defaultConfig}}}
+		return docshelper.DocProvider{"config": map[string]any{"minify": parser.LowerCaseCamelJSONMarshaller{Value: defaultConfig}}}
 	}
 	docshelper.AddDocProviderFunc(docsProvider)
 }
diff --git a/minifiers/config_test.go b/minifiers/config_test.go
@@ -25,10 +25,10 @@ func TestConfig(t *testing.T) {
 	c := qt.New(t)
 	v := config.New()
 
-	v.Set("minify", map[string]interface{}{
+	v.Set("minify", map[string]any{
 		"disablexml": true,
-		"tdewolff": map[string]interface{}{
-			"html": map[string]interface{}{
+		"tdewolff": map[string]any{
+			"html": map[string]any{
 				"keepwhitespace": false,
 			},
 		},
diff --git a/minifiers/minifiers_test.go b/minifiers/minifiers_test.go
@@ -77,10 +77,10 @@ func TestNew(t *testing.T) {
 func TestConfigureMinify(t *testing.T) {
 	c := qt.New(t)
 	v := config.New()
-	v.Set("minify", map[string]interface{}{
+	v.Set("minify", map[string]any{
 		"disablexml": true,
-		"tdewolff": map[string]interface{}{
-			"html": map[string]interface{}{
+		"tdewolff": map[string]any{
+			"html": map[string]any{
 				"keepwhitespace": true,
 			},
 		},
@@ -137,8 +137,8 @@ func TestJSONRoundTrip(t *testing.T) {
 }`} {
 
 		var b bytes.Buffer
-		m1 := make(map[string]interface{})
-		m2 := make(map[string]interface{})
+		m1 := make(map[string]any)
+		m2 := make(map[string]any)
 		c.Assert(json.Unmarshal([]byte(test), &m1), qt.IsNil)
 		c.Assert(m.Minify(media.JSONType, &b, strings.NewReader(test)), qt.IsNil)
 		c.Assert(json.Unmarshal(b.Bytes(), &m2), qt.IsNil)
@@ -172,13 +172,13 @@ func TestBugs(t *testing.T) {
 func TestDecodeConfigDecimalIsNowPrecision(t *testing.T) {
 	c := qt.New(t)
 	v := config.New()
-	v.Set("minify", map[string]interface{}{
+	v.Set("minify", map[string]any{
 		"disablexml": true,
-		"tdewolff": map[string]interface{}{
-			"css": map[string]interface{}{
+		"tdewolff": map[string]any{
+			"css": map[string]any{
 				"decimal": 3,
 			},
-			"svg": map[string]interface{}{
+			"svg": map[string]any{
 				"decimal": 3,
 			},
 		},
@@ -195,9 +195,9 @@ func TestDecodeConfigDecimalIsNowPrecision(t *testing.T) {
 func TestDecodeConfigKeepWhitespace(t *testing.T) {
 	c := qt.New(t)
 	v := config.New()
-	v.Set("minify", map[string]interface{}{
-		"tdewolff": map[string]interface{}{
-			"html": map[string]interface{}{
+	v.Set("minify", map[string]any{
+		"tdewolff": map[string]any{
+			"html": map[string]any{
 				"keepEndTags": false,
 			},
 		},
diff --git a/modules/collect.go b/modules/collect.go
@@ -408,7 +408,7 @@ func (c *collector) applyMounts(moduleImport Import, mod *moduleAdapter) error {
 func (c *collector) applyThemeConfig(tc *moduleAdapter) error {
 	var (
 		configFilename string
-		themeCfg       map[string]interface{}
+		themeCfg       map[string]any
 		hasConfigFile  bool
 		err            error
 	)
@@ -487,7 +487,7 @@ func (c *collector) applyThemeConfig(tc *moduleAdapter) error {
 		}
 
 		if config.Params == nil {
-			config.Params = make(map[string]interface{})
+			config.Params = make(map[string]any)
 		}
 
 		for k, v := range themeCfg {
diff --git a/modules/config.go b/modules/config.go
@@ -270,7 +270,7 @@ type Config struct {
 	Imports []Import
 
 	// Meta info about this module (license information etc.).
-	Params map[string]interface{}
+	Params map[string]any
 
 	// Will be validated against the running Hugo version.
 	HugoVersion HugoVersion
@@ -386,10 +386,10 @@ type Mount struct {
 	Lang string // any language code associated with this mount.
 
 	// Include only files matching the given Glob patterns (string or slice).
-	IncludeFiles interface{}
+	IncludeFiles any
 
 	// Exclude all files matching the given Glob patterns (string or slice).
-	ExcludeFiles interface{}
+	ExcludeFiles any
 }
 
 // Used as key to remove duplicates.
diff --git a/modules/npm/package_builder.go b/modules/npm/package_builder.go
@@ -119,12 +119,12 @@ func Pack(fs afero.Fs, fis []hugofs.FileMetaInfo) error {
 	// Replace the dependencies in the original template with the merged set.
 	b.originalPackageJSON[dependenciesKey] = b.dependencies
 	b.originalPackageJSON[devDependenciesKey] = b.devDependencies
-	var commentsm map[string]interface{}
+	var commentsm map[string]any
 	comments, found := b.originalPackageJSON["comments"]
 	if found {
 		commentsm = maps.ToStringMap(comments)
 	} else {
-		commentsm = make(map[string]interface{})
+		commentsm = make(map[string]any)
 	}
 	commentsm[dependenciesKey] = b.dependenciesComments
 	commentsm[devDependenciesKey] = b.devDependenciesComments
@@ -148,10 +148,10 @@ func Pack(fs afero.Fs, fis []hugofs.FileMetaInfo) error {
 
 func newPackageBuilder(source string, first io.Reader) *packageBuilder {
 	b := &packageBuilder{
-		devDependencies:         make(map[string]interface{}),
-		devDependenciesComments: make(map[string]interface{}),
-		dependencies:            make(map[string]interface{}),
-		dependenciesComments:    make(map[string]interface{}),
+		devDependencies:         make(map[string]any),
+		devDependenciesComments: make(map[string]any),
+		dependencies:            make(map[string]any),
+		dependenciesComments:    make(map[string]any),
 	}
 
 	m := b.unmarshal(first)
@@ -169,12 +169,12 @@ type packageBuilder struct {
 	err error
 
 	// The original package.hugo.json.
-	originalPackageJSON map[string]interface{}
+	originalPackageJSON map[string]any
 
-	devDependencies         map[string]interface{}
-	devDependenciesComments map[string]interface{}
-	dependencies            map[string]interface{}
-	dependenciesComments    map[string]interface{}
+	devDependencies         map[string]any
+	devDependenciesComments map[string]any
+	dependencies            map[string]any
+	dependenciesComments    map[string]any
 }
 
 func (b *packageBuilder) Add(source string, r io.Reader) *packageBuilder {
@@ -192,7 +192,7 @@ func (b *packageBuilder) Add(source string, r io.Reader) *packageBuilder {
 	return b
 }
 
-func (b *packageBuilder) addm(source string, m map[string]interface{}) {
+func (b *packageBuilder) addm(source string, m map[string]any) {
 	if source == "" {
 		source = "project"
 	}
@@ -225,8 +225,8 @@ func (b *packageBuilder) addm(source string, m map[string]interface{}) {
 	}
 }
 
-func (b *packageBuilder) unmarshal(r io.Reader) map[string]interface{} {
-	m := make(map[string]interface{})
+func (b *packageBuilder) unmarshal(r io.Reader) map[string]any {
+	m := make(map[string]any)
 	err := json.Unmarshal(helpers.ReaderToBytes(r), &m)
 	if err != nil {
 		b.err = err
diff --git a/modules/npm/package_builder_test.go b/modules/npm/package_builder_test.go
@@ -73,7 +73,7 @@ func TestPackageBuilder(t *testing.T) {
 
 	c.Assert(b.Err(), qt.IsNil)
 
-	c.Assert(b.dependencies, qt.DeepEquals, map[string]interface{}{
+	c.Assert(b.dependencies, qt.DeepEquals, map[string]any{
 		"@babel/cli":        "7.8.4",
 		"add1":              "1.1.1",
 		"add3":              "3.1.1",
@@ -83,7 +83,7 @@ func TestPackageBuilder(t *testing.T) {
 		"tailwindcss":       "1.2.0",
 	})
 
-	c.Assert(b.devDependencies, qt.DeepEquals, map[string]interface{}{
+	c.Assert(b.devDependencies, qt.DeepEquals, map[string]any{
 		"tailwindcss":       "1.2.0",
 		"@babel/cli":        "7.8.4",
 		"@babel/core":       "7.9.0",
diff --git a/navigation/menu.go b/navigation/menu.go
@@ -73,7 +73,7 @@ type Page interface {
 	Weight() int
 	IsPage() bool
 	IsSection() bool
-	IsAncestor(other interface{}) (bool, error)
+	IsAncestor(other any) (bool, error)
 	Params() maps.Params
 }
 
@@ -131,7 +131,7 @@ func (m *MenuEntry) isSamePage(p Page) bool {
 	return false
 }
 
-func (m *MenuEntry) MarshallMap(ime map[string]interface{}) error {
+func (m *MenuEntry) MarshallMap(ime map[string]any) error {
 	var err error
 	for k, v := range ime {
 		loki := strings.ToLower(k)
diff --git a/output/docshelper.go b/output/docshelper.go
@@ -12,7 +12,7 @@ import (
 func init() {
 	docsProvider := func() docshelper.DocProvider {
 		return docshelper.DocProvider{
-			"output": map[string]interface{}{
+			"output": map[string]any{
 				"formats": DefaultFormats,
 				"layouts": createLayoutExamples(),
 			},
@@ -22,7 +22,7 @@ func init() {
 	docshelper.AddDocProviderFunc(docsProvider)
 }
 
-func createLayoutExamples() interface{} {
+func createLayoutExamples() any {
 	type Example struct {
 		Example      string
 		Kind         string
diff --git a/output/outputFormat.go b/output/outputFormat.go
@@ -292,7 +292,7 @@ func (formats Formats) FromFilename(filename string) (f Format, found bool) {
 
 // DecodeFormats takes a list of output format configurations and merges those,
 // in the order given, with the Hugo defaults as the last resort.
-func DecodeFormats(mediaTypes media.Types, maps ...map[string]interface{}) (Formats, error) {
+func DecodeFormats(mediaTypes media.Types, maps ...map[string]any) (Formats, error) {
 	f := make(Formats, len(DefaultFormats))
 	copy(f, DefaultFormats)
 
@@ -334,12 +334,12 @@ func DecodeFormats(mediaTypes media.Types, maps ...map[string]interface{}) (Form
 	return f, nil
 }
 
-func decode(mediaTypes media.Types, input interface{}, output *Format) error {
+func decode(mediaTypes media.Types, input any, output *Format) error {
 	config := &mapstructure.DecoderConfig{
 		Metadata:         nil,
 		Result:           output,
 		WeaklyTypedInput: true,
-		DecodeHook: func(a reflect.Type, b reflect.Type, c interface{}) (interface{}, error) {
+		DecodeHook: func(a reflect.Type, b reflect.Type, c any) (any, error) {
 			if a.Kind() == reflect.Map {
 				dataVal := reflect.Indirect(reflect.ValueOf(c))
 				for _, key := range dataVal.MapKeys() {
diff --git a/output/outputFormat_test.go b/output/outputFormat_test.go
@@ -145,15 +145,15 @@ func TestDecodeFormats(t *testing.T) {
 
 	tests := []struct {
 		name        string
-		maps        []map[string]interface{}
+		maps        []map[string]any
 		shouldError bool
 		assert      func(t *testing.T, name string, f Formats)
 	}{
 		{
 			"Redefine JSON",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"JsON": map[string]interface{}{
+					"JsON": map[string]any{
 						"baseName":    "myindex",
 						"isPlainText": "false",
 					},
@@ -171,9 +171,9 @@ func TestDecodeFormats(t *testing.T) {
 		},
 		{
 			"Add XML format with string as mediatype",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"MYXMLFORMAT": map[string]interface{}{
+					"MYXMLFORMAT": map[string]any{
 						"baseName":  "myxml",
 						"mediaType": "application/xml",
 					},
@@ -194,9 +194,9 @@ func TestDecodeFormats(t *testing.T) {
 		},
 		{
 			"Add format unknown mediatype",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"MYINVALID": map[string]interface{}{
+					"MYINVALID": map[string]any{
 						"baseName":  "mymy",
 						"mediaType": "application/hugo",
 					},
@@ -208,15 +208,15 @@ func TestDecodeFormats(t *testing.T) {
 		},
 		{
 			"Add and redefine XML format",
-			[]map[string]interface{}{
+			[]map[string]any{
 				{
-					"MYOTHERXMLFORMAT": map[string]interface{}{
+					"MYOTHERXMLFORMAT": map[string]any{
 						"baseName":  "myotherxml",
 						"mediaType": media.XMLType,
 					},
 				},
 				{
-					"MYOTHERXMLFORMAT": map[string]interface{}{
+					"MYOTHERXMLFORMAT": map[string]any{
 						"baseName": "myredefined",
 					},
 				},
diff --git a/parser/frontmatter.go b/parser/frontmatter.go
@@ -32,7 +32,7 @@ const (
 	tomlDelimLf = "+++\n"
 )
 
-func InterfaceToConfig(in interface{}, format metadecoders.Format, w io.Writer) error {
+func InterfaceToConfig(in any, format metadecoders.Format, w io.Writer) error {
 	if in == nil {
 		return errors.New("input was nil")
 	}
@@ -77,7 +77,7 @@ func InterfaceToConfig(in interface{}, format metadecoders.Format, w io.Writer) 
 	}
 }
 
-func InterfaceToFrontMatter(in interface{}, format metadecoders.Format, w io.Writer) error {
+func InterfaceToFrontMatter(in any, format metadecoders.Format, w io.Writer) error {
 	if in == nil {
 		return errors.New("input was nil")
 	}
diff --git a/parser/frontmatter_test.go b/parser/frontmatter_test.go
@@ -23,33 +23,33 @@ import (
 
 func TestInterfaceToConfig(t *testing.T) {
 	cases := []struct {
-		input  interface{}
+		input  any
 		format metadecoders.Format
 		want   []byte
 		isErr  bool
 	}{
 		// TOML
-		{map[string]interface{}{}, metadecoders.TOML, nil, false},
+		{map[string]any{}, metadecoders.TOML, nil, false},
 		{
-			map[string]interface{}{"title": "test' 1"},
+			map[string]any{"title": "test' 1"},
 			metadecoders.TOML,
 			[]byte("title = \"test' 1\"\n"),
 			false,
 		},
 
 		// YAML
-		{map[string]interface{}{}, metadecoders.YAML, []byte("{}\n"), false},
+		{map[string]any{}, metadecoders.YAML, []byte("{}\n"), false},
 		{
-			map[string]interface{}{"title": "test 1"},
+			map[string]any{"title": "test 1"},
 			metadecoders.YAML,
 			[]byte("title: test 1\n"),
 			false,
 		},
 
 		// JSON
-		{map[string]interface{}{}, metadecoders.JSON, []byte("{}\n"), false},
+		{map[string]any{}, metadecoders.JSON, []byte("{}\n"), false},
 		{
-			map[string]interface{}{"title": "test 1"},
+			map[string]any{"title": "test 1"},
 			metadecoders.JSON,
 			[]byte("{\n   \"title\": \"test 1\"\n}\n"),
 			false,
@@ -57,7 +57,7 @@ func TestInterfaceToConfig(t *testing.T) {
 
 		// Errors
 		{nil, metadecoders.TOML, nil, true},
-		{map[string]interface{}{}, "foo", nil, true},
+		{map[string]any{}, "foo", nil, true},
 	}
 
 	for i, c := range cases {
diff --git a/parser/lowercase_camel_json.go b/parser/lowercase_camel_json.go
@@ -29,7 +29,7 @@ var (
 
 // Code adapted from https://gist.github.com/piersy/b9934790a8892db1a603820c0c23e4a7
 type LowerCaseCamelJSONMarshaller struct {
-	Value interface{}
+	Value any
 }
 
 func (c LowerCaseCamelJSONMarshaller) MarshalJSON() ([]byte, error) {
diff --git a/parser/metadecoders/decoder.go b/parser/metadecoders/decoder.go
@@ -58,8 +58,8 @@ var Default = Decoder{
 
 // UnmarshalToMap will unmarshall data in format f into a new map. This is
 // what's needed for Hugo's front matter decoding.
-func (d Decoder) UnmarshalToMap(data []byte, f Format) (map[string]interface{}, error) {
-	m := make(map[string]interface{})
+func (d Decoder) UnmarshalToMap(data []byte, f Format) (map[string]any, error) {
+	m := make(map[string]any)
 	if data == nil {
 		return m, nil
 	}
@@ -71,7 +71,7 @@ func (d Decoder) UnmarshalToMap(data []byte, f Format) (map[string]interface{}, 
 
 // UnmarshalFileToMap is the same as UnmarshalToMap, but reads the data from
 // the given filename.
-func (d Decoder) UnmarshalFileToMap(fs afero.Fs, filename string) (map[string]interface{}, error) {
+func (d Decoder) UnmarshalFileToMap(fs afero.Fs, filename string) (map[string]any, error) {
 	format := FormatFromString(filename)
 	if format == "" {
 		return nil, errors.Errorf("%q is not a valid configuration format", filename)
@@ -85,16 +85,16 @@ func (d Decoder) UnmarshalFileToMap(fs afero.Fs, filename string) (map[string]in
 }
 
 // UnmarshalStringTo tries to unmarshal data to a new instance of type typ.
-func (d Decoder) UnmarshalStringTo(data string, typ interface{}) (interface{}, error) {
+func (d Decoder) UnmarshalStringTo(data string, typ any) (any, error) {
 	data = strings.TrimSpace(data)
 	// We only check for the possible types in YAML, JSON and TOML.
 	switch typ.(type) {
 	case string:
 		return data, nil
-	case map[string]interface{}:
+	case map[string]any:
 		format := d.FormatFromContentString(data)
 		return d.UnmarshalToMap([]byte(data), format)
-	case []interface{}:
+	case []any:
 		// A standalone slice. Let YAML handle it.
 		return d.Unmarshal([]byte(data), YAML)
 	case bool:
@@ -112,23 +112,23 @@ func (d Decoder) UnmarshalStringTo(data string, typ interface{}) (interface{}, e
 
 // Unmarshal will unmarshall data in format f into an interface{}.
 // This is what's needed for Hugo's /data handling.
-func (d Decoder) Unmarshal(data []byte, f Format) (interface{}, error) {
+func (d Decoder) Unmarshal(data []byte, f Format) (any, error) {
 	if data == nil {
 		switch f {
 		case CSV:
 			return make([][]string, 0), nil
 		default:
-			return make(map[string]interface{}), nil
+			return make(map[string]any), nil
 		}
 	}
-	var v interface{}
+	var v any
 	err := d.UnmarshalTo(data, f, &v)
 
 	return v, err
 }
 
 // UnmarshalTo unmarshals data in format f into v.
-func (d Decoder) UnmarshalTo(data []byte, f Format, v interface{}) error {
+func (d Decoder) UnmarshalTo(data []byte, f Format, v any) error {
 	var err error
 
 	switch f {
@@ -140,19 +140,19 @@ func (d Decoder) UnmarshalTo(data []byte, f Format, v interface{}) error {
 		var xmlRoot xml.Map
 		xmlRoot, err = xml.NewMapXml(data)
 
-		var xmlValue map[string]interface{}
+		var xmlValue map[string]any
 		if err == nil {
 			xmlRootName, err := xmlRoot.Root()
 			if err != nil {
 				return toFileError(f, errors.Wrap(err, "failed to unmarshal XML"))
 			}
-			xmlValue = xmlRoot[xmlRootName].(map[string]interface{})
+			xmlValue = xmlRoot[xmlRootName].(map[string]any)
 		}
 
 		switch v := v.(type) {
-		case *map[string]interface{}:
+		case *map[string]any:
 			*v = xmlValue
-		case *interface{}:
+		case *any:
 			*v = xmlValue
 		}
 	case TOML:
@@ -167,12 +167,12 @@ func (d Decoder) UnmarshalTo(data []byte, f Format, v interface{}) error {
 		// map[interface{}]interface{}. Here we recurse through the result
 		// and change all maps to map[string]interface{} like we would've
 		// gotten from `json`.
-		var ptr interface{}
+		var ptr any
 		switch v.(type) {
-		case *map[string]interface{}:
-			ptr = *v.(*map[string]interface{})
-		case *interface{}:
-			ptr = *v.(*interface{})
+		case *map[string]any:
+			ptr = *v.(*map[string]any)
+		case *any:
+			ptr = *v.(*any)
 		default:
 			// Not a map.
 		}
@@ -180,10 +180,10 @@ func (d Decoder) UnmarshalTo(data []byte, f Format, v interface{}) error {
 		if ptr != nil {
 			if mm, changed := stringifyMapKeys(ptr); changed {
 				switch v.(type) {
-				case *map[string]interface{}:
-					*v.(*map[string]interface{}) = mm.(map[string]interface{})
-				case *interface{}:
-					*v.(*interface{}) = mm
+				case *map[string]any:
+					*v.(*map[string]any) = mm.(map[string]any)
+				case *any:
+					*v.(*any) = mm
 				}
 			}
 		}
@@ -201,7 +201,7 @@ func (d Decoder) UnmarshalTo(data []byte, f Format, v interface{}) error {
 	return toFileError(f, errors.Wrap(err, "unmarshal failed"))
 }
 
-func (d Decoder) unmarshalCSV(data []byte, v interface{}) error {
+func (d Decoder) unmarshalCSV(data []byte, v any) error {
 	r := csv.NewReader(bytes.NewReader(data))
 	r.Comma = d.Delimiter
 	r.Comment = d.Comment
@@ -212,8 +212,8 @@ func (d Decoder) unmarshalCSV(data []byte, v interface{}) error {
 	}
 
 	switch v.(type) {
-	case *interface{}:
-		*v.(*interface{}) = records
+	case *any:
+		*v.(*any) = records
 	default:
 		return errors.Errorf("CSV cannot be unmarshaled into %T", v)
 
@@ -230,14 +230,14 @@ func parseORGDate(s string) string {
 	return s
 }
 
-func (d Decoder) unmarshalORG(data []byte, v interface{}) error {
+func (d Decoder) unmarshalORG(data []byte, v any) error {
 	config := org.New()
 	config.Log = jww.WARN
 	document := config.Parse(bytes.NewReader(data), "")
 	if document.Error != nil {
 		return document.Error
 	}
-	frontMatter := make(map[string]interface{}, len(document.BufferSettings))
+	frontMatter := make(map[string]any, len(document.BufferSettings))
 	for k, v := range document.BufferSettings {
 		k = strings.ToLower(k)
 		if strings.HasSuffix(k, "[]") {
@@ -252,10 +252,10 @@ func (d Decoder) unmarshalORG(data []byte, v interface{}) error {
 		}
 	}
 	switch v.(type) {
-	case *map[string]interface{}:
-		*v.(*map[string]interface{}) = frontMatter
+	case *map[string]any:
+		*v.(*map[string]any) = frontMatter
 	default:
-		*v.(*interface{}) = frontMatter
+		*v.(*any) = frontMatter
 	}
 	return nil
 }
@@ -270,22 +270,22 @@ func toFileError(f Format, err error) error {
 // described here: https://github.com/go-yaml/yaml/issues/139
 //
 // Inspired by https://github.com/stripe/stripe-mock, MIT licensed
-func stringifyMapKeys(in interface{}) (interface{}, bool) {
+func stringifyMapKeys(in any) (any, bool) {
 	switch in := in.(type) {
-	case []interface{}:
+	case []any:
 		for i, v := range in {
 			if vv, replaced := stringifyMapKeys(v); replaced {
 				in[i] = vv
 			}
 		}
-	case map[string]interface{}:
+	case map[string]any:
 		for k, v := range in {
 			if vv, changed := stringifyMapKeys(v); changed {
 				in[k] = vv
 			}
 		}
-	case map[interface{}]interface{}:
-		res := make(map[string]interface{})
+	case map[any]any:
+		res := make(map[string]any)
 		var (
 			ok  bool
 			err error
diff --git a/parser/metadecoders/decoder_test.go b/parser/metadecoders/decoder_test.go
@@ -45,13 +45,13 @@ func TestUnmarshalXML(t *testing.T) {
 		</channel>
 	</rss>`
 
-	expect := map[string]interface{}{
+	expect := map[string]any{
 		"-atom": "http://www.w3.org/2005/Atom", "-version": "2.0",
-		"channel": map[string]interface{}{
+		"channel": map[string]any{
 			"copyright":   "Example",
 			"description": "Example feed",
 			"generator":   "Hugo -- gohugo.io",
-			"item": map[string]interface{}{
+			"item": map[string]any{
 				"description": "Example description",
 				"guid":        "https://example.com/2021/11/30/example-title/",
 				"link":        "https://example.com/2021/11/30/example-title/",
@@ -59,7 +59,7 @@ func TestUnmarshalXML(t *testing.T) {
 				"title":       "Example title"},
 			"language":      "en-us",
 			"lastBuildDate": "Fri, 08 Jan 2021 14:44:10 +0000",
-			"link": []interface{}{"https://example.com/", map[string]interface{}{
+			"link": []any{"https://example.com/", map[string]any{
 				"-href": "https://example.com/feed.xml",
 				"-rel":  "self",
 				"-type": "application/rss+xml"}},
@@ -76,20 +76,20 @@ func TestUnmarshalXML(t *testing.T) {
 func TestUnmarshalToMap(t *testing.T) {
 	c := qt.New(t)
 
-	expect := map[string]interface{}{"a": "b"}
+	expect := map[string]any{"a": "b"}
 
 	d := Default
 
 	for i, test := range []struct {
 		data   string
 		format Format
-		expect interface{}
+		expect any
 	}{
 		{`a = "b"`, TOML, expect},
 		{`a: "b"`, YAML, expect},
 		// Make sure we get all string keys, even for YAML
-		{"a: Easy!\nb:\n  c: 2\n  d: [3, 4]", YAML, map[string]interface{}{"a": "Easy!", "b": map[string]interface{}{"c": 2, "d": []interface{}{3, 4}}}},
-		{"a:\n  true: 1\n  false: 2", YAML, map[string]interface{}{"a": map[string]interface{}{"true": 1, "false": 2}}},
+		{"a: Easy!\nb:\n  c: 2\n  d: [3, 4]", YAML, map[string]any{"a": "Easy!", "b": map[string]any{"c": 2, "d": []any{3, 4}}}},
+		{"a:\n  true: 1\n  false: 2", YAML, map[string]any{"a": map[string]any{"true": 1, "false": 2}}},
 		{`{ "a": "b" }`, JSON, expect},
 		{`<root><a>b</a></root>`, XML, expect},
 		{`#+a: b`, ORG, expect},
@@ -111,24 +111,24 @@ func TestUnmarshalToMap(t *testing.T) {
 func TestUnmarshalToInterface(t *testing.T) {
 	c := qt.New(t)
 
-	expect := map[string]interface{}{"a": "b"}
+	expect := map[string]any{"a": "b"}
 
 	d := Default
 
 	for i, test := range []struct {
 		data   string
 		format Format
-		expect interface{}
+		expect any
 	}{
-		{`[ "Brecker", "Blake", "Redman" ]`, JSON, []interface{}{"Brecker", "Blake", "Redman"}},
+		{`[ "Brecker", "Blake", "Redman" ]`, JSON, []any{"Brecker", "Blake", "Redman"}},
 		{`{ "a": "b" }`, JSON, expect},
 		{`#+a: b`, ORG, expect},
-		{`#+DATE: <2020-06-26 Fri>`, ORG, map[string]interface{}{"date": "2020-06-26"}},
+		{`#+DATE: <2020-06-26 Fri>`, ORG, map[string]any{"date": "2020-06-26"}},
 		{`a = "b"`, TOML, expect},
 		{`a: "b"`, YAML, expect},
 		{`<root><a>b</a></root>`, XML, expect},
 		{`a,b,c`, CSV, [][]string{{"a", "b", "c"}}},
-		{"a: Easy!\nb:\n  c: 2\n  d: [3, 4]", YAML, map[string]interface{}{"a": "Easy!", "b": map[string]interface{}{"c": 2, "d": []interface{}{3, 4}}}},
+		{"a: Easy!\nb:\n  c: 2\n  d: [3, 4]", YAML, map[string]any{"a": "Easy!", "b": map[string]any{"c": 2, "d": []any{3, 4}}}},
 		// errors
 		{`a = "`, TOML, false},
 	} {
@@ -149,20 +149,20 @@ func TestUnmarshalStringTo(t *testing.T) {
 
 	d := Default
 
-	expectMap := map[string]interface{}{"a": "b"}
+	expectMap := map[string]any{"a": "b"}
 
 	for i, test := range []struct {
 		data   string
-		to     interface{}
-		expect interface{}
+		to     any
+		expect any
 	}{
 		{"a string", "string", "a string"},
-		{`{ "a": "b" }`, make(map[string]interface{}), expectMap},
+		{`{ "a": "b" }`, make(map[string]any), expectMap},
 		{"32", int64(1234), int64(32)},
 		{"32", int(1234), int(32)},
 		{"3.14159", float64(1), float64(3.14159)},
-		{"[3,7,9]", []interface{}{}, []interface{}{3, 7, 9}},
-		{"[3.1,7.2,9.3]", []interface{}{}, []interface{}{3.1, 7.2, 9.3}},
+		{"[3,7,9]", []any{}, []any{3, 7, 9}},
+		{"[3.1,7.2,9.3]", []any{}, []any{3.1, 7.2, 9.3}},
 	} {
 		msg := qt.Commentf("%d: %T", i, test.to)
 		m, err := d.UnmarshalStringTo(test.data, test.to)
@@ -178,43 +178,43 @@ func TestUnmarshalStringTo(t *testing.T) {
 
 func TestStringifyYAMLMapKeys(t *testing.T) {
 	cases := []struct {
-		input    interface{}
-		want     interface{}
+		input    any
+		want     any
 		replaced bool
 	}{
 		{
-			map[interface{}]interface{}{"a": 1, "b": 2},
-			map[string]interface{}{"a": 1, "b": 2},
+			map[any]any{"a": 1, "b": 2},
+			map[string]any{"a": 1, "b": 2},
 			true,
 		},
 		{
-			map[interface{}]interface{}{"a": []interface{}{1, map[interface{}]interface{}{"b": 2}}},
-			map[string]interface{}{"a": []interface{}{1, map[string]interface{}{"b": 2}}},
+			map[any]any{"a": []any{1, map[any]any{"b": 2}}},
+			map[string]any{"a": []any{1, map[string]any{"b": 2}}},
 			true,
 		},
 		{
-			map[interface{}]interface{}{true: 1, "b": false},
-			map[string]interface{}{"true": 1, "b": false},
+			map[any]any{true: 1, "b": false},
+			map[string]any{"true": 1, "b": false},
 			true,
 		},
 		{
-			map[interface{}]interface{}{1: "a", 2: "b"},
-			map[string]interface{}{"1": "a", "2": "b"},
+			map[any]any{1: "a", 2: "b"},
+			map[string]any{"1": "a", "2": "b"},
 			true,
 		},
 		{
-			map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": 1}},
-			map[string]interface{}{"a": map[string]interface{}{"b": 1}},
+			map[any]any{"a": map[any]any{"b": 1}},
+			map[string]any{"a": map[string]any{"b": 1}},
 			true,
 		},
 		{
-			map[string]interface{}{"a": map[string]interface{}{"b": 1}},
-			map[string]interface{}{"a": map[string]interface{}{"b": 1}},
+			map[string]any{"a": map[string]any{"b": 1}},
+			map[string]any{"a": map[string]any{"b": 1}},
 			false,
 		},
 		{
-			[]interface{}{map[interface{}]interface{}{1: "a", 2: "b"}},
-			[]interface{}{map[string]interface{}{"1": "a", "2": "b"}},
+			[]any{map[any]any{1: "a", 2: "b"}},
+			[]any{map[string]any{"1": "a", "2": "b"}},
 			false,
 		},
 	}
@@ -235,18 +235,18 @@ func TestStringifyYAMLMapKeys(t *testing.T) {
 }
 
 func BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps(b *testing.B) {
-	maps := make([]map[interface{}]interface{}, b.N)
+	maps := make([]map[any]any, b.N)
 	for i := 0; i < b.N; i++ {
-		maps[i] = map[interface{}]interface{}{
-			"a": map[interface{}]interface{}{
+		maps[i] = map[any]any{
+			"a": map[any]any{
 				"b": 32,
 				"c": 43,
-				"d": map[interface{}]interface{}{
+				"d": map[any]any{
 					"b": 32,
 					"c": 43,
 				},
 			},
-			"b": []interface{}{"a", "b"},
+			"b": []any{"a", "b"},
 			"c": "d",
 		}
 	}
@@ -257,16 +257,16 @@ func BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps(b *testing.B) {
 }
 
 func BenchmarkStringifyMapKeysStringsOnlyStringMaps(b *testing.B) {
-	m := map[string]interface{}{
-		"a": map[string]interface{}{
+	m := map[string]any{
+		"a": map[string]any{
 			"b": 32,
 			"c": 43,
-			"d": map[string]interface{}{
+			"d": map[string]any{
 				"b": 32,
 				"c": 43,
 			},
 		},
-		"b": []interface{}{"a", "b"},
+		"b": []any{"a", "b"},
 		"c": "d",
 	}
 
@@ -277,18 +277,18 @@ func BenchmarkStringifyMapKeysStringsOnlyStringMaps(b *testing.B) {
 }
 
 func BenchmarkStringifyMapKeysIntegers(b *testing.B) {
-	maps := make([]map[interface{}]interface{}, b.N)
+	maps := make([]map[any]any, b.N)
 	for i := 0; i < b.N; i++ {
-		maps[i] = map[interface{}]interface{}{
-			1: map[interface{}]interface{}{
+		maps[i] = map[any]any{
+			1: map[any]any{
 				4: 32,
 				5: 43,
-				6: map[interface{}]interface{}{
+				6: map[any]any{
 					7: 32,
 					8: 43,
 				},
 			},
-			2: []interface{}{"a", "b"},
+			2: []any{"a", "b"},
 			3: "d",
 		}
 	}
diff --git a/parser/metadecoders/format_test.go b/parser/metadecoders/format_test.go
@@ -64,7 +64,7 @@ func TestFormatFromContentString(t *testing.T) {
 
 	for i, test := range []struct {
 		data   string
-		expect interface{}
+		expect any
 	}{
 		{`foo = "bar"`, TOML},
 		{`   foo = "bar"`, TOML},
diff --git a/parser/pageparser/item.go b/parser/pageparser/item.go
@@ -33,7 +33,7 @@ func (i Item) ValStr() string {
 	return string(i.Val)
 }
 
-func (i Item) ValTyped() interface{} {
+func (i Item) ValTyped() any {
 	str := i.ValStr()
 	if i.isString {
 		// A quoted value that is a string even if it looks like a number etc.
diff --git a/parser/pageparser/pagelexer.go b/parser/pageparser/pagelexer.go
@@ -176,7 +176,7 @@ func (l *pageLexer) ignore() {
 var lf = []byte("\n")
 
 // nil terminates the parser
-func (l *pageLexer) errorf(format string, args ...interface{}) stateFunc {
+func (l *pageLexer) errorf(format string, args ...any) stateFunc {
 	l.items = append(l.items, Item{tError, l.start, []byte(fmt.Sprintf(format, args...)), true})
 	return nil
 }
diff --git a/parser/pageparser/pageparser.go b/parser/pageparser/pageparser.go
@@ -42,7 +42,7 @@ func Parse(r io.Reader, cfg Config) (Result, error) {
 
 type ContentFrontMatter struct {
 	Content           []byte
-	FrontMatter       map[string]interface{}
+	FrontMatter       map[string]any
 	FrontMatterFormat metadecoders.Format
 }
 
diff --git a/related/inverted_index.go b/related/inverted_index.go
@@ -262,7 +262,7 @@ func (idx *InvertedIndex) SearchDoc(doc Document, indices ...string) ([]Document
 }
 
 // ToKeywords returns a Keyword slice of the given input.
-func (cfg IndexConfig) ToKeywords(v interface{}) ([]Keyword, error) {
+func (cfg IndexConfig) ToKeywords(v any) ([]Keyword, error) {
 	var (
 		keywords []Keyword
 		toLower  = cfg.ToLower
diff --git a/releaser/github.go b/releaser/github.go
@@ -114,7 +114,7 @@ func (g *gitHubAPI) fetchRepo() (gitHubRepo, error) {
 	return repo, err
 }
 
-func doGitHubRequest(req *http.Request, v interface{}) error {
+func doGitHubRequest(req *http.Request, v any) error {
 	addGitHubToken(req)
 
 	resp, err := http.DefaultClient.Do(req)
diff --git a/resources/errorResource.go b/resources/errorResource.go
@@ -56,7 +56,7 @@ func (e *errorResource) ReadSeekCloser() (hugio.ReadSeekCloser, error) {
 	panic(e.error)
 }
 
-func (e *errorResource) Content() (interface{}, error) {
+func (e *errorResource) Content() (any, error) {
 	panic(e.error)
 }
 
@@ -88,7 +88,7 @@ func (e *errorResource) Params() maps.Params {
 	panic(e.error)
 }
 
-func (e *errorResource) Data() interface{} {
+func (e *errorResource) Data() any {
 	panic(e.error)
 }
 
@@ -116,7 +116,7 @@ func (e *errorResource) Resize(spec string) (resource.Image, error) {
 	panic(e.error)
 }
 
-func (e *errorResource) Filter(filters ...interface{}) (resource.Image, error) {
+func (e *errorResource) Filter(filters ...any) (resource.Image, error) {
 	panic(e.error)
 }
 
diff --git a/resources/image.go b/resources/image.go
@@ -238,7 +238,7 @@ func (i *imageResource) Fill(spec string) (resource.Image, error) {
 	return img, err
 }
 
-func (i *imageResource) Filter(filters ...interface{}) (resource.Image, error) {
+func (i *imageResource) Filter(filters ...any) (resource.Image, error) {
 	conf := images.GetDefaultImageConfig("filter", i.Proc.Cfg)
 
 	var gfilters []gift.Filter
diff --git a/resources/image_extended_test.go b/resources/image_extended_test.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build extended
 // +build extended
 
 package resources
diff --git a/resources/image_test.go b/resources/image_test.go
@@ -351,7 +351,7 @@ func TestImageWithMetadata(t *testing.T) {
 
 	image := fetchSunset(c)
 
-	meta := []map[string]interface{}{
+	meta := []map[string]any{
 		{
 			"title": "My Sunset",
 			"name":  "Sunset #:counter",
@@ -694,7 +694,7 @@ func TestImageOperationsGolden(t *testing.T) {
 			f.Overlay(gopher.(images.ImageSource), 20, 30),
 			f.Text("No options"),
 			f.Text("This long text is to test line breaks. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."),
-			f.Text("Hugo rocks!", map[string]interface{}{"x": 3, "y": 3, "size": 20, "color": "#fc03b1"}),
+			f.Text("Hugo rocks!", map[string]any{"x": 3, "y": 3, "size": 20, "color": "#fc03b1"}),
 		}
 
 		resized, err := orig.Fill("400x200 center")
diff --git a/resources/images/color_test.go b/resources/images/color_test.go
@@ -25,7 +25,7 @@ func TestHexStringToColor(t *testing.T) {
 
 	for _, test := range []struct {
 		arg    string
-		expect interface{}
+		expect any
 	}{
 		{"f", false},
 		{"#f", false},
diff --git a/resources/images/config.go b/resources/images/config.go
@@ -131,9 +131,9 @@ var defaultImaging = Imaging{
 	Quality:        defaultJPEGQuality,
 }
 
-func DecodeConfig(m map[string]interface{}) (ImagingConfig, error) {
+func DecodeConfig(m map[string]any) (ImagingConfig, error) {
 	if m == nil {
-		m = make(map[string]interface{})
+		m = make(map[string]any)
 	}
 
 	i := ImagingConfig{
diff --git a/resources/images/config_test.go b/resources/images/config_test.go
@@ -23,7 +23,7 @@ import (
 
 func TestDecodeConfig(t *testing.T) {
 	c := qt.New(t)
-	m := map[string]interface{}{
+	m := map[string]any{
 		"quality":        42,
 		"resampleFilter": "NearestNeighbor",
 		"anchor":         "topLeft",
@@ -37,7 +37,7 @@ func TestDecodeConfig(t *testing.T) {
 	c.Assert(imaging.ResampleFilter, qt.Equals, "nearestneighbor")
 	c.Assert(imaging.Anchor, qt.Equals, "topleft")
 
-	m = map[string]interface{}{}
+	m = map[string]any{}
 
 	imagingConfig, err = DecodeConfig(m)
 	c.Assert(err, qt.IsNil)
@@ -45,30 +45,30 @@ func TestDecodeConfig(t *testing.T) {
 	c.Assert(imaging.ResampleFilter, qt.Equals, "box")
 	c.Assert(imaging.Anchor, qt.Equals, "smart")
 
-	_, err = DecodeConfig(map[string]interface{}{
+	_, err = DecodeConfig(map[string]any{
 		"quality": 123,
 	})
 	c.Assert(err, qt.Not(qt.IsNil))
 
-	_, err = DecodeConfig(map[string]interface{}{
+	_, err = DecodeConfig(map[string]any{
 		"resampleFilter": "asdf",
 	})
 	c.Assert(err, qt.Not(qt.IsNil))
 
-	_, err = DecodeConfig(map[string]interface{}{
+	_, err = DecodeConfig(map[string]any{
 		"anchor": "asdf",
 	})
 	c.Assert(err, qt.Not(qt.IsNil))
 
-	imagingConfig, err = DecodeConfig(map[string]interface{}{
+	imagingConfig, err = DecodeConfig(map[string]any{
 		"anchor": "Smart",
 	})
 	imaging = imagingConfig.Cfg
 	c.Assert(err, qt.IsNil)
 	c.Assert(imaging.Anchor, qt.Equals, "smart")
 
-	imagingConfig, err = DecodeConfig(map[string]interface{}{
-		"exif": map[string]interface{}{
+	imagingConfig, err = DecodeConfig(map[string]any{
+		"exif": map[string]any{
 			"disableLatLong": true,
 		},
 	})
@@ -81,7 +81,7 @@ func TestDecodeConfig(t *testing.T) {
 func TestDecodeImageConfig(t *testing.T) {
 	for i, this := range []struct {
 		in     string
-		expect interface{}
+		expect any
 	}{
 		{"300x400", newImageConfig(300, 400, 75, 0, "box", "smart", "")},
 		{"300x400 #fff", newImageConfig(300, 400, 75, 0, "box", "smart", "fff")},
diff --git a/resources/images/exif/exif.go b/resources/images/exif/exif.go
@@ -134,7 +134,7 @@ func (d *Decoder) Decode(r io.Reader) (ex *Exif, err error) {
 		lat, long, _ = x.LatLong()
 	}
 
-	walker := &exifWalker{x: x, vals: make(map[string]interface{}), includeMatcher: d.includeFieldsRe, excludeMatcher: d.excludeFieldsrRe}
+	walker := &exifWalker{x: x, vals: make(map[string]any), includeMatcher: d.includeFieldsRe, excludeMatcher: d.excludeFieldsrRe}
 	if err = x.Walk(walker); err != nil {
 		return
 	}
@@ -144,7 +144,7 @@ func (d *Decoder) Decode(r io.Reader) (ex *Exif, err error) {
 	return
 }
 
-func decodeTag(x *_exif.Exif, f _exif.FieldName, t *tiff.Tag) (interface{}, error) {
+func decodeTag(x *_exif.Exif, f _exif.FieldName, t *tiff.Tag) (any, error) {
 	switch t.Format() {
 	case tiff.StringVal, tiff.UndefVal:
 		s := nullString(t.Val)
@@ -158,7 +158,7 @@ func decodeTag(x *_exif.Exif, f _exif.FieldName, t *tiff.Tag) (interface{}, erro
 		return "unknown", nil
 	}
 
-	var rv []interface{}
+	var rv []any
 
 	for i := 0; i < int(t.Count); i++ {
 		switch t.Format() {
@@ -203,7 +203,7 @@ func tryParseDate(x *_exif.Exif, s string) (time.Time, error) {
 
 type exifWalker struct {
 	x              *_exif.Exif
-	vals           map[string]interface{}
+	vals           map[string]any
 	includeMatcher *regexp.Regexp
 	excludeMatcher *regexp.Regexp
 }
@@ -246,10 +246,10 @@ func init() {
 	}
 }
 
-type Tags map[string]interface{}
+type Tags map[string]any
 
 func (v *Tags) UnmarshalJSON(b []byte) error {
-	vv := make(map[string]interface{})
+	vv := make(map[string]any)
 	if err := tcodec.Unmarshal(b, &vv); err != nil {
 		return err
 	}
diff --git a/resources/images/filters.go b/resources/images/filters.go
@@ -32,7 +32,7 @@ type Filters struct {
 }
 
 // Overlay creates a filter that overlays src at position x y.
-func (*Filters) Overlay(src ImageSource, x, y interface{}) gift.Filter {
+func (*Filters) Overlay(src ImageSource, x, y any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(src.Key(), x, y),
 		Filter:  overlayFilter{src: src, x: cast.ToInt(x), y: cast.ToInt(y)},
@@ -40,7 +40,7 @@ func (*Filters) Overlay(src ImageSource, x, y interface{}) gift.Filter {
 }
 
 // Text creates a filter that draws text with the given options.
-func (*Filters) Text(text string, options ...interface{}) gift.Filter {
+func (*Filters) Text(text string, options ...any) gift.Filter {
 	tf := textFilter{
 		text:        text,
 		color:       "#ffffff",
@@ -95,7 +95,7 @@ func (*Filters) Text(text string, options ...interface{}) gift.Filter {
 
 // Brightness creates a filter that changes the brightness of an image.
 // The percentage parameter must be in range (-100, 100).
-func (*Filters) Brightness(percentage interface{}) gift.Filter {
+func (*Filters) Brightness(percentage any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(percentage),
 		Filter:  gift.Brightness(cast.ToFloat32(percentage)),
@@ -104,7 +104,7 @@ func (*Filters) Brightness(percentage interface{}) gift.Filter {
 
 // ColorBalance creates a filter that changes the color balance of an image.
 // The percentage parameters for each color channel (red, green, blue) must be in range (-100, 500).
-func (*Filters) ColorBalance(percentageRed, percentageGreen, percentageBlue interface{}) gift.Filter {
+func (*Filters) ColorBalance(percentageRed, percentageGreen, percentageBlue any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(percentageRed, percentageGreen, percentageBlue),
 		Filter:  gift.ColorBalance(cast.ToFloat32(percentageRed), cast.ToFloat32(percentageGreen), cast.ToFloat32(percentageBlue)),
@@ -115,7 +115,7 @@ func (*Filters) ColorBalance(percentageRed, percentageGreen, percentageBlue inte
 // The hue parameter is the angle on the color wheel, typically in range (0, 360).
 // The saturation parameter must be in range (0, 100).
 // The percentage parameter specifies the strength of the effect, it must be in range (0, 100).
-func (*Filters) Colorize(hue, saturation, percentage interface{}) gift.Filter {
+func (*Filters) Colorize(hue, saturation, percentage any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(hue, saturation, percentage),
 		Filter:  gift.Colorize(cast.ToFloat32(hue), cast.ToFloat32(saturation), cast.ToFloat32(percentage)),
@@ -124,7 +124,7 @@ func (*Filters) Colorize(hue, saturation, percentage interface{}) gift.Filter {
 
 // Contrast creates a filter that changes the contrast of an image.
 // The percentage parameter must be in range (-100, 100).
-func (*Filters) Contrast(percentage interface{}) gift.Filter {
+func (*Filters) Contrast(percentage any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(percentage),
 		Filter:  gift.Contrast(cast.ToFloat32(percentage)),
@@ -134,7 +134,7 @@ func (*Filters) Contrast(percentage interface{}) gift.Filter {
 // Gamma creates a filter that performs a gamma correction on an image.
 // The gamma parameter must be positive. Gamma = 1 gives the original image.
 // Gamma less than 1 darkens the image and gamma greater than 1 lightens it.
-func (*Filters) Gamma(gamma interface{}) gift.Filter {
+func (*Filters) Gamma(gamma any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(gamma),
 		Filter:  gift.Gamma(cast.ToFloat32(gamma)),
@@ -142,7 +142,7 @@ func (*Filters) Gamma(gamma interface{}) gift.Filter {
 }
 
 // GaussianBlur creates a filter that applies a gaussian blur to an image.
-func (*Filters) GaussianBlur(sigma interface{}) gift.Filter {
+func (*Filters) GaussianBlur(sigma any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(sigma),
 		Filter:  gift.GaussianBlur(cast.ToFloat32(sigma)),
@@ -158,7 +158,7 @@ func (*Filters) Grayscale() gift.Filter {
 
 // Hue creates a filter that rotates the hue of an image.
 // The hue angle shift is typically in range -180 to 180.
-func (*Filters) Hue(shift interface{}) gift.Filter {
+func (*Filters) Hue(shift any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(shift),
 		Filter:  gift.Hue(cast.ToFloat32(shift)),
@@ -173,7 +173,7 @@ func (*Filters) Invert() gift.Filter {
 }
 
 // Pixelate creates a filter that applies a pixelation effect to an image.
-func (*Filters) Pixelate(size interface{}) gift.Filter {
+func (*Filters) Pixelate(size any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(size),
 		Filter:  gift.Pixelate(cast.ToInt(size)),
@@ -181,7 +181,7 @@ func (*Filters) Pixelate(size interface{}) gift.Filter {
 }
 
 // Saturation creates a filter that changes the saturation of an image.
-func (*Filters) Saturation(percentage interface{}) gift.Filter {
+func (*Filters) Saturation(percentage any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(percentage),
 		Filter:  gift.Saturation(cast.ToFloat32(percentage)),
@@ -189,7 +189,7 @@ func (*Filters) Saturation(percentage interface{}) gift.Filter {
 }
 
 // Sepia creates a filter that produces a sepia-toned version of an image.
-func (*Filters) Sepia(percentage interface{}) gift.Filter {
+func (*Filters) Sepia(percentage any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(percentage),
 		Filter:  gift.Sepia(cast.ToFloat32(percentage)),
@@ -198,7 +198,7 @@ func (*Filters) Sepia(percentage interface{}) gift.Filter {
 
 // Sigmoid creates a filter that changes the contrast of an image using a sigmoidal function and returns the adjusted image.
 // It's a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail.
-func (*Filters) Sigmoid(midpoint, factor interface{}) gift.Filter {
+func (*Filters) Sigmoid(midpoint, factor any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(midpoint, factor),
 		Filter:  gift.Sigmoid(cast.ToFloat32(midpoint), cast.ToFloat32(factor)),
@@ -210,7 +210,7 @@ func (*Filters) Sigmoid(midpoint, factor interface{}) gift.Filter {
 // Sigma must be positive. Sharpen radius roughly equals 3 * sigma.
 // The amount parameter controls how much darker and how much lighter the edge borders become. Typically between 0.5 and 1.5.
 // The threshold parameter controls the minimum brightness change that will be sharpened. Typically between 0 and 0.05.
-func (*Filters) UnsharpMask(sigma, amount, threshold interface{}) gift.Filter {
+func (*Filters) UnsharpMask(sigma, amount, threshold any) gift.Filter {
 	return filter{
 		Options: newFilterOpts(sigma, amount, threshold),
 		Filter:  gift.UnsharpMask(cast.ToFloat32(sigma), cast.ToFloat32(amount), cast.ToFloat32(threshold)),
@@ -225,10 +225,10 @@ type filter struct {
 // For cache-busting.
 type filterOpts struct {
 	Version int
-	Vals    interface{}
+	Vals    any
 }
 
-func newFilterOpts(vals ...interface{}) filterOpts {
+func newFilterOpts(vals ...any) filterOpts {
 	return filterOpts{
 		Version: filterAPIVersion,
 		Vals:    vals,
diff --git a/resources/images/image.go b/resources/images/image.go
@@ -341,7 +341,7 @@ func imageConfigFromImage(img image.Image) image.Config {
 	return image.Config{Width: b.Max.X, Height: b.Max.Y}
 }
 
-func ToFilters(in interface{}) []gift.Filter {
+func ToFilters(in any) []gift.Filter {
 	switch v := in.(type) {
 	case []gift.Filter:
 		return v
diff --git a/resources/images/webp/webp.go b/resources/images/webp/webp.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build extended
 // +build extended
 
 package webp
diff --git a/resources/images/webp/webp_notavailable.go b/resources/images/webp/webp_notavailable.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !extended
 // +build !extended
 
 package webp
diff --git a/resources/internal/key.go b/resources/internal/key.go
@@ -21,13 +21,13 @@ import "github.com/gohugoio/hugo/helpers"
 // with the target filename and a content hash of the origin to use as cache key.
 type ResourceTransformationKey struct {
 	Name     string
-	elements []interface{}
+	elements []any
 }
 
 // NewResourceTransformationKey creates a new ResourceTransformationKey from the transformation
 // name and elements. We will create a 64 bit FNV hash from the elements, which when combined
 // with the other key elements should be unique for all practical applications.
-func NewResourceTransformationKey(name string, elements ...interface{}) ResourceTransformationKey {
+func NewResourceTransformationKey(name string, elements ...any) ResourceTransformationKey {
 	return ResourceTransformationKey{Name: name, elements: elements}
 }
 
diff --git a/resources/page/page.go b/resources/page/page.go
@@ -75,7 +75,7 @@ type ChildCareProvider interface {
 
 // ContentProvider provides the content related values for a Page.
 type ContentProvider interface {
-	Content() (interface{}, error)
+	Content() (any, error)
 	Plain() string
 	PlainWords() []string
 	Summary() template.HTML
@@ -174,7 +174,7 @@ type PageMetaProvider interface {
 	IsPage() bool
 
 	// Param looks for a param in Page and then in Site config.
-	Param(key interface{}) (interface{}, error)
+	Param(key any) (any, error)
 
 	// Path gets the relative path, including file name and extension if relevant,
 	// to the source of this Page. It will be relative to any content root.
@@ -217,7 +217,7 @@ type PageMetaProvider interface {
 // PageRenderProvider provides a way for a Page to render content.
 type PageRenderProvider interface {
 	Render(layout ...string) (template.HTML, error)
-	RenderString(args ...interface{}) (template.HTML, error)
+	RenderString(args ...any) (template.HTML, error)
 }
 
 // PageWithoutContent is the Page without any of the content methods.
@@ -302,10 +302,10 @@ type RawContentProvider interface {
 
 // RefProvider provides the methods needed to create reflinks to pages.
 type RefProvider interface {
-	Ref(argsm map[string]interface{}) (string, error)
-	RefFrom(argsm map[string]interface{}, source interface{}) (string, error)
-	RelRef(argsm map[string]interface{}) (string, error)
-	RelRefFrom(argsm map[string]interface{}, source interface{}) (string, error)
+	Ref(argsm map[string]any) (string, error)
+	RefFrom(argsm map[string]any, source any) (string, error)
+	RelRef(argsm map[string]any) (string, error)
+	RelRefFrom(argsm map[string]any, source any) (string, error)
 }
 
 // RelatedKeywordsProvider allows a Page to be indexed.
@@ -352,7 +352,7 @@ type TreeProvider interface {
 
 	// IsAncestor returns whether the current page is an ancestor of the given
 	// Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
-	IsAncestor(other interface{}) (bool, error)
+	IsAncestor(other any) (bool, error)
 
 	// CurrentSection returns the page's current section or the page itself if home or a section.
 	// Note that this will return nil for pages that is not regular, home or section pages.
@@ -360,7 +360,7 @@ type TreeProvider interface {
 
 	// IsDescendant returns whether the current page is a descendant of the given
 	// Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
-	IsDescendant(other interface{}) (bool, error)
+	IsDescendant(other any) (bool, error)
 
 	// FirstSection returns the section on level 1 below home, e.g. "/docs".
 	// For the home page, this will return itself.
@@ -369,7 +369,7 @@ type TreeProvider interface {
 	// InSection returns whether the given page is in the current section.
 	// Note that this will always return false for pages that are
 	// not either regular, home or section pages.
-	InSection(other interface{}) (bool, error)
+	InSection(other any) (bool, error)
 
 	// Parent returns a section's parent section or a page's section.
 	// To get a section's subsections, see Page's Sections method.
@@ -387,9 +387,8 @@ type TreeProvider interface {
 // DeprecatedWarningPageMethods lists deprecated Page methods that will trigger
 // a WARNING if invoked.
 // This was added in Hugo 0.55.
-type DeprecatedWarningPageMethods interface { // This was emptied in Hugo 0.93.0.
-}
+type DeprecatedWarningPageMethods any // This was emptied in Hugo 0.93.0.
 
 // Move here to trigger ERROR instead of WARNING.
 // TODO(bep) create wrappers and put into the Page once it has some methods.
-type DeprecatedErrorPageMethods interface{}
+type DeprecatedErrorPageMethods any
diff --git a/resources/page/page_data.go b/resources/page/page_data.go
@@ -21,7 +21,7 @@ import (
 
 // Data represents the .Data element in a Page in Hugo. We make this
 // a type so we can do lazy loading of .Data.Pages
-type Data map[string]interface{}
+type Data map[string]any
 
 // Pages returns the pages stored with key "pages". If this is a func,
 // it will be invoked.
diff --git a/resources/page/page_lazy_contentprovider.go b/resources/page/page_lazy_contentprovider.go
@@ -48,7 +48,7 @@ func NewLazyContentProvider(f func() (OutputFormatContentProvider, error)) *Lazy
 		init: lazy.New(),
 		cp:   NopPage,
 	}
-	lcp.init.Add(func() (interface{}, error) {
+	lcp.init.Add(func() (any, error) {
 		cp, err := f()
 		if err != nil {
 			return nil, err
@@ -63,7 +63,7 @@ func (lcp *LazyContentProvider) Reset() {
 	lcp.init.Reset()
 }
 
-func (lcp *LazyContentProvider) Content() (interface{}, error) {
+func (lcp *LazyContentProvider) Content() (any, error) {
 	lcp.init.Do()
 	return lcp.cp.Content()
 }
@@ -113,7 +113,7 @@ func (lcp *LazyContentProvider) Render(layout ...string) (template.HTML, error) 
 	return lcp.cp.Render(layout...)
 }
 
-func (lcp *LazyContentProvider) RenderString(args ...interface{}) (template.HTML, error) {
+func (lcp *LazyContentProvider) RenderString(args ...any) (template.HTML, error) {
 	lcp.init.Do()
 	return lcp.cp.RenderString(args...)
 }
diff --git a/resources/page/page_marshaljson.autogen.go b/resources/page/page_marshaljson.autogen.go
@@ -92,7 +92,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
 	getIdentity := p.GetIdentity()
 
 	s := struct {
-		Content                  interface{}
+		Content                  any
 		Plain                    string
 		PlainWords               []string
 		Summary                  template.HTML
@@ -110,7 +110,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
 		Name                     string
 		Title                    string
 		Params                   maps.Params
-		Data                     interface{}
+		Data                     any
 		Date                     time.Time
 		Lastmod                  time.Time
 		PublishDate              time.Time
diff --git a/resources/page/page_matcher.go b/resources/page/page_matcher.go
@@ -71,7 +71,7 @@ func (m PageMatcher) Matches(p Page) bool {
 }
 
 // DecodeCascade decodes in which could be eiter a map or a slice of maps.
-func DecodeCascade(in interface{}) (map[PageMatcher]maps.Params, error) {
+func DecodeCascade(in any) (map[PageMatcher]maps.Params, error) {
 	m, err := maps.ToSliceStringMap(in)
 	if err != nil {
 		return map[PageMatcher]maps.Params{
@@ -106,7 +106,7 @@ func DecodeCascade(in interface{}) (map[PageMatcher]maps.Params, error) {
 }
 
 // DecodePageMatcher decodes m into v.
-func DecodePageMatcher(m interface{}, v *PageMatcher) error {
+func DecodePageMatcher(m any, v *PageMatcher) error {
 	if err := mapstructure.WeakDecode(m, v); err != nil {
 		return err
 	}
diff --git a/resources/page/page_matcher_test.go b/resources/page/page_matcher_test.go
@@ -54,13 +54,13 @@ func TestPageMatcher(t *testing.T) {
 
 	c.Run("Decode", func(c *qt.C) {
 		var v PageMatcher
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "foo"}, &v), qt.Not(qt.IsNil))
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "{foo,bar}"}, &v), qt.Not(qt.IsNil))
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "taxonomy"}, &v), qt.IsNil)
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "{taxonomy,foo}"}, &v), qt.IsNil)
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "{taxonomy,term}"}, &v), qt.IsNil)
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "*"}, &v), qt.IsNil)
-		c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "home", "path": filepath.FromSlash("/a/b/**")}, &v), qt.IsNil)
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "foo"}, &v), qt.Not(qt.IsNil))
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "{foo,bar}"}, &v), qt.Not(qt.IsNil))
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "taxonomy"}, &v), qt.IsNil)
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "{taxonomy,foo}"}, &v), qt.IsNil)
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "{taxonomy,term}"}, &v), qt.IsNil)
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "*"}, &v), qt.IsNil)
+		c.Assert(DecodePageMatcher(map[string]any{"kind": "home", "path": filepath.FromSlash("/a/b/**")}, &v), qt.IsNil)
 		c.Assert(v, qt.Equals, PageMatcher{Kind: "home", Path: "/a/b/**"})
 	})
 }
diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go
@@ -96,7 +96,7 @@ func (p *nopPage) BundleType() files.ContentClass {
 	return ""
 }
 
-func (p *nopPage) Content() (interface{}, error) {
+func (p *nopPage) Content() (any, error) {
 	return "", nil
 }
 
@@ -108,7 +108,7 @@ func (p *nopPage) CurrentSection() Page {
 	return nil
 }
 
-func (p *nopPage) Data() interface{} {
+func (p *nopPage) Data() any {
 	return nil
 }
 
@@ -120,11 +120,11 @@ func (p *nopPage) Description() string {
 	return ""
 }
 
-func (p *nopPage) RefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p *nopPage) RefFrom(argsm map[string]any, source any) (string, error) {
 	return "", nil
 }
 
-func (p *nopPage) RelRefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p *nopPage) RelRefFrom(argsm map[string]any, source any) (string, error) {
 	return "", nil
 }
 
@@ -136,7 +136,7 @@ func (p *nopPage) Draft() bool {
 	return false
 }
 
-func (p *nopPage) Eq(other interface{}) bool {
+func (p *nopPage) Eq(other any) bool {
 	return p == other
 }
 
@@ -182,7 +182,7 @@ func (p *nopPage) GetPageWithTemplateInfo(info tpl.Info, ref string) (Page, erro
 	return nil, nil
 }
 
-func (p *nopPage) GetParam(key string) interface{} {
+func (p *nopPage) GetParam(key string) any {
 	return nil
 }
 
@@ -210,15 +210,15 @@ func (p *nopPage) Hugo() (h hugo.Info) {
 	return
 }
 
-func (p *nopPage) InSection(other interface{}) (bool, error) {
+func (p *nopPage) InSection(other any) (bool, error) {
 	return false, nil
 }
 
-func (p *nopPage) IsAncestor(other interface{}) (bool, error) {
+func (p *nopPage) IsAncestor(other any) (bool, error) {
 	return false, nil
 }
 
-func (p *nopPage) IsDescendant(other interface{}) (bool, error) {
+func (p *nopPage) IsDescendant(other any) (bool, error) {
 	return false, nil
 }
 
@@ -314,15 +314,15 @@ func (p *nopPage) RegularPagesRecursive() Pages {
 	return nil
 }
 
-func (p *nopPage) Paginate(seq interface{}, options ...interface{}) (*Pager, error) {
+func (p *nopPage) Paginate(seq any, options ...any) (*Pager, error) {
 	return nil, nil
 }
 
-func (p *nopPage) Paginator(options ...interface{}) (*Pager, error) {
+func (p *nopPage) Paginator(options ...any) (*Pager, error) {
 	return nil, nil
 }
 
-func (p *nopPage) Param(key interface{}) (interface{}, error) {
+func (p *nopPage) Param(key any) (any, error) {
 	return nil, nil
 }
 
@@ -390,7 +390,7 @@ func (p *nopPage) ReadingTime() int {
 	return 0
 }
 
-func (p *nopPage) Ref(argsm map[string]interface{}) (string, error) {
+func (p *nopPage) Ref(argsm map[string]any) (string, error) {
 	return "", nil
 }
 
@@ -398,7 +398,7 @@ func (p *nopPage) RelPermalink() string {
 	return ""
 }
 
-func (p *nopPage) RelRef(argsm map[string]interface{}) (string, error) {
+func (p *nopPage) RelRef(argsm map[string]any) (string, error) {
 	return "", nil
 }
 
@@ -406,7 +406,7 @@ func (p *nopPage) Render(layout ...string) (template.HTML, error) {
 	return "", nil
 }
 
-func (p *nopPage) RenderString(args ...interface{}) (template.HTML, error) {
+func (p *nopPage) RenderString(args ...any) (template.HTML, error) {
 	return "", nil
 }
 
diff --git a/resources/page/pagegroup.go b/resources/page/pagegroup.go
@@ -39,7 +39,7 @@ var (
 // PageGroup represents a group of pages, grouped by the key.
 // The key is typically a year or similar.
 type PageGroup struct {
-	Key interface{}
+	Key any
 	Pages
 }
 
@@ -112,7 +112,7 @@ func (p Pages) GroupBy(key string, order ...string) (PagesGroup, error) {
 		direction = "desc"
 	}
 
-	var ft interface{}
+	var ft any
 	index := hreflect.GetMethodIndexByName(pagePtrType, key)
 	if index != -1 {
 		m := pagePtrType.Method(index)
@@ -347,7 +347,7 @@ func (p Pages) GroupByParamDate(key string, format string, order ...string) (Pag
 }
 
 // ProbablyEq wraps compare.ProbablyEqer
-func (p PageGroup) ProbablyEq(other interface{}) bool {
+func (p PageGroup) ProbablyEq(other any) bool {
 	otherP, ok := other.(PageGroup)
 	if !ok {
 		return false
@@ -362,11 +362,11 @@ func (p PageGroup) ProbablyEq(other interface{}) bool {
 
 // Slice is not meant to be used externally. It's a bridge function
 // for the template functions. See collections.Slice.
-func (p PageGroup) Slice(in interface{}) (interface{}, error) {
+func (p PageGroup) Slice(in any) (any, error) {
 	switch items := in.(type) {
 	case PageGroup:
 		return items, nil
-	case []interface{}:
+	case []any:
 		groups := make(PagesGroup, len(items))
 		for i, v := range items {
 			g, ok := v.(PageGroup)
@@ -391,7 +391,7 @@ func (psg PagesGroup) Len() int {
 }
 
 // ProbablyEq wraps compare.ProbablyEqer
-func (psg PagesGroup) ProbablyEq(other interface{}) bool {
+func (psg PagesGroup) ProbablyEq(other any) bool {
 	otherPsg, ok := other.(PagesGroup)
 	if !ok {
 		return false
@@ -411,7 +411,7 @@ func (psg PagesGroup) ProbablyEq(other interface{}) bool {
 }
 
 // ToPagesGroup tries to convert seq into a PagesGroup.
-func ToPagesGroup(seq interface{}) (PagesGroup, error) {
+func ToPagesGroup(seq any) (PagesGroup, error) {
 	switch v := seq.(type) {
 	case nil:
 		return nil, nil
@@ -419,7 +419,7 @@ func ToPagesGroup(seq interface{}) (PagesGroup, error) {
 		return v, nil
 	case []PageGroup:
 		return PagesGroup(v), nil
-	case []interface{}:
+	case []any:
 		l := len(v)
 		if l == 0 {
 			break
diff --git a/resources/page/pagemeta/page_frontmatter.go b/resources/page/pagemeta/page_frontmatter.go
@@ -49,7 +49,7 @@ type FrontMatterHandler struct {
 type FrontMatterDescriptor struct {
 
 	// This the Page's front matter.
-	Frontmatter map[string]interface{}
+	Frontmatter map[string]any
 
 	// This is the Page's base filename (BaseFilename), e.g. page.md., or
 	// if page is a leaf bundle, the bundle folder name (ContentBaseName).
@@ -64,7 +64,7 @@ type FrontMatterDescriptor struct {
 	// The below are pointers to values on Page and will be modified.
 
 	// This is the Page's params.
-	Params map[string]interface{}
+	Params map[string]any
 
 	// This is the Page's dates.
 	Dates *resource.Dates
@@ -253,7 +253,7 @@ func expandDefaultValues(values []string, defaults []string) []string {
 	return out
 }
 
-func toLowerSlice(in interface{}) []string {
+func toLowerSlice(in any) []string {
 	out := cast.ToStringSlice(in)
 	for i := 0; i < len(out); i++ {
 		out[i] = strings.ToLower(out[i])
@@ -335,7 +335,7 @@ func (f *FrontMatterHandler) createHandlers() error {
 	return nil
 }
 
-func setParamIfNotSet(key string, value interface{}, d *FrontMatterDescriptor) {
+func setParamIfNotSet(key string, value any, d *FrontMatterDescriptor) {
 	if _, found := d.Params[key]; found {
 		return
 	}
diff --git a/resources/page/pagemeta/page_frontmatter_test.go b/resources/page/pagemeta/page_frontmatter_test.go
@@ -63,8 +63,8 @@ func TestDateAndSlugFromBaseFilename(t *testing.T) {
 
 func newTestFd() *FrontMatterDescriptor {
 	return &FrontMatterDescriptor{
-		Frontmatter: make(map[string]interface{}),
-		Params:      make(map[string]interface{}),
+		Frontmatter: make(map[string]any),
+		Params:      make(map[string]any),
 		Dates:       &resource.Dates{},
 		PageURLs:    &URLPath{},
 		Location:    time.UTC,
@@ -76,7 +76,7 @@ func TestFrontMatterNewConfig(t *testing.T) {
 
 	cfg := config.New()
 
-	cfg.Set("frontmatter", map[string]interface{}{
+	cfg.Set("frontmatter", map[string]any{
 		"date":        []string{"publishDate", "LastMod"},
 		"Lastmod":     []string{"publishDate"},
 		"expiryDate":  []string{"lastMod"},
@@ -100,7 +100,7 @@ func TestFrontMatterNewConfig(t *testing.T) {
 	c.Assert(fc.publishDate, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "date"})
 
 	// :default keyword
-	cfg.Set("frontmatter", map[string]interface{}{
+	cfg.Set("frontmatter", map[string]any{
 		"date":        []string{"d1", ":default"},
 		"lastmod":     []string{"d2", ":default"},
 		"expiryDate":  []string{"d3", ":default"},
@@ -121,7 +121,7 @@ func TestFrontMatterDatesHandlers(t *testing.T) {
 
 		cfg := config.New()
 
-		cfg.Set("frontmatter", map[string]interface{}{
+		cfg.Set("frontmatter", map[string]any{
 			"date": []string{handlerID, "date"},
 		})
 
@@ -160,7 +160,7 @@ func TestFrontMatterDatesCustomConfig(t *testing.T) {
 	c := qt.New(t)
 
 	cfg := config.New()
-	cfg.Set("frontmatter", map[string]interface{}{
+	cfg.Set("frontmatter", map[string]any{
 		"date":        []string{"mydate"},
 		"lastmod":     []string{"publishdate"},
 		"publishdate": []string{"publishdate"},
@@ -208,7 +208,7 @@ func TestFrontMatterDatesDefaultKeyword(t *testing.T) {
 
 	cfg := config.New()
 
-	cfg.Set("frontmatter", map[string]interface{}{
+	cfg.Set("frontmatter", map[string]any{
 		"date":        []string{"mydate", ":default"},
 		"publishdate": []string{":default", "mypubdate"},
 	})
diff --git a/resources/page/pagemeta/pagemeta.go b/resources/page/pagemeta/pagemeta.go
@@ -75,7 +75,7 @@ func (b BuildConfig) IsZero() bool {
 	return !b.set
 }
 
-func DecodeBuildConfig(m interface{}) (BuildConfig, error) {
+func DecodeBuildConfig(m any) (BuildConfig, error) {
 	b := defaultBuildConfig
 	if m == nil {
 		return b, nil
diff --git a/resources/page/pagemeta/pagemeta_test.go b/resources/page/pagemeta/pagemeta_test.go
@@ -36,11 +36,11 @@ list = %s
 publishResources = true`
 
 	for _, test := range []struct {
-		args   []interface{}
+		args   []any
 		expect BuildConfig
 	}{
 		{
-			[]interface{}{"true", "true"},
+			[]any{"true", "true"},
 			BuildConfig{
 				Render:           Always,
 				List:             Always,
@@ -48,31 +48,31 @@ publishResources = true`
 				set:              true,
 			},
 		},
-		{[]interface{}{"true", "false"}, BuildConfig{
+		{[]any{"true", "false"}, BuildConfig{
 			Render:           Always,
 			List:             Never,
 			PublishResources: true,
 			set:              true,
 		}},
-		{[]interface{}{`"always"`, `"always"`}, BuildConfig{
+		{[]any{`"always"`, `"always"`}, BuildConfig{
 			Render:           Always,
 			List:             Always,
 			PublishResources: true,
 			set:              true,
 		}},
-		{[]interface{}{`"never"`, `"never"`}, BuildConfig{
+		{[]any{`"never"`, `"never"`}, BuildConfig{
 			Render:           Never,
 			List:             Never,
 			PublishResources: true,
 			set:              true,
 		}},
-		{[]interface{}{`"link"`, `"local"`}, BuildConfig{
+		{[]any{`"link"`, `"local"`}, BuildConfig{
 			Render:           Link,
 			List:             ListLocally,
 			PublishResources: true,
 			set:              true,
 		}},
-		{[]interface{}{`"always"`, `"asdfadf"`}, BuildConfig{
+		{[]any{`"always"`, `"asdfadf"`}, BuildConfig{
 			Render:           Always,
 			List:             Always,
 			PublishResources: true,
diff --git a/resources/page/pages.go b/resources/page/pages.go
@@ -52,7 +52,7 @@ func (pages Pages) ToResources() resource.Resources {
 }
 
 // ToPages tries to convert seq into Pages.
-func ToPages(seq interface{}) (Pages, error) {
+func ToPages(seq any) (Pages, error) {
 	if seq == nil {
 		return Pages{}, nil
 	}
@@ -72,7 +72,7 @@ func ToPages(seq interface{}) (Pages, error) {
 			pages[i] = vv
 		}
 		return pages, nil
-	case []interface{}:
+	case []any:
 		pages := make(Pages, len(v))
 		success := true
 		for i, vv := range v {
@@ -91,7 +91,7 @@ func ToPages(seq interface{}) (Pages, error) {
 	return nil, fmt.Errorf("cannot convert type %T to Pages", seq)
 }
 
-func (p Pages) Group(key interface{}, in interface{}) (interface{}, error) {
+func (p Pages) Group(key any, in any) (any, error) {
 	pages, err := ToPages(in)
 	if err != nil {
 		return nil, err
@@ -105,7 +105,7 @@ func (p Pages) Len() int {
 }
 
 // ProbablyEq wraps compare.ProbablyEqer
-func (pages Pages) ProbablyEq(other interface{}) bool {
+func (pages Pages) ProbablyEq(other any) bool {
 	otherPages, ok := other.(Pages)
 	if !ok {
 		return false
diff --git a/resources/page/pages_language_merge.go b/resources/page/pages_language_merge.go
@@ -22,7 +22,7 @@ var _ pagesLanguageMerger = (*Pages)(nil)
 type pagesLanguageMerger interface {
 	MergeByLanguage(other Pages) Pages
 	// Needed for integration with the tpl package.
-	MergeByLanguageInterface(other interface{}) (interface{}, error)
+	MergeByLanguageInterface(other any) (any, error)
 }
 
 // MergeByLanguage supplies missing translations in p1 with values from p2.
@@ -50,7 +50,7 @@ func (p1 Pages) MergeByLanguage(p2 Pages) Pages {
 
 // MergeByLanguageInterface is the generic version of MergeByLanguage. It
 // is here just so it can be called from the tpl package.
-func (p1 Pages) MergeByLanguageInterface(in interface{}) (interface{}, error) {
+func (p1 Pages) MergeByLanguageInterface(in any) (any, error) {
 	if in == nil {
 		return p1, nil
 	}
diff --git a/resources/page/pages_related.go b/resources/page/pages_related.go
@@ -38,7 +38,7 @@ type PageGenealogist interface {
 
 	// Template example:
 	// {{ $related := .RegularPages.RelatedIndices . "tags" "date" }}
-	RelatedIndices(doc related.Document, indices ...interface{}) (Pages, error)
+	RelatedIndices(doc related.Document, indices ...any) (Pages, error)
 
 	// Template example:
 	// {{ $related := .RegularPages.RelatedTo ( keyVals "tags" "hugo", "rocks")  ( keyVals "date" .Date ) }}
@@ -62,7 +62,7 @@ func (p Pages) Related(doc related.Document) (Pages, error) {
 
 // RelatedIndices searches the given indices with the search keywords from the
 // supplied document.
-func (p Pages) RelatedIndices(doc related.Document, indices ...interface{}) (Pages, error) {
+func (p Pages) RelatedIndices(doc related.Document, indices ...any) (Pages, error) {
 	indicesStr, err := cast.ToStringSliceE(indices)
 	if err != nil {
 		return nil, err
diff --git a/resources/page/pages_related_test.go b/resources/page/pages_related_test.go
@@ -31,21 +31,21 @@ func TestRelated(t *testing.T) {
 		&testPage{
 			title:   "Page 1",
 			pubDate: mustParseDate("2017-01-03"),
-			params: map[string]interface{}{
+			params: map[string]any{
 				"keywords": []string{"hugo", "says"},
 			},
 		},
 		&testPage{
 			title:   "Page 2",
 			pubDate: mustParseDate("2017-01-02"),
-			params: map[string]interface{}{
+			params: map[string]any{
 				"keywords": []string{"hugo", "rocks"},
 			},
 		},
 		&testPage{
 			title:   "Page 3",
 			pubDate: mustParseDate("2017-01-01"),
-			params: map[string]interface{}{
+			params: map[string]any{
 				"keywords": []string{"bep", "says"},
 			},
 		},
diff --git a/resources/page/pages_sort.go b/resources/page/pages_sort.go
@@ -322,7 +322,7 @@ func (p Pages) Reverse() Pages {
 // Adjacent invocations on the same receiver with the same paramsKey will return a cached result.
 //
 // This may safely be executed  in parallel.
-func (p Pages) ByParam(paramsKey interface{}) Pages {
+func (p Pages) ByParam(paramsKey any) Pages {
 	paramsKeyStr := cast.ToString(paramsKey)
 	key := "pageSort.ByParam." + paramsKeyStr
 
@@ -338,7 +338,7 @@ func (p Pages) ByParam(paramsKey interface{}) Pages {
 			return true
 		}
 
-		isNumeric := func(v interface{}) bool {
+		isNumeric := func(v any) bool {
 			switch v.(type) {
 			case uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64:
 				return true
diff --git a/resources/page/pages_sort_test.go b/resources/page/pages_sort_test.go
@@ -157,7 +157,7 @@ func TestPageSortReverse(t *testing.T) {
 func TestPageSortByParam(t *testing.T) {
 	t.Parallel()
 	c := qt.New(t)
-	var k interface{} = "arbitrarily.nested"
+	var k any = "arbitrarily.nested"
 
 	unsorted := createSortTestPages(10)
 	delete(unsorted[9].Params(), "arbitrarily")
@@ -188,7 +188,7 @@ func TestPageSortByParamNumeric(t *testing.T) {
 	t.Parallel()
 	c := qt.New(t)
 
-	var k interface{} = "arbitrarily.nested"
+	var k any = "arbitrarily.nested"
 
 	n := 10
 	unsorted := createSortTestPages(n)
@@ -198,8 +198,8 @@ func TestPageSortByParamNumeric(t *testing.T) {
 			v = 100.0 - i
 		}
 
-		unsorted[i].(*testPage).params = map[string]interface{}{
-			"arbitrarily": map[string]interface{}{
+		unsorted[i].(*testPage).params = map[string]any{
+			"arbitrarily": map[string]any{
 				"nested": v,
 			},
 		}
@@ -268,8 +268,8 @@ func createSortTestPages(num int) Pages {
 		p := newTestPage()
 		p.path = fmt.Sprintf("/x/y/p%d.md", i)
 		p.title = fmt.Sprintf("Title %d", i%(num+1/2))
-		p.params = map[string]interface{}{
-			"arbitrarily": map[string]interface{}{
+		p.params = map[string]any{
+			"arbitrarily": map[string]any{
 				"nested": ("xyz" + fmt.Sprintf("%v", 100-i)),
 			},
 		}
diff --git a/resources/page/pages_test.go b/resources/page/pages_test.go
@@ -56,7 +56,7 @@ func TestToPages(t *testing.T) {
 	p1, p2 := &testPage{title: "p1"}, &testPage{title: "p2"}
 	pages12 := Pages{p1, p2}
 
-	mustToPages := func(in interface{}) Pages {
+	mustToPages := func(in any) Pages {
 		p, err := ToPages(in)
 		c.Assert(err, qt.IsNil)
 		return p
@@ -65,7 +65,7 @@ func TestToPages(t *testing.T) {
 	c.Assert(mustToPages(nil), eq, Pages{})
 	c.Assert(mustToPages(pages12), eq, pages12)
 	c.Assert(mustToPages([]Page{p1, p2}), eq, pages12)
-	c.Assert(mustToPages([]interface{}{p1, p2}), eq, pages12)
+	c.Assert(mustToPages([]any{p1, p2}), eq, pages12)
 
 	_, err := ToPages("not a page")
 	c.Assert(err, qt.Not(qt.IsNil))
diff --git a/resources/page/pagination.go b/resources/page/pagination.go
@@ -27,8 +27,8 @@ import (
 
 // PaginatorProvider provides two ways to create a page paginator.
 type PaginatorProvider interface {
-	Paginator(options ...interface{}) (*Pager, error)
-	Paginate(seq interface{}, options ...interface{}) (*Pager, error)
+	Paginator(options ...any) (*Pager, error)
+	Paginate(seq any, options ...any) (*Pager, error)
 }
 
 // Pager represents one of the elements in a paginator.
@@ -207,7 +207,7 @@ func splitPages(pages Pages, size int) []paginatedElement {
 
 func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement {
 	type keyPage struct {
-		key  interface{}
+		key  any
 		page Page
 	}
 
@@ -229,7 +229,7 @@ func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement {
 
 		var (
 			pg         PagesGroup
-			key        interface{}
+			key        any
 			groupIndex = -1
 		)
 
@@ -248,7 +248,7 @@ func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement {
 	return split
 }
 
-func ResolvePagerSize(cfg config.Provider, options ...interface{}) (int, error) {
+func ResolvePagerSize(cfg config.Provider, options ...any) (int, error) {
 	if len(options) == 0 {
 		return cfg.GetInt("paginate"), nil
 	}
@@ -266,7 +266,7 @@ func ResolvePagerSize(cfg config.Provider, options ...interface{}) (int, error) 
 	return pas, nil
 }
 
-func Paginate(td TargetPathDescriptor, seq interface{}, pagerSize int) (*Paginator, error) {
+func Paginate(td TargetPathDescriptor, seq any, pagerSize int) (*Paginator, error) {
 	if pagerSize <= 0 {
 		return nil, errors.New("'paginate' configuration setting must be positive to paginate")
 	}
@@ -296,7 +296,7 @@ func Paginate(td TargetPathDescriptor, seq interface{}, pagerSize int) (*Paginat
 // It may return false positives.
 // The motivation behind this is to avoid potential costly reflect.DeepEqual
 // when "probably" is good enough.
-func probablyEqualPageLists(a1 interface{}, a2 interface{}) bool {
+func probablyEqualPageLists(a1 any, a2 any) bool {
 	if a1 == nil || a2 == nil {
 		return a1 == a2
 	}
diff --git a/resources/page/pagination_test.go b/resources/page/pagination_test.go
@@ -254,8 +254,8 @@ func TestProbablyEqualPageLists(t *testing.T) {
 	ninePagesByWeight, _ := createTestPages(9).GroupBy("Weight", "asc")
 
 	for i, this := range []struct {
-		v1     interface{}
-		v2     interface{}
+		v1     any
+		v2     any
 		expect bool
 	}{
 		{nil, nil, true},
diff --git a/resources/page/site.go b/resources/page/site.go
@@ -39,11 +39,11 @@ type Site interface {
 	Sites() Sites
 	Hugo() hugo.Info
 	BaseURL() template.URL
-	Taxonomies() interface{}
+	Taxonomies() any
 	LastChange() time.Time
 	Menus() navigation.Menus
 	Params() maps.Params
-	Data() map[string]interface{}
+	Data() map[string]any
 }
 
 // Sites represents an ordered list of sites (languages).
@@ -106,7 +106,7 @@ func (t testSite) Menus() navigation.Menus {
 	return nil
 }
 
-func (t testSite) Taxonomies() interface{} {
+func (t testSite) Taxonomies() any {
 	return nil
 }
 
@@ -118,7 +118,7 @@ func (t testSite) Params() maps.Params {
 	return nil
 }
 
-func (t testSite) Data() map[string]interface{} {
+func (t testSite) Data() map[string]any {
 	return nil
 }
 
diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go
@@ -58,8 +58,8 @@ func newTestPageWithFile(filename string) *testPage {
 	filename = filepath.FromSlash(filename)
 	file := source.NewTestFile(filename)
 	return &testPage{
-		params: make(map[string]interface{}),
-		data:   make(map[string]interface{}),
+		params: make(map[string]any),
+		data:   make(map[string]any),
 		file:   file,
 		currentSection: &testPage{
 			sectionEntries: []string{"a", "b", "c"},
@@ -111,8 +111,8 @@ type testPage struct {
 
 	weight int
 
-	params map[string]interface{}
-	data   map[string]interface{}
+	params map[string]any
+	data   map[string]any
 
 	file source.File
 
@@ -152,7 +152,7 @@ func (p *testPage) BundleType() files.ContentClass {
 	panic("not implemented")
 }
 
-func (p *testPage) Content() (interface{}, error) {
+func (p *testPage) Content() (any, error) {
 	panic("not implemented")
 }
 
@@ -164,7 +164,7 @@ func (p *testPage) CurrentSection() Page {
 	return p.currentSection
 }
 
-func (p *testPage) Data() interface{} {
+func (p *testPage) Data() any {
 	return p.data
 }
 
@@ -192,7 +192,7 @@ func (p *testPage) Draft() bool {
 	panic("not implemented")
 }
 
-func (p *testPage) Eq(other interface{}) bool {
+func (p *testPage) Eq(other any) bool {
 	return p == other
 }
 
@@ -236,7 +236,7 @@ func (p *testPage) GetPageWithTemplateInfo(info tpl.Info, ref string) (Page, err
 	panic("not implemented")
 }
 
-func (p *testPage) GetParam(key string) interface{} {
+func (p *testPage) GetParam(key string) any {
 	panic("not implemented")
 }
 
@@ -268,15 +268,15 @@ func (p *testPage) Hugo() hugo.Info {
 	panic("not implemented")
 }
 
-func (p *testPage) InSection(other interface{}) (bool, error) {
+func (p *testPage) InSection(other any) (bool, error) {
 	panic("not implemented")
 }
 
-func (p *testPage) IsAncestor(other interface{}) (bool, error) {
+func (p *testPage) IsAncestor(other any) (bool, error) {
 	panic("not implemented")
 }
 
-func (p *testPage) IsDescendant(other interface{}) (bool, error) {
+func (p *testPage) IsDescendant(other any) (bool, error) {
 	panic("not implemented")
 }
 
@@ -390,15 +390,15 @@ func (p *testPage) RegularPagesRecursive() Pages {
 	panic("not implemented")
 }
 
-func (p *testPage) Paginate(seq interface{}, options ...interface{}) (*Pager, error) {
+func (p *testPage) Paginate(seq any, options ...any) (*Pager, error) {
 	return nil, nil
 }
 
-func (p *testPage) Paginator(options ...interface{}) (*Pager, error) {
+func (p *testPage) Paginator(options ...any) (*Pager, error) {
 	return nil, nil
 }
 
-func (p *testPage) Param(key interface{}) (interface{}, error) {
+func (p *testPage) Param(key any) (any, error) {
 	return resource.Param(p, nil, key)
 }
 
@@ -462,11 +462,11 @@ func (p *testPage) ReadingTime() int {
 	panic("not implemented")
 }
 
-func (p *testPage) Ref(argsm map[string]interface{}) (string, error) {
+func (p *testPage) Ref(argsm map[string]any) (string, error) {
 	panic("not implemented")
 }
 
-func (p *testPage) RefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p *testPage) RefFrom(argsm map[string]any, source any) (string, error) {
 	return "", nil
 }
 
@@ -474,11 +474,11 @@ func (p *testPage) RelPermalink() string {
 	panic("not implemented")
 }
 
-func (p *testPage) RelRef(argsm map[string]interface{}) (string, error) {
+func (p *testPage) RelRef(argsm map[string]any) (string, error) {
 	panic("not implemented")
 }
 
-func (p *testPage) RelRefFrom(argsm map[string]interface{}, source interface{}) (string, error) {
+func (p *testPage) RelRefFrom(argsm map[string]any, source any) (string, error) {
 	return "", nil
 }
 
@@ -486,7 +486,7 @@ func (p *testPage) Render(layout ...string) (template.HTML, error) {
 	panic("not implemented")
 }
 
-func (p *testPage) RenderString(args ...interface{}) (template.HTML, error) {
+func (p *testPage) RenderString(args ...any) (template.HTML, error) {
 	panic("not implemented")
 }
 
diff --git a/resources/page/weighted.go b/resources/page/weighted.go
@@ -65,11 +65,11 @@ func (w WeightedPage) String() string {
 
 // Slice is not meant to be used externally. It's a bridge function
 // for the template functions. See collections.Slice.
-func (p WeightedPage) Slice(in interface{}) (interface{}, error) {
+func (p WeightedPage) Slice(in any) (any, error) {
 	switch items := in.(type) {
 	case WeightedPages:
 		return items, nil
-	case []interface{}:
+	case []any:
 		weighted := make(WeightedPages, len(items))
 		for i, v := range items {
 			g, ok := v.(WeightedPage)
diff --git a/resources/postpub/fields.go b/resources/postpub/fields.go
@@ -21,14 +21,14 @@ const (
 	FieldNotSupported = "__field_not_supported"
 )
 
-func structToMapWithPlaceholders(root string, in interface{}, createPlaceholder func(s string) string) map[string]interface{} {
+func structToMapWithPlaceholders(root string, in any, createPlaceholder func(s string) string) map[string]any {
 	m := structToMap(in)
 	insertFieldPlaceholders(root, m, createPlaceholder)
 	return m
 }
 
-func structToMap(s interface{}) map[string]interface{} {
-	m := make(map[string]interface{})
+func structToMap(s any) map[string]any {
+	m := make(map[string]any)
 	t := reflect.TypeOf(s)
 
 	for i := 0; i < t.NumMethod(); i++ {
@@ -52,7 +52,7 @@ func structToMap(s interface{}) map[string]interface{} {
 }
 
 // insert placeholder for the templates. Do it very shallow for now.
-func insertFieldPlaceholders(root string, m map[string]interface{}, createPlaceholder func(s string) string) {
+func insertFieldPlaceholders(root string, m map[string]any, createPlaceholder func(s string) string) {
 	for k := range m {
 		m[k] = createPlaceholder(root + "." + k)
 	}
diff --git a/resources/postpub/fields_test.go b/resources/postpub/fields_test.go
@@ -30,7 +30,7 @@ func TestCreatePlaceholders(t *testing.T) {
 		return "pre_" + s + "_post"
 	})
 
-	c.Assert(m, qt.DeepEquals, map[string]interface{}{
+	c.Assert(m, qt.DeepEquals, map[string]any{
 		"IsZero":      "pre_foo.IsZero_post",
 		"MarshalJSON": "pre_foo.MarshalJSON_post",
 		"Suffixes":    "pre_foo.Suffixes_post",
diff --git a/resources/postpub/postpub.go b/resources/postpub/postpub.go
@@ -35,7 +35,7 @@ type PostPublishedResource interface {
 	resource.ResourceDataProvider
 	resource.OriginProvider
 
-	MediaType() map[string]interface{}
+	MediaType() map[string]any
 }
 
 const (
@@ -109,13 +109,13 @@ func (r *PostPublishResource) GetFieldString(pattern string) (string, bool) {
 	case strings.HasPrefix(fieldAccessor, "MediaType"):
 		return r.fieldToString(d.MediaType(), fieldAccessor), true
 	case fieldAccessor == "Data.Integrity":
-		return cast.ToString((d.Data().(map[string]interface{})["Integrity"])), true
+		return cast.ToString((d.Data().(map[string]any)["Integrity"])), true
 	default:
 		panic(fmt.Sprintf("unknown field accessor %q", fieldAccessor))
 	}
 }
 
-func (r *PostPublishResource) fieldToString(receiver interface{}, path string) string {
+func (r *PostPublishResource) fieldToString(receiver any, path string) string {
 	fieldname := strings.Split(path, ".")[1]
 
 	receiverv := reflect.ValueOf(receiver)
@@ -143,15 +143,15 @@ func (r *PostPublishResource) fieldToString(receiver interface{}, path string) s
 	}
 }
 
-func (r *PostPublishResource) Data() interface{} {
-	m := map[string]interface{}{
+func (r *PostPublishResource) Data() any {
+	m := map[string]any{
 		"Integrity": "",
 	}
 	insertFieldPlaceholders("Data", m, r.field)
 	return m
 }
 
-func (r *PostPublishResource) MediaType() map[string]interface{} {
+func (r *PostPublishResource) MediaType() map[string]any {
 	m := structToMapWithPlaceholders("MediaType", media.Type{}, r.field)
 	return m
 }
@@ -172,7 +172,7 @@ func (r *PostPublishResource) Params() maps.Params {
 	panic(r.fieldNotSupported("Params"))
 }
 
-func (r *PostPublishResource) Content() (interface{}, error) {
+func (r *PostPublishResource) Content() (any, error) {
 	return r.field("Content"), nil
 }
 
diff --git a/resources/resource.go b/resources/resource.go
@@ -102,7 +102,7 @@ type Transformer interface {
 	Transform(...ResourceTransformation) (ResourceTransformer, error)
 }
 
-func NewFeatureNotAvailableTransformer(key string, elements ...interface{}) ResourceTransformation {
+func NewFeatureNotAvailableTransformer(key string, elements ...any) ResourceTransformation {
 	return transformerNotAvailable{
 		key: internal.NewResourceTransformationKey(key, elements...),
 	}
@@ -163,11 +163,11 @@ type commonResource struct {
 
 // Slice is not meant to be used externally. It's a bridge function
 // for the template functions. See collections.Slice.
-func (commonResource) Slice(in interface{}) (interface{}, error) {
+func (commonResource) Slice(in any) (any, error) {
 	switch items := in.(type) {
 	case resource.Resources:
 		return items, nil
-	case []interface{}:
+	case []any:
 		groups := make(resource.Resources, len(items))
 		for i, v := range items {
 			g, ok := v.(resource.Resource)
@@ -214,8 +214,8 @@ type genericResource struct {
 
 	title  string
 	name   string
-	params map[string]interface{}
-	data   map[string]interface{}
+	params map[string]any
+	data   map[string]any
 
 	resourceType string
 	mediaType    media.Type
@@ -225,7 +225,7 @@ func (l *genericResource) Clone() resource.Resource {
 	return l.clone()
 }
 
-func (l *genericResource) Content() (interface{}, error) {
+func (l *genericResource) Content() (any, error) {
 	if err := l.initContent(); err != nil {
 		return nil, err
 	}
@@ -237,7 +237,7 @@ func (r *genericResource) Err() error {
 	return nil
 }
 
-func (l *genericResource) Data() interface{} {
+func (l *genericResource) Data() any {
 	return l.data
 }
 
@@ -382,12 +382,12 @@ func (r *genericResource) tryTransformedFileCache(key string, u *transformationU
 	return f
 }
 
-func (r *genericResource) mergeData(in map[string]interface{}) {
+func (r *genericResource) mergeData(in map[string]any) {
 	if len(in) == 0 {
 		return
 	}
 	if r.data == nil {
-		r.data = make(map[string]interface{})
+		r.data = make(map[string]any)
 	}
 	for k, v := range in {
 		if _, found := r.data[k]; !found {
@@ -539,7 +539,7 @@ func (l *genericResource) relTargetPathsForRel(rel string) []string {
 	return targetPaths
 }
 
-func (l *genericResource) updateParams(params map[string]interface{}) {
+func (l *genericResource) updateParams(params map[string]any) {
 	if l.params == nil {
 		l.params = params
 		return
diff --git a/resources/resource/params.go b/resources/resource/params.go
@@ -19,7 +19,7 @@ import (
 	"github.com/spf13/cast"
 )
 
-func Param(r ResourceParamsProvider, fallback maps.Params, key interface{}) (interface{}, error) {
+func Param(r ResourceParamsProvider, fallback maps.Params, key any) (any, error) {
 	keyStr, err := cast.ToStringE(key)
 	if err != nil {
 		return nil, err
diff --git a/resources/resource/resource_helpers.go b/resources/resource/resource_helpers.go
@@ -24,17 +24,17 @@ import (
 
 // GetParam will return the param with the given key from the Resource,
 // nil if not found.
-func GetParam(r Resource, key string) interface{} {
+func GetParam(r Resource, key string) any {
 	return getParam(r, key, false)
 }
 
 // GetParamToLower is the same as GetParam but it will lower case any string
 // result, including string slices.
-func GetParamToLower(r Resource, key string) interface{} {
+func GetParamToLower(r Resource, key string) any {
 	return getParam(r, key, true)
 }
 
-func getParam(r Resource, key string, stringToLower bool) interface{} {
+func getParam(r Resource, key string, stringToLower bool) any {
 	v := r.Params()[strings.ToLower(key)]
 
 	if v == nil {
@@ -60,9 +60,9 @@ func getParam(r Resource, key string, stringToLower bool) interface{} {
 			return helpers.SliceToLower(val)
 		}
 		return v
-	case map[string]interface{}: // JSON and TOML
+	case map[string]any:
 		return v
-	case map[interface{}]interface{}: // YAML
+	case map[any]any:
 		return v
 	}
 
diff --git a/resources/resource/resources.go b/resources/resource/resources.go
@@ -108,7 +108,7 @@ func (r Resources) MergeByLanguage(r2 Resources) Resources {
 
 // MergeByLanguageInterface is the generic version of MergeByLanguage. It
 // is here just so it can be called from the tpl package.
-func (r Resources) MergeByLanguageInterface(in interface{}) (interface{}, error) {
+func (r Resources) MergeByLanguageInterface(in any) (any, error) {
 	r2, ok := in.(Resources)
 	if !ok {
 		return nil, fmt.Errorf("%T cannot be merged by language", in)
diff --git a/resources/resource/resourcetypes.go b/resources/resource/resourcetypes.go
@@ -66,7 +66,7 @@ type ImageOps interface {
 	Fill(spec string) (Image, error)
 	Fit(spec string) (Image, error)
 	Resize(spec string) (Image, error)
-	Filter(filters ...interface{}) (Image, error)
+	Filter(filters ...any) (Image, error)
 	Exif() *exif.Exif
 
 	// Internal
@@ -119,7 +119,7 @@ type ResourceParamsProvider interface {
 type ResourceDataProvider interface {
 	// Resource specific data set by Hugo.
 	// One example would be.Data.Digest for fingerprinted resources.
-	Data() interface{}
+	Data() any
 }
 
 // ResourcesLanguageMerger describes an interface for merging resources from a
@@ -127,7 +127,7 @@ type ResourceDataProvider interface {
 type ResourcesLanguageMerger interface {
 	MergeByLanguage(other Resources) Resources
 	// Needed for integration with the tpl package.
-	MergeByLanguageInterface(other interface{}) (interface{}, error)
+	MergeByLanguageInterface(other any) (any, error)
 }
 
 // Identifier identifies a resource.
@@ -152,7 +152,7 @@ type ContentProvider interface {
 	// * Page: template.HTML
 	// * JSON: String
 	// * Etc.
-	Content() (interface{}, error)
+	Content() (any, error)
 }
 
 // OpenReadSeekCloser allows setting some other way (than reading from a filesystem)
diff --git a/resources/resource_cache.go b/resources/resource_cache.go
@@ -44,7 +44,7 @@ type ResourceCache struct {
 	sync.RWMutex
 
 	// Either resource.Resource or resource.Resources.
-	cache map[string]interface{}
+	cache map[string]any
 
 	fileCache *filecache.Cache
 
@@ -128,7 +128,7 @@ func newResourceCache(rs *Spec) *ResourceCache {
 	return &ResourceCache{
 		rs:        rs,
 		fileCache: rs.FileCaches.AssetsCache(),
-		cache:     make(map[string]interface{}),
+		cache:     make(map[string]any),
 		nlocker:   locker.NewLocker(),
 	}
 }
@@ -137,7 +137,7 @@ func (c *ResourceCache) clear() {
 	c.Lock()
 	defer c.Unlock()
 
-	c.cache = make(map[string]interface{})
+	c.cache = make(map[string]any)
 	c.nlocker = locker.NewLocker()
 }
 
@@ -151,7 +151,7 @@ func (c *ResourceCache) cleanKey(key string) string {
 	return strings.TrimPrefix(path.Clean(strings.ToLower(key)), "/")
 }
 
-func (c *ResourceCache) get(key string) (interface{}, bool) {
+func (c *ResourceCache) get(key string) (any, bool) {
 	c.RLock()
 	defer c.RUnlock()
 	r, found := c.cache[key]
@@ -159,7 +159,7 @@ func (c *ResourceCache) get(key string) (interface{}, bool) {
 }
 
 func (c *ResourceCache) GetOrCreate(key string, f func() (resource.Resource, error)) (resource.Resource, error) {
-	r, err := c.getOrCreate(key, func() (interface{}, error) { return f() })
+	r, err := c.getOrCreate(key, func() (any, error) { return f() })
 	if r == nil || err != nil {
 		return nil, err
 	}
@@ -167,14 +167,14 @@ func (c *ResourceCache) GetOrCreate(key string, f func() (resource.Resource, err
 }
 
 func (c *ResourceCache) GetOrCreateResources(key string, f func() (resource.Resources, error)) (resource.Resources, error) {
-	r, err := c.getOrCreate(key, func() (interface{}, error) { return f() })
+	r, err := c.getOrCreate(key, func() (any, error) { return f() })
 	if r == nil || err != nil {
 		return nil, err
 	}
 	return r.(resource.Resources), nil
 }
 
-func (c *ResourceCache) getOrCreate(key string, f func() (interface{}, error)) (interface{}, error) {
+func (c *ResourceCache) getOrCreate(key string, f func() (any, error)) (any, error) {
 	key = c.cleanKey(key)
 	// First check in-memory cache.
 	r, found := c.get(key)
@@ -254,7 +254,7 @@ func (c *ResourceCache) writeMeta(key string, meta transformedResourceMetadata) 
 	return fi, fc, err
 }
 
-func (c *ResourceCache) set(key string, r interface{}) {
+func (c *ResourceCache) set(key string, r any) {
 	c.Lock()
 	defer c.Unlock()
 	c.cache[key] = r
diff --git a/resources/resource_factories/create/remote.go b/resources/resource_factories/create/remote.go
@@ -38,7 +38,7 @@ import (
 
 // FromRemote expects one or n-parts of a URL to a resource
 // If you provide multiple parts they will be joined together to the final URL.
-func (c *Client) FromRemote(uri string, optionsm map[string]interface{}) (resource.Resource, error) {
+func (c *Client) FromRemote(uri string, optionsm map[string]any) (resource.Resource, error) {
 	rURL, err := url.Parse(uri)
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to parse URL for resource %s", uri)
@@ -174,7 +174,7 @@ func addDefaultHeaders(req *http.Request, accepts ...string) {
 	}
 }
 
-func addUserProvidedHeaders(headers map[string]interface{}, req *http.Request) {
+func addUserProvidedHeaders(headers map[string]any, req *http.Request) {
 	if headers == nil {
 		return
 	}
@@ -209,7 +209,7 @@ func hasHeaderKey(m http.Header, key string) bool {
 
 type fromRemoteOptions struct {
 	Method  string
-	Headers map[string]interface{}
+	Headers map[string]any
 	Body    []byte
 }
 
@@ -220,7 +220,7 @@ func (o fromRemoteOptions) BodyReader() io.Reader {
 	return bytes.NewBuffer(o.Body)
 }
 
-func decodeRemoteOptions(optionsm map[string]interface{}) (fromRemoteOptions, error) {
+func decodeRemoteOptions(optionsm map[string]any) (fromRemoteOptions, error) {
 	options := fromRemoteOptions{
 		Method: "GET",
 	}
diff --git a/resources/resource_factories/create/remote_test.go b/resources/resource_factories/create/remote_test.go
@@ -24,21 +24,21 @@ func TestDecodeRemoteOptions(t *testing.T) {
 
 	for _, test := range []struct {
 		name    string
-		args    map[string]interface{}
+		args    map[string]any
 		want    fromRemoteOptions
 		wantErr bool
 	}{
 		{
 			"POST",
-			map[string]interface{}{
+			map[string]any{
 				"meThod": "PoST",
-				"headers": map[string]interface{}{
+				"headers": map[string]any{
 					"foo": "bar",
 				},
 			},
 			fromRemoteOptions{
 				Method: "POST",
-				Headers: map[string]interface{}{
+				Headers: map[string]any{
 					"foo": "bar",
 				},
 			},
@@ -46,7 +46,7 @@ func TestDecodeRemoteOptions(t *testing.T) {
 		},
 		{
 			"Body",
-			map[string]interface{}{
+			map[string]any{
 				"meThod": "POST",
 				"body":   []byte("foo"),
 			},
@@ -58,7 +58,7 @@ func TestDecodeRemoteOptions(t *testing.T) {
 		},
 		{
 			"Body, string",
-			map[string]interface{}{
+			map[string]any{
 				"meThod": "POST",
 				"body":   "foo",
 			},
diff --git a/resources/resource_metadata.go b/resources/resource_metadata.go
@@ -43,7 +43,7 @@ type metaAssigner interface {
 	setTitle(title string)
 	setName(name string)
 	setMediaType(mediaType media.Type)
-	updateParams(params map[string]interface{})
+	updateParams(params map[string]any)
 }
 
 const counterPlaceHolder = ":counter"
@@ -53,7 +53,7 @@ const counterPlaceHolder = ":counter"
 // This assignment is additive, but the most specific match needs to be first.
 // The `name` and `title` metadata field support shell-matched collection it got a match in.
 // See https://golang.org/pkg/path/#Match
-func AssignMetadata(metadata []map[string]interface{}, resources ...resource.Resource) error {
+func AssignMetadata(metadata []map[string]any, resources ...resource.Resource) error {
 	counters := make(map[string]int)
 
 	for _, r := range resources {
diff --git a/resources/resource_metadata_test.go b/resources/resource_metadata_test.go
@@ -30,10 +30,10 @@ func TestAssignMetadata(t *testing.T) {
 	var resources resource.Resources
 
 	for _, this := range []struct {
-		metaData   []map[string]interface{}
+		metaData   []map[string]any
 		assertFunc func(err error)
 	}{
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "My Resource",
 				"name":  "My Name",
@@ -44,7 +44,7 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(logo1.Name(), qt.Equals, "My Name")
 			c.Assert(foo2.Name(), qt.Equals, "My Name")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "My Logo",
 				"src":   "*loGo*",
@@ -62,11 +62,11 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(foo3.Name(), qt.Equals, "My Name")
 			c.Assert(foo3.Title(), qt.Equals, "My Resource")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "My Logo",
 				"src":   "*loGo*",
-				"params": map[string]interface{}{
+				"params": map[string]any{
 					"Param1": true,
 					"icon":   "logo",
 				},
@@ -74,7 +74,7 @@ func TestAssignMetadata(t *testing.T) {
 			{
 				"title": "My Resource",
 				"src":   "*",
-				"params": map[string]interface{}{
+				"params": map[string]any{
 					"Param2": true,
 					"icon":   "resource",
 				},
@@ -101,7 +101,7 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(icon1, qt.Equals, "logo")
 			c.Assert(icon2, qt.Equals, "resource")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"name": "Logo Name #:counter",
 				"src":  "*logo*",
@@ -124,7 +124,7 @@ func TestAssignMetadata(t *testing.T) {
 
 			c.Assert(resources.GetMatch("logo name #1*"), qt.Equals, logo2)
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "Third Logo #:counter",
 				"src":   "logo3.png",
@@ -143,7 +143,7 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(logo1.Title(), qt.Equals, "Other Logo #2")
 			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "Third Logo",
 				"src":   "logo3.png",
@@ -162,7 +162,7 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(logo1.Title(), qt.Equals, "Other Logo #2")
 			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"name": "third-logo",
 				"src":  "logo3.png",
@@ -181,7 +181,7 @@ func TestAssignMetadata(t *testing.T) {
 			c.Assert(logo1.Title(), qt.Equals, "Logo #2")
 			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "Third Logo #:counter",
 			},
@@ -189,7 +189,7 @@ func TestAssignMetadata(t *testing.T) {
 			// Missing src
 			c.Assert(err, qt.Not(qt.IsNil))
 		}},
-		{[]map[string]interface{}{
+		{[]map[string]any{
 			{
 				"title": "Title",
 				"src":   "[]",
diff --git a/resources/resource_spec.go b/resources/resource_spec.go
@@ -240,7 +240,7 @@ func (r *Spec) newGenericResourceWithBase(
 		mediaType:              mediaType,
 		resourceType:           resourceType,
 		spec:                   r,
-		params:                 make(map[string]interface{}),
+		params:                 make(map[string]any),
 		name:                   baseFilename,
 		title:                  baseFilename,
 		resourceContent:        &resourceContent{},
diff --git a/resources/resource_test.go b/resources/resource_test.go
@@ -244,7 +244,7 @@ func BenchmarkAssignMetadata(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		b.StopTimer()
 		var resources resource.Resources
-		meta := []map[string]interface{}{
+		meta := []map[string]any{
 			{
 				"title": "Foo #:counter",
 				"name":  "Foo Name #:counter",
diff --git a/resources/resource_transformers/babel/babel.go b/resources/resource_transformers/babel/babel.go
@@ -50,7 +50,7 @@ type Options struct {
 }
 
 // DecodeOptions decodes options to and generates command flags
-func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
+func DecodeOptions(m map[string]any) (opts Options, err error) {
 	if m == nil {
 		return
 	}
@@ -58,8 +58,8 @@ func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
 	return
 }
 
-func (opts Options) toArgs() []interface{} {
-	var args []interface{}
+func (opts Options) toArgs() []any {
+	var args []any
 
 	// external is not a known constant on the babel command line
 	// .sourceMaps must be a boolean, "inline", "both", or undefined
@@ -147,11 +147,11 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx
 
 	ctx.ReplaceOutPathExtension(".js")
 
-	var cmdArgs []interface{}
+	var cmdArgs []any
 
 	if configFile != "" {
 		logger.Infoln("babel: use config file", configFile)
-		cmdArgs = []interface{}{"--config-file", configFile}
+		cmdArgs = []any{"--config-file", configFile}
 	}
 
 	if optArgs := t.options.toArgs(); len(optArgs) > 0 {
diff --git a/resources/resource_transformers/htesting/testhelpers.go b/resources/resource_transformers/htesting/testhelpers.go
@@ -31,7 +31,7 @@ func NewTestResourceSpec() (*resources.Spec, error) {
 	cfg.Set("baseURL", "https://example.org")
 	cfg.Set("publishDir", "public")
 
-	imagingCfg := map[string]interface{}{
+	imagingCfg := map[string]any{
 		"resampleFilter": "linear",
 		"quality":        68,
 		"anchor":         "left",
diff --git a/resources/resource_transformers/integrity/integrity_test.go b/resources/resource_transformers/integrity/integrity_test.go
@@ -62,7 +62,7 @@ func TestTransform(t *testing.T) {
 
 	c.Assert(err, qt.IsNil)
 	c.Assert(transformed.RelPermalink(), qt.Equals, "/hugo.a5ad1c6961214a55de53c1ce6e60d27b6b761f54851fa65e33066460dfa6a0db.txt")
-	c.Assert(transformed.Data(), qt.DeepEquals, map[string]interface{}{"Integrity": template.HTMLAttr("sha256-pa0caWEhSlXeU8HObmDSe2t2H1SFH6ZeMwZkYN+moNs=")})
+	c.Assert(transformed.Data(), qt.DeepEquals, map[string]any{"Integrity": template.HTMLAttr("sha256-pa0caWEhSlXeU8HObmDSe2t2H1SFH6ZeMwZkYN+moNs=")})
 	content, err := transformed.(resource.ContentProvider).Content()
 	c.Assert(err, qt.IsNil)
 	c.Assert(content, qt.Equals, "Hugo Rocks!")
diff --git a/resources/resource_transformers/js/build.go b/resources/resource_transformers/js/build.go
@@ -54,7 +54,7 @@ func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) *Client {
 }
 
 type buildTransformation struct {
-	optsm map[string]interface{}
+	optsm map[string]any
 	c     *Client
 }
 
@@ -205,7 +205,7 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx
 }
 
 // Process process esbuild transform
-func (c *Client) Process(res resources.ResourceTransformer, opts map[string]interface{}) (resource.Resource, error) {
+func (c *Client) Process(res resources.ResourceTransformer, opts map[string]any) (resource.Resource, error) {
 	return res.Transform(
 		&buildTransformation{c: c, optsm: opts},
 	)
diff --git a/resources/resource_transformers/js/options.go b/resources/resource_transformers/js/options.go
@@ -71,14 +71,14 @@ type Options struct {
 	Inject []string
 
 	// User defined symbols.
-	Defines map[string]interface{}
+	Defines map[string]any
 
 	// Maps a component import to another.
 	Shims map[string]string
 
 	// User defined params. Will be marshaled to JSON and available as "@params", e.g.
 	//     import * as params from '@params';
-	Params interface{}
+	Params any
 
 	// What to use instead of React.createElement.
 	JSXFactory string
@@ -106,7 +106,7 @@ type Options struct {
 	tsConfig   string
 }
 
-func decodeOptions(m map[string]interface{}) (Options, error) {
+func decodeOptions(m map[string]any) (Options, error) {
 	var opts Options
 
 	if err := mapstructure.WeakDecode(m, &opts); err != nil {
@@ -269,7 +269,7 @@ func createBuildPlugins(c *Client, opts Options) ([]api.Plugin, error) {
 	params := opts.Params
 	if params == nil {
 		// This way @params will always resolve to something.
-		params = make(map[string]interface{})
+		params = make(map[string]any)
 	}
 
 	b, err := json.Marshal(params)
diff --git a/resources/resource_transformers/js/options_test.go b/resources/resource_transformers/js/options_test.go
@@ -33,7 +33,7 @@ import (
 func TestOptionKey(t *testing.T) {
 	c := qt.New(t)
 
-	opts := map[string]interface{}{
+	opts := map[string]any{
 		"TargetPath": "foo",
 		"Target":     "es2018",
 	}
diff --git a/resources/resource_transformers/postcss/postcss.go b/resources/resource_transformers/postcss/postcss.go
@@ -57,7 +57,7 @@ func New(rs *resources.Spec) *Client {
 	return &Client{rs: rs}
 }
 
-func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
+func DecodeOptions(m map[string]any) (opts Options, err error) {
 	if m == nil {
 		return
 	}
@@ -165,11 +165,11 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
 		}
 	}
 
-	var cmdArgs []interface{}
+	var cmdArgs []any
 
 	if configFile != "" {
 		logger.Infoln("postcss: use config file", configFile)
-		cmdArgs = []interface{}{"--config", configFile}
+		cmdArgs = []any{"--config", configFile}
 	}
 
 	if optArgs := t.options.toArgs(); len(optArgs) > 0 {
diff --git a/resources/resource_transformers/postcss/postcss_test.go b/resources/resource_transformers/postcss/postcss_test.go
@@ -31,14 +31,14 @@ import (
 // Issue 6166
 func TestDecodeOptions(t *testing.T) {
 	c := qt.New(t)
-	opts1, err := DecodeOptions(map[string]interface{}{
+	opts1, err := DecodeOptions(map[string]any{
 		"no-map": true,
 	})
 
 	c.Assert(err, qt.IsNil)
 	c.Assert(opts1.NoMap, qt.Equals, true)
 
-	opts2, err := DecodeOptions(map[string]interface{}{
+	opts2, err := DecodeOptions(map[string]any{
 		"noMap": true,
 	})
 
diff --git a/resources/resource_transformers/templates/execute_as_template.go b/resources/resource_transformers/templates/execute_as_template.go
@@ -44,7 +44,7 @@ type executeAsTemplateTransform struct {
 	rs         *resources.Spec
 	t          tpl.TemplatesProvider
 	targetPath string
-	data       interface{}
+	data       any
 }
 
 func (t *executeAsTemplateTransform) Key() internal.ResourceTransformationKey {
@@ -63,7 +63,7 @@ func (t *executeAsTemplateTransform) Transform(ctx *resources.ResourceTransforma
 	return t.t.Tmpl().Execute(templ, ctx.To, t.data)
 }
 
-func (c *Client) ExecuteAsTemplate(res resources.ResourceTransformer, targetPath string, data interface{}) (resource.Resource, error) {
+func (c *Client) ExecuteAsTemplate(res resources.ResourceTransformer, targetPath string, data any) (resource.Resource, error) {
 	return res.Transform(&executeAsTemplateTransform{
 		rs:         c.rs,
 		targetPath: helpers.ToSlashTrimLeading(targetPath),
diff --git a/resources/resource_transformers/tocss/dartsass/client.go b/resources/resource_transformers/tocss/dartsass/client.go
@@ -69,7 +69,7 @@ type Client struct {
 	transpiler           *godartsass.Transpiler
 }
 
-func (c *Client) ToCSS(res resources.ResourceTransformer, args map[string]interface{}) (resource.Resource, error) {
+func (c *Client) ToCSS(res resources.ResourceTransformer, args map[string]any) (resource.Resource, error) {
 	if c.dartSassNotAvailable {
 		return res.Transform(resources.NewFeatureNotAvailableTransformer(transformationName, args))
 	}
@@ -123,7 +123,7 @@ type Options struct {
 	EnableSourceMap bool
 }
 
-func decodeOptions(m map[string]interface{}) (opts Options, err error) {
+func decodeOptions(m map[string]any) (opts Options, err error) {
 	if m == nil {
 		return
 	}
diff --git a/resources/resource_transformers/tocss/dartsass/transform.go b/resources/resource_transformers/tocss/dartsass/transform.go
@@ -53,7 +53,7 @@ func Supports() bool {
 }
 
 type transform struct {
-	optsm map[string]interface{}
+	optsm map[string]any
 	c     *Client
 }
 
diff --git a/resources/resource_transformers/tocss/scss/client.go b/resources/resource_transformers/tocss/scss/client.go
@@ -62,7 +62,7 @@ type Options struct {
 	EnableSourceMap bool
 }
 
-func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
+func DecodeOptions(m map[string]any) (opts Options, err error) {
 	if m == nil {
 		return
 	}
diff --git a/resources/resource_transformers/tocss/scss/client_extended.go b/resources/resource_transformers/tocss/scss/client_extended.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build extended
 // +build extended
 
 package scss
diff --git a/resources/resource_transformers/tocss/scss/client_notavailable.go b/resources/resource_transformers/tocss/scss/client_notavailable.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !extended
 // +build !extended
 
 package scss
diff --git a/resources/resource_transformers/tocss/scss/tocss.go b/resources/resource_transformers/tocss/scss/tocss.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build extended
 // +build extended
 
 package scss
diff --git a/resources/testhelpers_test.go b/resources/testhelpers_test.go
@@ -70,7 +70,7 @@ func newTestResourceSpec(desc specDescriptor) *Spec {
 	cfg := createTestCfg()
 	cfg.Set("baseURL", baseURL)
 
-	imagingCfg := map[string]interface{}{
+	imagingCfg := map[string]any{
 		"resampleFilter": "linear",
 		"quality":        68,
 		"anchor":         "left",
diff --git a/resources/transform.go b/resources/transform.go
@@ -108,7 +108,7 @@ type ResourceTransformationCtx struct {
 
 	// Data data can be set on the transformed Resource. Not that this need
 	// to be simple types, as it needs to be serialized to JSON and back.
-	Data map[string]interface{}
+	Data map[string]any
 
 	// This is used to publish additional artifacts, e.g. source maps.
 	// We may improve this.
@@ -159,7 +159,7 @@ type resourceAdapter struct {
 	*resourceAdapterInner
 }
 
-func (r *resourceAdapter) Content() (interface{}, error) {
+func (r *resourceAdapter) Content() (any, error) {
 	r.init(false, true)
 	if r.transformationsErr != nil {
 		return nil, r.transformationsErr
@@ -171,7 +171,7 @@ func (r *resourceAdapter) Err() error {
 	return nil
 }
 
-func (r *resourceAdapter) Data() interface{} {
+func (r *resourceAdapter) Data() any {
 	r.init(false, false)
 	return r.target.Data()
 }
@@ -188,7 +188,7 @@ func (r *resourceAdapter) Fit(spec string) (resource.Image, error) {
 	return r.getImageOps().Fit(spec)
 }
 
-func (r *resourceAdapter) Filter(filters ...interface{}) (resource.Image, error) {
+func (r *resourceAdapter) Filter(filters ...any) (resource.Image, error) {
 	return r.getImageOps().Filter(filters...)
 }
 
@@ -355,7 +355,7 @@ func (r *resourceAdapter) transform(publish, setContent bool) error {
 	defer bp.PutBuffer(b2)
 
 	tctx := &ResourceTransformationCtx{
-		Data:                  make(map[string]interface{}),
+		Data:                  make(map[string]any),
 		OpenResourcePublisher: r.target.openPublishFileForWriting,
 	}
 
@@ -605,7 +605,7 @@ type transformationUpdate struct {
 	sourceFs       afero.Fs
 	targetPath     string
 	mediaType      media.Type
-	data           map[string]interface{}
+	data           map[string]any
 
 	startCtx ResourceTransformationCtx
 }
@@ -631,9 +631,9 @@ func (u *transformationUpdate) updateFromCtx(ctx *ResourceTransformationCtx) {
 
 // We will persist this information to disk.
 type transformedResourceMetadata struct {
-	Target     string                 `json:"Target"`
-	MediaTypeV string                 `json:"MediaType"`
-	MetaData   map[string]interface{} `json:"Data"`
+	Target     string         `json:"Target"`
+	MediaTypeV string         `json:"MediaType"`
+	MetaData   map[string]any `json:"Data"`
 }
 
 // contentReadSeekerCloser returns a ReadSeekerCloser if possible for a given Resource.
diff --git a/resources/transform_test.go b/resources/transform_test.go
@@ -118,7 +118,7 @@ func TestTransform(t *testing.T) {
 		c.Assert(tr.RelPermalink(), qt.Equals, "/f1.csv")
 		assertShouldExist(c, spec, "public/f1.csv", true)
 
-		data := tr.Data().(map[string]interface{})
+		data := tr.Data().(map[string]any)
 		c.Assert(data["mydata"], qt.Equals, "Hugo Rocks!")
 
 		assertNoDuplicateWrites(c, spec)
@@ -211,7 +211,7 @@ func TestTransform(t *testing.T) {
 						in = strings.Replace(in, "blue", "green", 1)
 						ctx.AddOutPathIdentifier("." + "cached")
 						ctx.OutMediaType = media.CSVType
-						ctx.Data = map[string]interface{}{
+						ctx.Data = map[string]any{
 							"Hugo": "Rocks!",
 						}
 						fmt.Fprint(ctx.To, in)
@@ -236,7 +236,7 @@ func TestTransform(t *testing.T) {
 			c.Assert(err, qt.IsNil)
 			c.Assert(content, qt.Equals, "color is green", msg)
 			c.Assert(tr.MediaType(), eq, media.CSVType)
-			c.Assert(tr.Data(), qt.DeepEquals, map[string]interface{}{
+			c.Assert(tr.Data(), qt.DeepEquals, map[string]any{
 				"Hugo": "Rocks!",
 			})
 
diff --git a/source/content_directory_test.go b/source/content_directory_test.go
@@ -29,7 +29,7 @@ func TestIgnoreDotFilesAndDirectories(t *testing.T) {
 	tests := []struct {
 		path                string
 		ignore              bool
-		ignoreFilesRegexpes interface{}
+		ignoreFilesRegexpes any
 	}{
 		{".foobar/", true, nil},
 		{"foobar/.barfoo/", true, nil},
diff --git a/source/sourceSpec.go b/source/sourceSpec.go
@@ -37,7 +37,7 @@ type SourceSpec struct {
 
 	shouldInclude func(filename string) bool
 
-	Languages              map[string]interface{}
+	Languages              map[string]any
 	DefaultContentLanguage string
 	DisabledLanguages      map[string]bool
 }
diff --git a/tpl/cast/cast.go b/tpl/cast/cast.go
@@ -30,23 +30,23 @@ type Namespace struct {
 }
 
 // ToInt converts the given value to an int.
-func (ns *Namespace) ToInt(v interface{}) (int, error) {
+func (ns *Namespace) ToInt(v any) (int, error) {
 	v = convertTemplateToString(v)
 	return _cast.ToIntE(v)
 }
 
 // ToString converts the given value to a string.
-func (ns *Namespace) ToString(v interface{}) (string, error) {
+func (ns *Namespace) ToString(v any) (string, error) {
 	return _cast.ToStringE(v)
 }
 
 // ToFloat converts the given value to a float.
-func (ns *Namespace) ToFloat(v interface{}) (float64, error) {
+func (ns *Namespace) ToFloat(v any) (float64, error) {
 	v = convertTemplateToString(v)
 	return _cast.ToFloat64E(v)
 }
 
-func convertTemplateToString(v interface{}) interface{} {
+func convertTemplateToString(v any) any {
 	switch vv := v.(type) {
 	case template.HTML:
 		v = string(vv)
diff --git a/tpl/cast/cast_test.go b/tpl/cast/cast_test.go
@@ -27,8 +27,8 @@ func TestToInt(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{"1", 1},
 		{template.HTML("2"), 2},
@@ -59,8 +59,8 @@ func TestToString(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{1, "1"},
 		{template.HTML("2"), "2"},
@@ -87,8 +87,8 @@ func TestToFloat(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{"1", 1.0},
 		{template.HTML("2"), 2.0},
diff --git a/tpl/cast/docshelper.go b/tpl/cast/docshelper.go
@@ -43,7 +43,7 @@ func init() {
 
 		}
 
-		return docshelper.DocProvider{"tpl": map[string]interface{}{"funcs": namespaces}}
+		return docshelper.DocProvider{"tpl": map[string]any{"funcs": namespaces}}
 	}
 
 	docshelper.AddDocProviderFunc(docsProvider)
diff --git a/tpl/cast/init.go b/tpl/cast/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.ToInt,
diff --git a/tpl/collections/append.go b/tpl/collections/append.go
@@ -25,7 +25,7 @@ import (
 // Note that with 2 arguments where both are slices of the same type,
 // the first slice will be appended to the second:
 //     {{ $pages = $pages | append .Site.RegularPages }}
-func (ns *Namespace) Append(args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Append(args ...any) (any, error) {
 	if len(args) < 2 {
 		return nil, errors.New("need at least 2 arguments to append")
 	}
diff --git a/tpl/collections/append_test.go b/tpl/collections/append_test.go
@@ -29,20 +29,20 @@ func TestAppend(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		start    interface{}
-		addend   []interface{}
-		expected interface{}
+		start    any
+		addend   []any
+		expected any
 	}{
-		{[]string{"a", "b"}, []interface{}{"c"}, []string{"a", "b", "c"}},
-		{[]string{"a", "b"}, []interface{}{"c", "d", "e"}, []string{"a", "b", "c", "d", "e"}},
-		{[]string{"a", "b"}, []interface{}{[]string{"c", "d", "e"}}, []string{"a", "b", "c", "d", "e"}},
+		{[]string{"a", "b"}, []any{"c"}, []string{"a", "b", "c"}},
+		{[]string{"a", "b"}, []any{"c", "d", "e"}, []string{"a", "b", "c", "d", "e"}},
+		{[]string{"a", "b"}, []any{[]string{"c", "d", "e"}}, []string{"a", "b", "c", "d", "e"}},
 		// Errors
-		{"", []interface{}{[]string{"a", "b"}}, false},
-		{[]string{"a", "b"}, []interface{}{}, false},
+		{"", []any{[]string{"a", "b"}}, false},
+		{[]string{"a", "b"}, []any{}, false},
 		// No string concatenation.
 		{
 			"ab",
-			[]interface{}{"c"},
+			[]any{"c"},
 			false,
 		},
 	} {
diff --git a/tpl/collections/apply.go b/tpl/collections/apply.go
@@ -25,9 +25,9 @@ import (
 )
 
 // Apply takes a map, array, or slice and returns a new slice with the function fname applied over it.
-func (ns *Namespace) Apply(ctx context.Context, seq interface{}, fname string, args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Apply(ctx context.Context, seq any, fname string, args ...any) (any, error) {
 	if seq == nil {
-		return make([]interface{}, 0), nil
+		return make([]any, 0), nil
 	}
 
 	if fname == "apply" {
@@ -47,7 +47,7 @@ func (ns *Namespace) Apply(ctx context.Context, seq interface{}, fname string, a
 
 	switch seqv.Kind() {
 	case reflect.Array, reflect.Slice:
-		r := make([]interface{}, seqv.Len())
+		r := make([]any, seqv.Len())
 		for i := 0; i < seqv.Len(); i++ {
 			vv := seqv.Index(i)
 
@@ -65,10 +65,10 @@ func (ns *Namespace) Apply(ctx context.Context, seq interface{}, fname string, a
 	}
 }
 
-func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...interface{}) (reflect.Value, error) {
+func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...any) (reflect.Value, error) {
 	num := fn.Type().NumIn()
 	if num > 0 && fn.Type().In(0).Implements(hreflect.ContextInterface) {
-		args = append([]interface{}{ctx}, args...)
+		args = append([]any{ctx}, args...)
 	}
 
 	n := make([]reflect.Value, len(args))
@@ -120,7 +120,7 @@ func (ns *Namespace) lookupFunc(fname string) (reflect.Value, bool) {
 		return reflect.Value{}, false
 	}
 
-	fn, ok := nv.Interface().(func(...interface{}) (interface{}, error))
+	fn, ok := nv.Interface().(func(...any) (any, error))
 	if !ok {
 		return reflect.Value{}, false
 	}
diff --git a/tpl/collections/apply_test.go b/tpl/collections/apply_test.go
@@ -48,11 +48,11 @@ func (templateFinder) LookupLayout(d output.LayoutDescriptor, f output.Format) (
 	return nil, false, nil
 }
 
-func (templateFinder) Execute(t tpl.Template, wr io.Writer, data interface{}) error {
+func (templateFinder) Execute(t tpl.Template, wr io.Writer, data any) error {
 	return nil
 }
 
-func (templateFinder) ExecuteWithContext(ctx context.Context, t tpl.Template, wr io.Writer, data interface{}) error {
+func (templateFinder) ExecuteWithContext(ctx context.Context, t tpl.Template, wr io.Writer, data any) error {
 	return nil
 }
 
@@ -71,13 +71,13 @@ func TestApply(t *testing.T) {
 	d.SetTmpl(new(templateFinder))
 	ns := New(d)
 
-	strings := []interface{}{"a\n", "b\n"}
+	strings := []any{"a\n", "b\n"}
 
 	ctx := context.Background()
 
 	result, err := ns.Apply(ctx, strings, "print", "a", "b", "c")
 	c.Assert(err, qt.IsNil)
-	c.Assert(result, qt.DeepEquals, []interface{}{"abc", "abc"})
+	c.Assert(result, qt.DeepEquals, []any{"abc", "abc"})
 
 	_, err = ns.Apply(ctx, strings, "apply", ".")
 	c.Assert(err, qt.Not(qt.IsNil))
diff --git a/tpl/collections/collections.go b/tpl/collections/collections.go
@@ -50,7 +50,7 @@ type Namespace struct {
 }
 
 // After returns all the items after the first N in a rangeable list.
-func (ns *Namespace) After(index interface{}, seq interface{}) (interface{}, error) {
+func (ns *Namespace) After(index any, seq any) (any, error) {
 	if index == nil || seq == nil {
 		return nil, errors.New("both limit and seq must be provided")
 	}
@@ -86,7 +86,7 @@ func (ns *Namespace) After(index interface{}, seq interface{}) (interface{}, err
 
 // Delimit takes a given sequence and returns a delimited HTML string.
 // If last is passed to the function, it will be used as the final delimiter.
-func (ns *Namespace) Delimit(seq, delimiter interface{}, last ...interface{}) (template.HTML, error) {
+func (ns *Namespace) Delimit(seq, delimiter any, last ...any) (template.HTML, error) {
 	d, err := cast.ToStringE(delimiter)
 	if err != nil {
 		return "", err
@@ -146,12 +146,12 @@ func (ns *Namespace) Delimit(seq, delimiter interface{}, last ...interface{}) (t
 // walking the parameters and treating them as key-value pairs.  The number
 // of parameters must be even.
 // The keys can be string slices, which will create the needed nested structure.
-func (ns *Namespace) Dictionary(values ...interface{}) (map[string]interface{}, error) {
+func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) {
 	if len(values)%2 != 0 {
 		return nil, errors.New("invalid dictionary call")
 	}
 
-	root := make(map[string]interface{})
+	root := make(map[string]any)
 
 	for i := 0; i < len(values); i += 2 {
 		dict := root
@@ -162,12 +162,12 @@ func (ns *Namespace) Dictionary(values ...interface{}) (map[string]interface{}, 
 		case []string:
 			for i := 0; i < len(v)-1; i++ {
 				key = v[i]
-				var m map[string]interface{}
+				var m map[string]any
 				v, found := dict[key]
 				if found {
-					m = v.(map[string]interface{})
+					m = v.(map[string]any)
 				} else {
-					m = make(map[string]interface{})
+					m = make(map[string]any)
 					dict[key] = m
 				}
 				dict = m
@@ -184,7 +184,7 @@ func (ns *Namespace) Dictionary(values ...interface{}) (map[string]interface{}, 
 
 // EchoParam returns a given value if it is set; otherwise, it returns an
 // empty string.
-func (ns *Namespace) EchoParam(a, key interface{}) interface{} {
+func (ns *Namespace) EchoParam(a, key any) any {
 	av, isNil := indirect(reflect.ValueOf(a))
 	if isNil {
 		return ""
@@ -227,7 +227,7 @@ func (ns *Namespace) EchoParam(a, key interface{}) interface{} {
 }
 
 // First returns the first N items in a rangeable list.
-func (ns *Namespace) First(limit interface{}, seq interface{}) (interface{}, error) {
+func (ns *Namespace) First(limit any, seq any) (any, error) {
 	if limit == nil || seq == nil {
 		return nil, errors.New("both limit and seq must be provided")
 	}
@@ -262,7 +262,7 @@ func (ns *Namespace) First(limit interface{}, seq interface{}) (interface{}, err
 }
 
 // In returns whether v is in the set l.  l may be an array or slice.
-func (ns *Namespace) In(l interface{}, v interface{}) (bool, error) {
+func (ns *Namespace) In(l any, v any) (bool, error) {
 	if l == nil || v == nil {
 		return false, nil
 	}
@@ -301,9 +301,9 @@ func (ns *Namespace) In(l interface{}, v interface{}) (bool, error) {
 
 // Intersect returns the common elements in the given sets, l1 and l2.  l1 and
 // l2 must be of the same type and may be either arrays or slices.
-func (ns *Namespace) Intersect(l1, l2 interface{}) (interface{}, error) {
+func (ns *Namespace) Intersect(l1, l2 any) (any, error) {
 	if l1 == nil || l2 == nil {
-		return make([]interface{}, 0), nil
+		return make([]any, 0), nil
 	}
 
 	var ins *intersector
@@ -313,19 +313,19 @@ func (ns *Namespace) Intersect(l1, l2 interface{}) (interface{}, error) {
 
 	switch l1v.Kind() {
 	case reflect.Array, reflect.Slice:
-		ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[interface{}]bool)}
+		ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[any]bool)}
 		switch l2v.Kind() {
 		case reflect.Array, reflect.Slice:
 			for i := 0; i < l1v.Len(); i++ {
 				l1vv := l1v.Index(i)
 				if !l1vv.Type().Comparable() {
-					return make([]interface{}, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
+					return make([]any, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
 				}
 
 				for j := 0; j < l2v.Len(); j++ {
 					l2vv := l2v.Index(j)
 					if !l2vv.Type().Comparable() {
-						return make([]interface{}, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
+						return make([]any, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
 					}
 
 					ins.handleValuePair(l1vv, l2vv)
@@ -342,7 +342,7 @@ func (ns *Namespace) Intersect(l1, l2 interface{}) (interface{}, error) {
 
 // Group groups a set of elements by the given key.
 // This is currently only supported for Pages.
-func (ns *Namespace) Group(key interface{}, items interface{}) (interface{}, error) {
+func (ns *Namespace) Group(key any, items any) (any, error) {
 	if key == nil {
 		return nil, errors.New("nil is not a valid key to group by")
 	}
@@ -362,7 +362,7 @@ func (ns *Namespace) Group(key interface{}, items interface{}) (interface{}, err
 
 // IsSet returns whether a given array, channel, slice, or map has a key
 // defined.
-func (ns *Namespace) IsSet(a interface{}, key interface{}) (bool, error) {
+func (ns *Namespace) IsSet(a any, key any) (bool, error) {
 	av := reflect.ValueOf(a)
 	kv := reflect.ValueOf(key)
 
@@ -387,7 +387,7 @@ func (ns *Namespace) IsSet(a interface{}, key interface{}) (bool, error) {
 }
 
 // Last returns the last N items in a rangeable list.
-func (ns *Namespace) Last(limit interface{}, seq interface{}) (interface{}, error) {
+func (ns *Namespace) Last(limit any, seq any) (any, error) {
 	if limit == nil || seq == nil {
 		return nil, errors.New("both limit and seq must be provided")
 	}
@@ -422,7 +422,7 @@ func (ns *Namespace) Last(limit interface{}, seq interface{}) (interface{}, erro
 }
 
 // Querify encodes the given parameters in URL-encoded form ("bar=baz&foo=quux") sorted by key.
-func (ns *Namespace) Querify(params ...interface{}) (string, error) {
+func (ns *Namespace) Querify(params ...any) (string, error) {
 	qs := url.Values{}
 
 	if len(params) == 1 {
@@ -438,7 +438,7 @@ func (ns *Namespace) Querify(params ...interface{}) (string, error) {
 
 			return qs.Encode(), nil
 
-		case []interface{}:
+		case []any:
 			params = v
 
 		default:
@@ -463,7 +463,7 @@ func (ns *Namespace) Querify(params ...interface{}) (string, error) {
 }
 
 // Reverse creates a copy of slice and reverses it.
-func (ns *Namespace) Reverse(slice interface{}) (interface{}, error) {
+func (ns *Namespace) Reverse(slice any) (any, error) {
 	if slice == nil {
 		return nil, nil
 	}
@@ -493,7 +493,7 @@ func (ns *Namespace) Reverse(slice interface{}) (interface{}, error) {
 //     -3 => -1, -2, -3
 //     1 4 => 1, 2, 3, 4
 //     1 -2 => 1, 0, -1, -2
-func (ns *Namespace) Seq(args ...interface{}) ([]int, error) {
+func (ns *Namespace) Seq(args ...any) ([]int, error) {
 	if len(args) < 1 || len(args) > 3 {
 		return nil, errors.New("invalid number of arguments to Seq")
 	}
@@ -561,7 +561,7 @@ func (ns *Namespace) Seq(args ...interface{}) ([]int, error) {
 }
 
 // Shuffle returns the given rangeable list in a randomised order.
-func (ns *Namespace) Shuffle(seq interface{}) (interface{}, error) {
+func (ns *Namespace) Shuffle(seq any) (any, error) {
 	if seq == nil {
 		return nil, errors.New("both count and seq must be provided")
 	}
@@ -591,7 +591,7 @@ func (ns *Namespace) Shuffle(seq interface{}) (interface{}, error) {
 }
 
 // Slice returns a slice of all passed arguments.
-func (ns *Namespace) Slice(args ...interface{}) interface{} {
+func (ns *Namespace) Slice(args ...any) any {
 	if len(args) == 0 {
 		return args
 	}
@@ -601,7 +601,7 @@ func (ns *Namespace) Slice(args ...interface{}) interface{} {
 
 type intersector struct {
 	r    reflect.Value
-	seen map[interface{}]bool
+	seen map[any]bool
 }
 
 func (i *intersector) appendIfNotSeen(v reflect.Value) {
@@ -638,9 +638,9 @@ func (i *intersector) handleValuePair(l1vv, l2vv reflect.Value) {
 // l2 must be of the same type and may be either arrays or slices.
 // If l1 and l2 aren't of the same type then l1 will be returned.
 // If either l1 or l2 is nil then the non-nil list will be returned.
-func (ns *Namespace) Union(l1, l2 interface{}) (interface{}, error) {
+func (ns *Namespace) Union(l1, l2 any) (any, error) {
 	if l1 == nil && l2 == nil {
-		return []interface{}{}, nil
+		return []any{}, nil
 	} else if l1 == nil && l2 != nil {
 		return l2, nil
 	} else if l1 != nil && l2 == nil {
@@ -656,7 +656,7 @@ func (ns *Namespace) Union(l1, l2 interface{}) (interface{}, error) {
 	case reflect.Array, reflect.Slice:
 		switch l2v.Kind() {
 		case reflect.Array, reflect.Slice:
-			ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[interface{}]bool)}
+			ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[any]bool)}
 
 			if l1v.Type() != l2v.Type() &&
 				l1v.Type().Elem().Kind() != reflect.Interface &&
@@ -673,7 +673,7 @@ func (ns *Namespace) Union(l1, l2 interface{}) (interface{}, error) {
 				l1vv, isNil = indirectInterface(l1v.Index(i))
 
 				if !l1vv.Type().Comparable() {
-					return []interface{}{}, errors.New("union does not support slices or arrays of uncomparable types")
+					return []any{}, errors.New("union does not support slices or arrays of uncomparable types")
 				}
 
 				if !isNil {
@@ -721,9 +721,9 @@ func (ns *Namespace) Union(l1, l2 interface{}) (interface{}, error) {
 
 // Uniq takes in a slice or array and returns a slice with subsequent
 // duplicate elements removed.
-func (ns *Namespace) Uniq(seq interface{}) (interface{}, error) {
+func (ns *Namespace) Uniq(seq any) (any, error) {
 	if seq == nil {
-		return make([]interface{}, 0), nil
+		return make([]any, 0), nil
 	}
 
 	v := reflect.ValueOf(seq)
@@ -739,7 +739,7 @@ func (ns *Namespace) Uniq(seq interface{}) (interface{}, error) {
 		return nil, errors.Errorf("type %T not supported", seq)
 	}
 
-	seen := make(map[interface{}]bool)
+	seen := make(map[any]bool)
 
 	for i := 0; i < v.Len(); i++ {
 		ev, _ := indirectInterface(v.Index(i))
@@ -756,7 +756,7 @@ func (ns *Namespace) Uniq(seq interface{}) (interface{}, error) {
 }
 
 // KeyVals creates a key and values wrapper.
-func (ns *Namespace) KeyVals(key interface{}, vals ...interface{}) (types.KeyValues, error) {
+func (ns *Namespace) KeyVals(key any, vals ...any) (types.KeyValues, error) {
 	return types.KeyValues{Key: key, Values: vals}, nil
 }
 
diff --git a/tpl/collections/collections_test.go b/tpl/collections/collections_test.go
@@ -43,9 +43,9 @@ func TestAfter(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		index  interface{}
-		seq    interface{}
-		expect interface{}
+		index  any
+		seq    any
+		expect any
 	}{
 		{int(2), []string{"a", "b", "c", "d"}, []string{"c", "d"}},
 		{int32(3), []string{"a", "b"}, []string{}},
@@ -81,7 +81,7 @@ type tstGrouper struct {
 
 type tstGroupers []*tstGrouper
 
-func (g tstGrouper) Group(key interface{}, items interface{}) (interface{}, error) {
+func (g tstGrouper) Group(key any, items any) (any, error) {
 	ilen := reflect.ValueOf(items).Len()
 	return fmt.Sprintf("%v(%d)", key, ilen), nil
 }
@@ -89,7 +89,7 @@ func (g tstGrouper) Group(key interface{}, items interface{}) (interface{}, erro
 type tstGrouper2 struct {
 }
 
-func (g *tstGrouper2) Group(key interface{}, items interface{}) (interface{}, error) {
+func (g *tstGrouper2) Group(key any, items any) (any, error) {
 	ilen := reflect.ValueOf(items).Len()
 	return fmt.Sprintf("%v(%d)", key, ilen), nil
 }
@@ -100,9 +100,9 @@ func TestGroup(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		key    interface{}
-		items  interface{}
-		expect interface{}
+		key    any
+		items  any
+		expect any
 	}{
 		{"a", []*tstGrouper{{}, {}}, "a(2)"},
 		{"b", tstGroupers{&tstGrouper{}, &tstGrouper{}}, "b(2)"},
@@ -136,9 +136,9 @@ func TestDelimit(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		seq       interface{}
-		delimiter interface{}
-		last      interface{}
+		seq       any
+		delimiter any
+		last      any
 		expect    template.HTML
 	}{
 		{[]string{"class1", "class2", "class3"}, " ", nil, "class1 class2 class3"},
@@ -188,19 +188,19 @@ func TestDictionary(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		values []interface{}
-		expect interface{}
+		values []any
+		expect any
 	}{
-		{[]interface{}{"a", "b"}, map[string]interface{}{"a": "b"}},
-		{[]interface{}{[]string{"a", "b"}, "c"}, map[string]interface{}{"a": map[string]interface{}{"b": "c"}}},
+		{[]any{"a", "b"}, map[string]any{"a": "b"}},
+		{[]any{[]string{"a", "b"}, "c"}, map[string]any{"a": map[string]any{"b": "c"}}},
 		{
-			[]interface{}{[]string{"a", "b"}, "c", []string{"a", "b2"}, "c2", "b", "c"},
-			map[string]interface{}{"a": map[string]interface{}{"b": "c", "b2": "c2"}, "b": "c"},
+			[]any{[]string{"a", "b"}, "c", []string{"a", "b2"}, "c2", "b", "c"},
+			map[string]any{"a": map[string]any{"b": "c", "b2": "c2"}, "b": "c"},
 		},
-		{[]interface{}{"a", 12, "b", []int{4}}, map[string]interface{}{"a": 12, "b": []int{4}}},
+		{[]any{"a", 12, "b", []int{4}}, map[string]any{"a": 12, "b": []int{4}}},
 		// errors
-		{[]interface{}{5, "b"}, false},
-		{[]interface{}{"a", "b", "c"}, false},
+		{[]any{5, "b"}, false},
+		{[]any{"a", "b", "c"}, false},
 	} {
 		i := i
 		test := test
@@ -246,9 +246,9 @@ func TestEchoParam(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		a      interface{}
-		key    interface{}
-		expect interface{}
+		a      any
+		key    any
+		expect any
 	}{
 		{[]int{1, 2, 3}, 1, int64(2)},
 		{[]uint{1, 2, 3}, 1, uint64(2)},
@@ -260,7 +260,7 @@ func TestEchoParam(t *testing.T) {
 		{map[string]float64{"foo": 1.1, "bar": 2.2, "baz": 3.3}, "bar", float64(2.2)},
 		{map[string]string{"foo": "FOO", "bar": "BAR", "baz": "BAZ"}, "bar", "BAR"},
 		{map[string]TstX{"foo": {A: "a", B: "b"}, "bar": {A: "c", B: "d"}, "baz": {A: "e", B: "f"}}, "bar", ""},
-		{map[string]interface{}{"foo": nil}, "foo", ""},
+		{map[string]any{"foo": nil}, "foo", ""},
 		{(*[]string)(nil), "bar", ""},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test)
@@ -278,9 +278,9 @@ func TestFirst(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		limit  interface{}
-		seq    interface{}
-		expect interface{}
+		limit  any
+		seq    any
+		expect any
 	}{
 		{int(2), []string{"a", "b", "c"}, []string{"a", "b"}},
 		{int32(3), []string{"a", "b"}, []string{"a", "b"}},
@@ -316,20 +316,20 @@ func TestIn(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		l1     interface{}
-		l2     interface{}
+		l1     any
+		l2     any
 		expect bool
 	}{
 		{[]string{"a", "b", "c"}, "b", true},
-		{[]interface{}{"a", "b", "c"}, "b", true},
-		{[]interface{}{"a", "b", "c"}, "d", false},
+		{[]any{"a", "b", "c"}, "b", true},
+		{[]any{"a", "b", "c"}, "d", false},
 		{[]string{"a", "b", "c"}, "d", false},
 		{[]string{"a", "12", "c"}, 12, false},
 		{[]string{"a", "b", "c"}, nil, false},
 		{[]int{1, 2, 4}, 2, true},
-		{[]interface{}{1, 2, 4}, 2, true},
-		{[]interface{}{1, 2, 4}, nil, false},
-		{[]interface{}{nil}, nil, false},
+		{[]any{1, 2, 4}, 2, true},
+		{[]any{1, 2, 4}, nil, false},
+		{[]any{nil}, nil, false},
 		{[]int{1, 2, 4}, 3, false},
 		{[]float64{1.23, 2.45, 4.67}, 1.23, true},
 		{[]float64{1.234567, 2.45, 4.67}, 1.234568, false},
@@ -392,16 +392,16 @@ func TestIntersect(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		l1, l2 interface{}
-		expect interface{}
+		l1, l2 any
+		expect any
 	}{
 		{[]string{"a", "b", "c", "c"}, []string{"a", "b", "b"}, []string{"a", "b"}},
 		{[]string{"a", "b"}, []string{"a", "b", "c"}, []string{"a", "b"}},
 		{[]string{"a", "b", "c"}, []string{"d", "e"}, []string{}},
 		{[]string{}, []string{}, []string{}},
-		{[]string{"a", "b"}, nil, []interface{}{}},
-		{nil, []string{"a", "b"}, []interface{}{}},
-		{nil, nil, []interface{}{}},
+		{[]string{"a", "b"}, nil, []any{}},
+		{nil, []string{"a", "b"}, []any{}},
+		{nil, nil, []any{}},
 		{[]string{"1", "2"}, []int{1, 2}, []string{}},
 		{[]int{1, 2}, []string{"1", "2"}, []int{}},
 		{[]int{1, 2, 4}, []int{2, 4}, []int{2, 4}},
@@ -410,45 +410,45 @@ func TestIntersect(t *testing.T) {
 		{[]float64{2.2, 4.4}, []float64{1.1, 2.2, 4.4}, []float64{2.2, 4.4}},
 
 		// []interface{} ∩ []interface{}
-		{[]interface{}{"a", "b", "c"}, []interface{}{"a", "b", "b"}, []interface{}{"a", "b"}},
-		{[]interface{}{1, 2, 3}, []interface{}{1, 2, 2}, []interface{}{1, 2}},
-		{[]interface{}{int8(1), int8(2), int8(3)}, []interface{}{int8(1), int8(2), int8(2)}, []interface{}{int8(1), int8(2)}},
-		{[]interface{}{int16(1), int16(2), int16(3)}, []interface{}{int16(1), int16(2), int16(2)}, []interface{}{int16(1), int16(2)}},
-		{[]interface{}{int32(1), int32(2), int32(3)}, []interface{}{int32(1), int32(2), int32(2)}, []interface{}{int32(1), int32(2)}},
-		{[]interface{}{int64(1), int64(2), int64(3)}, []interface{}{int64(1), int64(2), int64(2)}, []interface{}{int64(1), int64(2)}},
-		{[]interface{}{float32(1), float32(2), float32(3)}, []interface{}{float32(1), float32(2), float32(2)}, []interface{}{float32(1), float32(2)}},
-		{[]interface{}{float64(1), float64(2), float64(3)}, []interface{}{float64(1), float64(2), float64(2)}, []interface{}{float64(1), float64(2)}},
+		{[]any{"a", "b", "c"}, []any{"a", "b", "b"}, []any{"a", "b"}},
+		{[]any{1, 2, 3}, []any{1, 2, 2}, []any{1, 2}},
+		{[]any{int8(1), int8(2), int8(3)}, []any{int8(1), int8(2), int8(2)}, []any{int8(1), int8(2)}},
+		{[]any{int16(1), int16(2), int16(3)}, []any{int16(1), int16(2), int16(2)}, []any{int16(1), int16(2)}},
+		{[]any{int32(1), int32(2), int32(3)}, []any{int32(1), int32(2), int32(2)}, []any{int32(1), int32(2)}},
+		{[]any{int64(1), int64(2), int64(3)}, []any{int64(1), int64(2), int64(2)}, []any{int64(1), int64(2)}},
+		{[]any{float32(1), float32(2), float32(3)}, []any{float32(1), float32(2), float32(2)}, []any{float32(1), float32(2)}},
+		{[]any{float64(1), float64(2), float64(3)}, []any{float64(1), float64(2), float64(2)}, []any{float64(1), float64(2)}},
 
 		// []interface{} ∩ []T
-		{[]interface{}{"a", "b", "c"}, []string{"a", "b", "b"}, []interface{}{"a", "b"}},
-		{[]interface{}{1, 2, 3}, []int{1, 2, 2}, []interface{}{1, 2}},
-		{[]interface{}{int8(1), int8(2), int8(3)}, []int8{1, 2, 2}, []interface{}{int8(1), int8(2)}},
-		{[]interface{}{int16(1), int16(2), int16(3)}, []int16{1, 2, 2}, []interface{}{int16(1), int16(2)}},
-		{[]interface{}{int32(1), int32(2), int32(3)}, []int32{1, 2, 2}, []interface{}{int32(1), int32(2)}},
-		{[]interface{}{int64(1), int64(2), int64(3)}, []int64{1, 2, 2}, []interface{}{int64(1), int64(2)}},
-		{[]interface{}{uint(1), uint(2), uint(3)}, []uint{1, 2, 2}, []interface{}{uint(1), uint(2)}},
-		{[]interface{}{float32(1), float32(2), float32(3)}, []float32{1, 2, 2}, []interface{}{float32(1), float32(2)}},
-		{[]interface{}{float64(1), float64(2), float64(3)}, []float64{1, 2, 2}, []interface{}{float64(1), float64(2)}},
+		{[]any{"a", "b", "c"}, []string{"a", "b", "b"}, []any{"a", "b"}},
+		{[]any{1, 2, 3}, []int{1, 2, 2}, []any{1, 2}},
+		{[]any{int8(1), int8(2), int8(3)}, []int8{1, 2, 2}, []any{int8(1), int8(2)}},
+		{[]any{int16(1), int16(2), int16(3)}, []int16{1, 2, 2}, []any{int16(1), int16(2)}},
+		{[]any{int32(1), int32(2), int32(3)}, []int32{1, 2, 2}, []any{int32(1), int32(2)}},
+		{[]any{int64(1), int64(2), int64(3)}, []int64{1, 2, 2}, []any{int64(1), int64(2)}},
+		{[]any{uint(1), uint(2), uint(3)}, []uint{1, 2, 2}, []any{uint(1), uint(2)}},
+		{[]any{float32(1), float32(2), float32(3)}, []float32{1, 2, 2}, []any{float32(1), float32(2)}},
+		{[]any{float64(1), float64(2), float64(3)}, []float64{1, 2, 2}, []any{float64(1), float64(2)}},
 
 		// []T ∩ []interface{}
-		{[]string{"a", "b", "c"}, []interface{}{"a", "b", "b"}, []string{"a", "b"}},
-		{[]int{1, 2, 3}, []interface{}{1, 2, 2}, []int{1, 2}},
-		{[]int8{1, 2, 3}, []interface{}{int8(1), int8(2), int8(2)}, []int8{1, 2}},
-		{[]int16{1, 2, 3}, []interface{}{int16(1), int16(2), int16(2)}, []int16{1, 2}},
-		{[]int32{1, 2, 3}, []interface{}{int32(1), int32(2), int32(2)}, []int32{1, 2}},
-		{[]int64{1, 2, 3}, []interface{}{int64(1), int64(2), int64(2)}, []int64{1, 2}},
-		{[]float32{1, 2, 3}, []interface{}{float32(1), float32(2), float32(2)}, []float32{1, 2}},
-		{[]float64{1, 2, 3}, []interface{}{float64(1), float64(2), float64(2)}, []float64{1, 2}},
+		{[]string{"a", "b", "c"}, []any{"a", "b", "b"}, []string{"a", "b"}},
+		{[]int{1, 2, 3}, []any{1, 2, 2}, []int{1, 2}},
+		{[]int8{1, 2, 3}, []any{int8(1), int8(2), int8(2)}, []int8{1, 2}},
+		{[]int16{1, 2, 3}, []any{int16(1), int16(2), int16(2)}, []int16{1, 2}},
+		{[]int32{1, 2, 3}, []any{int32(1), int32(2), int32(2)}, []int32{1, 2}},
+		{[]int64{1, 2, 3}, []any{int64(1), int64(2), int64(2)}, []int64{1, 2}},
+		{[]float32{1, 2, 3}, []any{float32(1), float32(2), float32(2)}, []float32{1, 2}},
+		{[]float64{1, 2, 3}, []any{float64(1), float64(2), float64(2)}, []float64{1, 2}},
 
 		// Structs
 		{pagesPtr{p1, p4, p2, p3}, pagesPtr{p4, p2, p2}, pagesPtr{p4, p2}},
 		{pagesVals{p1v, p4v, p2v, p3v}, pagesVals{p1v, p3v, p3v}, pagesVals{p1v, p3v}},
-		{[]interface{}{p1, p4, p2, p3}, []interface{}{p4, p2, p2}, []interface{}{p4, p2}},
-		{[]interface{}{p1v, p4v, p2v, p3v}, []interface{}{p1v, p3v, p3v}, []interface{}{p1v, p3v}},
+		{[]any{p1, p4, p2, p3}, []any{p4, p2, p2}, []any{p4, p2}},
+		{[]any{p1v, p4v, p2v, p3v}, []any{p1v, p3v, p3v}, []any{p1v, p3v}},
 		{pagesPtr{p1, p4, p2, p3}, pagesPtr{}, pagesPtr{}},
 		{pagesVals{}, pagesVals{p1v, p3v, p3v}, pagesVals{}},
-		{[]interface{}{p1, p4, p2, p3}, []interface{}{}, []interface{}{}},
-		{[]interface{}{}, []interface{}{p1v, p3v, p3v}, []interface{}{}},
+		{[]any{p1, p4, p2, p3}, []any{}, []any{}},
+		{[]any{}, []any{p1v, p3v, p3v}, []any{}},
 
 		// errors
 		{"not array or slice", []string{"a"}, false},
@@ -482,23 +482,23 @@ func TestIsSet(t *testing.T) {
 	ns := newTestNs()
 
 	for i, test := range []struct {
-		a      interface{}
-		key    interface{}
+		a      any
+		key    any
 		expect bool
 		isErr  bool
 	}{
-		{[]interface{}{1, 2, 3, 5}, 2, true, false},
-		{[]interface{}{1, 2, 3, 5}, "2", true, false},
-		{[]interface{}{1, 2, 3, 5}, 2.0, true, false},
+		{[]any{1, 2, 3, 5}, 2, true, false},
+		{[]any{1, 2, 3, 5}, "2", true, false},
+		{[]any{1, 2, 3, 5}, 2.0, true, false},
 
-		{[]interface{}{1, 2, 3, 5}, 22, false, false},
+		{[]any{1, 2, 3, 5}, 22, false, false},
 
-		{map[string]interface{}{"a": 1, "b": 2}, "b", true, false},
-		{map[string]interface{}{"a": 1, "b": 2}, "bc", false, false},
+		{map[string]any{"a": 1, "b": 2}, "b", true, false},
+		{map[string]any{"a": 1, "b": 2}, "bc", false, false},
 
 		{time.Now(), "Day", false, false},
 		{nil, "nil", false, false},
-		{[]interface{}{1, 2, 3, 5}, TstX{}, false, true},
+		{[]any{1, 2, 3, 5}, TstX{}, false, true},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test)
 
@@ -519,9 +519,9 @@ func TestLast(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		limit  interface{}
-		seq    interface{}
-		expect interface{}
+		limit  any
+		seq    any
+		expect any
 	}{
 		{int(2), []string{"a", "b", "c"}, []string{"b", "c"}},
 		{int32(3), []string{"a", "b"}, []string{"a", "b"}},
@@ -558,21 +558,21 @@ func TestQuerify(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		params []interface{}
-		expect interface{}
+		params []any
+		expect any
 	}{
-		{[]interface{}{"a", "b"}, "a=b"},
-		{[]interface{}{"a", "b", "c", "d", "f", " &"}, `a=b&c=d&f=+%26`},
-		{[]interface{}{[]string{"a", "b"}}, "a=b"},
-		{[]interface{}{[]string{"a", "b", "c", "d", "f", " &"}}, `a=b&c=d&f=+%26`},
-		{[]interface{}{[]interface{}{"x", "y"}}, `x=y`},
-		{[]interface{}{[]interface{}{"x", 5}}, `x=5`},
+		{[]any{"a", "b"}, "a=b"},
+		{[]any{"a", "b", "c", "d", "f", " &"}, `a=b&c=d&f=+%26`},
+		{[]any{[]string{"a", "b"}}, "a=b"},
+		{[]any{[]string{"a", "b", "c", "d", "f", " &"}}, `a=b&c=d&f=+%26`},
+		{[]any{[]any{"x", "y"}}, `x=y`},
+		{[]any{[]any{"x", 5}}, `x=5`},
 		// errors
-		{[]interface{}{5, "b"}, false},
-		{[]interface{}{"a", "b", "c"}, false},
-		{[]interface{}{[]string{"a", "b", "c"}}, false},
-		{[]interface{}{[]string{"a", "b"}, "c"}, false},
-		{[]interface{}{[]interface{}{"c", "d", "e"}}, false},
+		{[]any{5, "b"}, false},
+		{[]any{"a", "b", "c"}, false},
+		{[]any{[]string{"a", "b", "c"}}, false},
+		{[]any{[]string{"a", "b"}, "c"}, false},
+		{[]any{[]any{"c", "d", "e"}}, false},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test.params)
 
@@ -590,7 +590,7 @@ func TestQuerify(t *testing.T) {
 
 func BenchmarkQuerify(b *testing.B) {
 	ns := New(&deps.Deps{})
-	params := []interface{}{"a", "b", "c", "d", "f", " &"}
+	params := []any{"a", "b", "c", "d", "f", " &"}
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
@@ -620,28 +620,28 @@ func TestSeq(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		args   []interface{}
-		expect interface{}
+		args   []any
+		expect any
 	}{
-		{[]interface{}{-2, 5}, []int{-2, -1, 0, 1, 2, 3, 4, 5}},
-		{[]interface{}{1, 2, 4}, []int{1, 3}},
-		{[]interface{}{1}, []int{1}},
-		{[]interface{}{3}, []int{1, 2, 3}},
-		{[]interface{}{3.2}, []int{1, 2, 3}},
-		{[]interface{}{0}, []int{}},
-		{[]interface{}{-1}, []int{-1}},
-		{[]interface{}{-3}, []int{-1, -2, -3}},
-		{[]interface{}{3, -2}, []int{3, 2, 1, 0, -1, -2}},
-		{[]interface{}{6, -2, 2}, []int{6, 4, 2}},
+		{[]any{-2, 5}, []int{-2, -1, 0, 1, 2, 3, 4, 5}},
+		{[]any{1, 2, 4}, []int{1, 3}},
+		{[]any{1}, []int{1}},
+		{[]any{3}, []int{1, 2, 3}},
+		{[]any{3.2}, []int{1, 2, 3}},
+		{[]any{0}, []int{}},
+		{[]any{-1}, []int{-1}},
+		{[]any{-3}, []int{-1, -2, -3}},
+		{[]any{3, -2}, []int{3, 2, 1, 0, -1, -2}},
+		{[]any{6, -2, 2}, []int{6, 4, 2}},
 		// errors
-		{[]interface{}{1, 0, 2}, false},
-		{[]interface{}{1, -1, 2}, false},
-		{[]interface{}{2, 1, 1}, false},
-		{[]interface{}{2, 1, 1, 1}, false},
-		{[]interface{}{2001}, false},
-		{[]interface{}{}, false},
-		{[]interface{}{0, -1000000}, false},
-		{[]interface{}{tstNoStringer{}}, false},
+		{[]any{1, 0, 2}, false},
+		{[]any{1, -1, 2}, false},
+		{[]any{2, 1, 1}, false},
+		{[]any{2, 1, 1, 1}, false},
+		{[]any{2001}, false},
+		{[]any{}, false},
+		{[]any{0, -1000000}, false},
+		{[]any{tstNoStringer{}}, false},
 		{nil, false},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test)
@@ -664,7 +664,7 @@ func TestShuffle(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		seq     interface{}
+		seq     any
 		success bool
 	}{
 		{[]string{"a", "b", "c", "d"}, true},
@@ -735,14 +735,14 @@ func TestSlice(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		args     []interface{}
-		expected interface{}
+		args     []any
+		expected any
 	}{
-		{[]interface{}{"a", "b"}, []string{"a", "b"}},
-		{[]interface{}{}, []interface{}{}},
-		{[]interface{}{nil}, []interface{}{nil}},
-		{[]interface{}{5, "b"}, []interface{}{5, "b"}},
-		{[]interface{}{tstNoStringer{}}, []tstNoStringer{{}}},
+		{[]any{"a", "b"}, []string{"a", "b"}},
+		{[]any{}, []any{}},
+		{[]any{nil}, []any{nil}},
+		{[]any{5, "b"}, []any{5, "b"}},
+		{[]any{tstNoStringer{}}, []tstNoStringer{{}}},
 	} {
 		errMsg := qt.Commentf("[%d] %v", i, test.args)
 
@@ -759,12 +759,12 @@ func TestUnion(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		l1     interface{}
-		l2     interface{}
-		expect interface{}
+		l1     any
+		l2     any
+		expect any
 		isErr  bool
 	}{
-		{nil, nil, []interface{}{}, false},
+		{nil, nil, []any{}, false},
 		{nil, []string{"a", "b"}, []string{"a", "b"}, false},
 		{[]string{"a", "b"}, nil, []string{"a", "b"}, false},
 
@@ -783,36 +783,36 @@ func TestUnion(t *testing.T) {
 		{[]int{2, 4}, []int{1, 2, 4}, []int{2, 4, 1}, false},
 		{[]int{1, 2, 4}, []int{3, 6}, []int{1, 2, 4, 3, 6}, false},
 		{[]float64{2.2, 4.4}, []float64{1.1, 2.2, 4.4}, []float64{2.2, 4.4, 1.1}, false},
-		{[]interface{}{"a", "b", "c", "c"}, []interface{}{"a", "b", "b"}, []interface{}{"a", "b", "c"}, false},
+		{[]any{"a", "b", "c", "c"}, []any{"a", "b", "b"}, []any{"a", "b", "c"}, false},
 
 		// []T ∪ []interface{}
-		{[]string{"1", "2"}, []interface{}{"9"}, []string{"1", "2", "9"}, false},
-		{[]int{2, 4}, []interface{}{1, 2, 4}, []int{2, 4, 1}, false},
-		{[]int8{2, 4}, []interface{}{int8(1), int8(2), int8(4)}, []int8{2, 4, 1}, false},
-		{[]int8{2, 4}, []interface{}{1, 2, 4}, []int8{2, 4, 1}, false},
-		{[]int16{2, 4}, []interface{}{1, 2, 4}, []int16{2, 4, 1}, false},
-		{[]int32{2, 4}, []interface{}{1, 2, 4}, []int32{2, 4, 1}, false},
-		{[]int64{2, 4}, []interface{}{1, 2, 4}, []int64{2, 4, 1}, false},
+		{[]string{"1", "2"}, []any{"9"}, []string{"1", "2", "9"}, false},
+		{[]int{2, 4}, []any{1, 2, 4}, []int{2, 4, 1}, false},
+		{[]int8{2, 4}, []any{int8(1), int8(2), int8(4)}, []int8{2, 4, 1}, false},
+		{[]int8{2, 4}, []any{1, 2, 4}, []int8{2, 4, 1}, false},
+		{[]int16{2, 4}, []any{1, 2, 4}, []int16{2, 4, 1}, false},
+		{[]int32{2, 4}, []any{1, 2, 4}, []int32{2, 4, 1}, false},
+		{[]int64{2, 4}, []any{1, 2, 4}, []int64{2, 4, 1}, false},
 
-		{[]float64{2.2, 4.4}, []interface{}{1.1, 2.2, 4.4}, []float64{2.2, 4.4, 1.1}, false},
-		{[]float32{2.2, 4.4}, []interface{}{1.1, 2.2, 4.4}, []float32{2.2, 4.4, 1.1}, false},
+		{[]float64{2.2, 4.4}, []any{1.1, 2.2, 4.4}, []float64{2.2, 4.4, 1.1}, false},
+		{[]float32{2.2, 4.4}, []any{1.1, 2.2, 4.4}, []float32{2.2, 4.4, 1.1}, false},
 
 		// []interface{} ∪ []T
-		{[]interface{}{"a", "b", "c", "c"}, []string{"a", "b", "d"}, []interface{}{"a", "b", "c", "d"}, false},
-		{[]interface{}{}, []string{}, []interface{}{}, false},
-		{[]interface{}{1, 2}, []int{2, 3}, []interface{}{1, 2, 3}, false},
-		{[]interface{}{1, 2}, []int8{2, 3}, []interface{}{1, 2, 3}, false}, // 28
-		{[]interface{}{uint(1), uint(2)}, []uint{2, 3}, []interface{}{uint(1), uint(2), uint(3)}, false},
-		{[]interface{}{1.1, 2.2}, []float64{2.2, 3.3}, []interface{}{1.1, 2.2, 3.3}, false},
+		{[]any{"a", "b", "c", "c"}, []string{"a", "b", "d"}, []any{"a", "b", "c", "d"}, false},
+		{[]any{}, []string{}, []any{}, false},
+		{[]any{1, 2}, []int{2, 3}, []any{1, 2, 3}, false},
+		{[]any{1, 2}, []int8{2, 3}, []any{1, 2, 3}, false}, // 28
+		{[]any{uint(1), uint(2)}, []uint{2, 3}, []any{uint(1), uint(2), uint(3)}, false},
+		{[]any{1.1, 2.2}, []float64{2.2, 3.3}, []any{1.1, 2.2, 3.3}, false},
 
 		// Structs
 		{pagesPtr{p1, p4}, pagesPtr{p4, p2, p2}, pagesPtr{p1, p4, p2}, false},
 		{pagesVals{p1v}, pagesVals{p3v, p3v}, pagesVals{p1v, p3v}, false},
-		{[]interface{}{p1, p4}, []interface{}{p4, p2, p2}, []interface{}{p1, p4, p2}, false},
-		{[]interface{}{p1v}, []interface{}{p3v, p3v}, []interface{}{p1v, p3v}, false},
+		{[]any{p1, p4}, []any{p4, p2, p2}, []any{p1, p4, p2}, false},
+		{[]any{p1v}, []any{p3v, p3v}, []any{p1v, p3v}, false},
 		// #3686
-		{[]interface{}{p1v}, []interface{}{}, []interface{}{p1v}, false},
-		{[]interface{}{}, []interface{}{p1v}, []interface{}{p1v}, false},
+		{[]any{p1v}, []any{}, []any{p1v}, false},
+		{[]any{}, []any{p1v}, []any{p1v}, false},
 		{pagesPtr{p1}, pagesPtr{}, pagesPtr{p1}, false},
 		{pagesVals{p1v}, pagesVals{}, pagesVals{p1v}, false},
 		{pagesPtr{}, pagesPtr{p1}, pagesPtr{p1}, false},
@@ -847,8 +847,8 @@ func TestUniq(t *testing.T) {
 	c := qt.New(t)
 	ns := New(&deps.Deps{})
 	for i, test := range []struct {
-		l      interface{}
-		expect interface{}
+		l      any
+		expect any
 		isErr  bool
 	}{
 		{[]string{"a", "b", "c"}, []string{"a", "b", "c"}, false},
@@ -860,7 +860,7 @@ func TestUniq(t *testing.T) {
 		{[]int{1, 2, 2, 3}, []int{1, 2, 3}, false},
 		{[]int{1, 2, 3, 2}, []int{1, 2, 3}, false},
 		{[4]int{1, 2, 3, 2}, []int{1, 2, 3}, false},
-		{nil, make([]interface{}, 0), false},
+		{nil, make([]any, 0), false},
 		// Pointers
 		{pagesPtr{p1, p2, p3, p2}, pagesPtr{p1, p2, p3}, false},
 		{pagesPtr{}, pagesPtr{}, false},
@@ -951,7 +951,7 @@ type TstXI interface {
 	TstRv2() string
 }
 
-func ToTstXIs(slice interface{}) []TstXI {
+func ToTstXIs(slice any) []TstXI {
 	s := reflect.ValueOf(slice)
 	if s.Kind() != reflect.Slice {
 		return nil
diff --git a/tpl/collections/complement.go b/tpl/collections/complement.go
@@ -25,7 +25,7 @@ import (
 //
 // The reasoning behind this rather clumsy API is so we can do this in the templates:
 //    {{ $c := .Pages | complement $last4 }}
-func (ns *Namespace) Complement(seqs ...interface{}) (interface{}, error) {
+func (ns *Namespace) Complement(seqs ...any) (any, error) {
 	if len(seqs) < 2 {
 		return nil, errors.New("complement needs at least two arguments")
 	}
diff --git a/tpl/collections/complement_test.go b/tpl/collections/complement_test.go
@@ -48,27 +48,27 @@ func TestComplement(t *testing.T) {
 	sp2_2 := StructWithSlicePointers{xb, xe}
 
 	for i, test := range []struct {
-		s        interface{}
-		t        []interface{}
-		expected interface{}
+		s        any
+		t        []any
+		expected any
 	}{
-		{[]string{"a", "b", "c"}, []interface{}{[]string{"c", "d"}}, []string{"a", "b"}},
-		{[]string{"a", "b", "c"}, []interface{}{[]string{"c", "d"}, []string{"a", "b"}}, []string{}},
-		{[]interface{}{"a", "b", nil}, []interface{}{[]string{"a", "d"}}, []interface{}{"b", nil}},
-		{[]int{1, 2, 3, 4, 5}, []interface{}{[]int{1, 3}, []string{"a", "b"}, []int{1, 2}}, []int{4, 5}},
-		{[]int{1, 2, 3, 4, 5}, []interface{}{[]int64{1, 3}}, []int{2, 4, 5}},
-		{s1, []interface{}{s2}, []TstX{{A: "a"}, {A: "d"}}},
-		{sp1, []interface{}{sp2}, []*StructWithSlice{xa, xd}},
-		{sp1_2, []interface{}{sp2_2}, StructWithSlicePointers{xa, xd}},
+		{[]string{"a", "b", "c"}, []any{[]string{"c", "d"}}, []string{"a", "b"}},
+		{[]string{"a", "b", "c"}, []any{[]string{"c", "d"}, []string{"a", "b"}}, []string{}},
+		{[]any{"a", "b", nil}, []any{[]string{"a", "d"}}, []any{"b", nil}},
+		{[]int{1, 2, 3, 4, 5}, []any{[]int{1, 3}, []string{"a", "b"}, []int{1, 2}}, []int{4, 5}},
+		{[]int{1, 2, 3, 4, 5}, []any{[]int64{1, 3}}, []int{2, 4, 5}},
+		{s1, []any{s2}, []TstX{{A: "a"}, {A: "d"}}},
+		{sp1, []any{sp2}, []*StructWithSlice{xa, xd}},
+		{sp1_2, []any{sp2_2}, StructWithSlicePointers{xa, xd}},
 
 		// Errors
-		{[]string{"a", "b", "c"}, []interface{}{"error"}, false},
-		{"error", []interface{}{[]string{"c", "d"}, []string{"a", "b"}}, false},
-		{[]string{"a", "b", "c"}, []interface{}{[][]string{{"c", "d"}}}, false},
+		{[]string{"a", "b", "c"}, []any{"error"}, false},
+		{"error", []any{[]string{"c", "d"}, []string{"a", "b"}}, false},
+		{[]string{"a", "b", "c"}, []any{[][]string{{"c", "d"}}}, false},
 		{
-			[]interface{}{[][]string{{"c", "d"}}},
-			[]interface{}{[]string{"c", "d"}, []string{"a", "b"}},
-			[]interface{}{[][]string{{"c", "d"}}},
+			[]any{[][]string{{"c", "d"}}},
+			[]any{[]string{"c", "d"}, []string{"a", "b"}},
+			[]any{[][]string{{"c", "d"}}},
 		},
 	} {
 
diff --git a/tpl/collections/index.go b/tpl/collections/index.go
@@ -32,7 +32,7 @@ import (
 // We deviate from the stdlib due to https://github.com/golang/go/issues/14751.
 //
 // TODO(moorereason): merge upstream changes.
-func (ns *Namespace) Index(item interface{}, args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Index(item any, args ...any) (any, error) {
 	v := reflect.ValueOf(item)
 	if !v.IsValid() {
 		return nil, errors.New("index of untyped nil")
@@ -43,7 +43,7 @@ func (ns *Namespace) Index(item interface{}, args ...interface{}) (interface{}, 
 		return lowerm.Get(cast.ToStringSlice(args)...), nil
 	}
 
-	var indices []interface{}
+	var indices []any
 
 	if len(args) == 1 {
 		v := reflect.ValueOf(args[0])
diff --git a/tpl/collections/index_test.go b/tpl/collections/index_test.go
@@ -29,28 +29,28 @@ func TestIndex(t *testing.T) {
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
-		item    interface{}
-		indices []interface{}
-		expect  interface{}
+		item    any
+		indices []any
+		expect  any
 		isErr   bool
 	}{
-		{[]int{0, 1}, []interface{}{0}, 0, false},
-		{[]int{0, 1}, []interface{}{9}, nil, false}, // index out of range
+		{[]int{0, 1}, []any{0}, 0, false},
+		{[]int{0, 1}, []any{9}, nil, false}, // index out of range
 		{[]uint{0, 1}, nil, []uint{0, 1}, false},
-		{[][]int{{1, 2}, {3, 4}}, []interface{}{0, 0}, 1, false},
-		{map[int]int{1: 10, 2: 20}, []interface{}{1}, 10, false},
-		{map[int]int{1: 10, 2: 20}, []interface{}{0}, 0, false},
-		{map[string]map[string]string{"a": {"b": "c"}}, []interface{}{"a", "b"}, "c", false},
-		{[]map[string]map[string]string{{"a": {"b": "c"}}}, []interface{}{0, "a", "b"}, "c", false},
-		{map[string]map[string]interface{}{"a": {"b": []string{"c", "d"}}}, []interface{}{"a", "b", 1}, "d", false},
-		{map[string]map[string]string{"a": {"b": "c"}}, []interface{}{[]string{"a", "b"}}, "c", false},
-		{maps.Params{"a": "av"}, []interface{}{"A"}, "av", false},
-		{maps.Params{"a": map[string]interface{}{"b": "bv"}}, []interface{}{"A", "B"}, "bv", false},
+		{[][]int{{1, 2}, {3, 4}}, []any{0, 0}, 1, false},
+		{map[int]int{1: 10, 2: 20}, []any{1}, 10, false},
+		{map[int]int{1: 10, 2: 20}, []any{0}, 0, false},
+		{map[string]map[string]string{"a": {"b": "c"}}, []any{"a", "b"}, "c", false},
+		{[]map[string]map[string]string{{"a": {"b": "c"}}}, []any{0, "a", "b"}, "c", false},
+		{map[string]map[string]any{"a": {"b": []string{"c", "d"}}}, []any{"a", "b", 1}, "d", false},
+		{map[string]map[string]string{"a": {"b": "c"}}, []any{[]string{"a", "b"}}, "c", false},
+		{maps.Params{"a": "av"}, []any{"A"}, "av", false},
+		{maps.Params{"a": map[string]any{"b": "bv"}}, []any{"A", "B"}, "bv", false},
 		// errors
 		{nil, nil, nil, true},
-		{[]int{0, 1}, []interface{}{"1"}, nil, true},
-		{[]int{0, 1}, []interface{}{nil}, nil, true},
-		{tstNoStringer{}, []interface{}{0}, nil, true},
+		{[]int{0, 1}, []any{"1"}, nil, true},
+		{[]int{0, 1}, []any{nil}, nil, true},
+		{tstNoStringer{}, []any{0}, nil, true},
 	} {
 		c.Run(fmt.Sprint(i), func(c *qt.C) {
 			errMsg := qt.Commentf("[%d] %v", i, test)
diff --git a/tpl/collections/init.go b/tpl/collections/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.After,
diff --git a/tpl/collections/merge.go b/tpl/collections/merge.go
@@ -26,7 +26,7 @@ import (
 // Merge creates a copy of the final parameter and merges the preceding
 // parameters into it in reverse order.
 // Currently only maps are supported. Key handling is case insensitive.
-func (ns *Namespace) Merge(params ...interface{}) (interface{}, error) {
+func (ns *Namespace) Merge(params ...any) (any, error) {
 	if len(params) < 2 {
 		return nil, errors.New("merge requires at least two parameters")
 	}
@@ -45,7 +45,7 @@ func (ns *Namespace) Merge(params ...interface{}) (interface{}, error) {
 }
 
 // merge creates a copy of dst and merges src into it.
-func (ns *Namespace) merge(src, dst interface{}) (interface{}, error) {
+func (ns *Namespace) merge(src, dst any) (any, error) {
 	vdst, vsrc := reflect.ValueOf(dst), reflect.ValueOf(src)
 
 	if vdst.Kind() != reflect.Map {
diff --git a/tpl/collections/merge_test.go b/tpl/collections/merge_test.go
@@ -29,56 +29,56 @@ import (
 func TestMerge(t *testing.T) {
 	ns := New(&deps.Deps{})
 
-	simpleMap := map[string]interface{}{"a": 1, "b": 2}
+	simpleMap := map[string]any{"a": 1, "b": 2}
 
 	for i, test := range []struct {
 		name   string
-		params []interface{}
-		expect interface{}
+		params []any
+		expect any
 		isErr  bool
 	}{
 		{
 			"basic",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "c": 3},
-				map[string]interface{}{"a": 1, "b": 2},
+			[]any{
+				map[string]any{"a": 42, "c": 3},
+				map[string]any{"a": 1, "b": 2},
 			},
-			map[string]interface{}{"a": 1, "b": 2, "c": 3},
+			map[string]any{"a": 1, "b": 2, "c": 3},
 			false,
 		},
 		{
 			"multi",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "c": 3, "e": 11},
-				map[string]interface{}{"a": 1, "b": 2},
-				map[string]interface{}{"a": 9, "c": 4, "d": 7},
+			[]any{
+				map[string]any{"a": 42, "c": 3, "e": 11},
+				map[string]any{"a": 1, "b": 2},
+				map[string]any{"a": 9, "c": 4, "d": 7},
 			},
-			map[string]interface{}{"a": 9, "b": 2, "c": 4, "d": 7, "e": 11},
+			map[string]any{"a": 9, "b": 2, "c": 4, "d": 7, "e": 11},
 			false,
 		},
 		{
 			"basic case insensitive",
-			[]interface{}{
-				map[string]interface{}{"A": 42, "c": 3},
-				map[string]interface{}{"a": 1, "b": 2},
+			[]any{
+				map[string]any{"A": 42, "c": 3},
+				map[string]any{"a": 1, "b": 2},
 			},
-			map[string]interface{}{"a": 1, "b": 2, "c": 3},
+			map[string]any{"a": 1, "b": 2, "c": 3},
 			false,
 		},
 		{
 			"nested",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "c": 3, "b": map[string]interface{}{"d": 55, "e": 66, "f": 3}},
-				map[string]interface{}{"a": 1, "b": map[string]interface{}{"d": 1, "e": 2}},
+			[]any{
+				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
+				map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2}},
 			},
-			map[string]interface{}{"a": 1, "b": map[string]interface{}{"d": 1, "e": 2, "f": 3}, "c": 3},
+			map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2, "f": 3}, "c": 3},
 			false,
 		},
 		{
 			// https://github.com/gohugoio/hugo/issues/6633
 			"params dst",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "c": 3},
+			[]any{
+				map[string]any{"a": 42, "c": 3},
 				maps.Params{"a": 1, "b": 2},
 			},
 			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
@@ -86,8 +86,8 @@ func TestMerge(t *testing.T) {
 		},
 		{
 			"params dst, upper case src",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "C": 3},
+			[]any{
+				map[string]any{"a": 42, "C": 3},
 				maps.Params{"a": 1, "b": 2},
 			},
 			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
@@ -95,26 +95,26 @@ func TestMerge(t *testing.T) {
 		},
 		{
 			"params src",
-			[]interface{}{
+			[]any{
 				maps.Params{"a": 42, "c": 3},
-				map[string]interface{}{"a": 1, "c": 2},
+				map[string]any{"a": 1, "c": 2},
 			},
-			map[string]interface{}{"a": int(1), "c": int(2)},
+			map[string]any{"a": int(1), "c": int(2)},
 			false,
 		},
 		{
 			"params src, upper case dst",
-			[]interface{}{
+			[]any{
 				maps.Params{"a": 42, "c": 3},
-				map[string]interface{}{"a": 1, "C": 2},
+				map[string]any{"a": 1, "C": 2},
 			},
-			map[string]interface{}{"a": int(1), "C": int(2)},
+			map[string]any{"a": int(1), "C": int(2)},
 			false,
 		},
 		{
 			"nested, params dst",
-			[]interface{}{
-				map[string]interface{}{"a": 42, "c": 3, "b": map[string]interface{}{"d": 55, "e": 66, "f": 3}},
+			[]any{
+				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
 				maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2}},
 			},
 			maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2, "f": 3}, "c": 3},
@@ -123,19 +123,19 @@ func TestMerge(t *testing.T) {
 		{
 			// https://github.com/gohugoio/hugo/issues/7899
 			"matching keys with non-map src value",
-			[]interface{}{
-				map[string]interface{}{"k": "v"},
-				map[string]interface{}{"k": map[string]interface{}{"k2": "v2"}},
+			[]any{
+				map[string]any{"k": "v"},
+				map[string]any{"k": map[string]any{"k2": "v2"}},
 			},
-			map[string]interface{}{"k": map[string]interface{}{"k2": "v2"}},
+			map[string]any{"k": map[string]any{"k2": "v2"}},
 			false,
 		},
-		{"src nil", []interface{}{nil, simpleMap}, simpleMap, false},
+		{"src nil", []any{nil, simpleMap}, simpleMap, false},
 		// Error cases.
-		{"dst not a map", []interface{}{nil, "not a map"}, nil, true},
-		{"src not a map", []interface{}{"not a map", simpleMap}, nil, true},
-		{"different map types", []interface{}{map[int]interface{}{32: "a"}, simpleMap}, nil, true},
-		{"all nil", []interface{}{nil, nil}, nil, true},
+		{"dst not a map", []any{nil, "not a map"}, nil, true},
+		{"src not a map", []any{"not a map", simpleMap}, nil, true},
+		{"different map types", []any{map[int]any{32: "a"}, simpleMap}, nil, true},
+		{"all nil", []any{nil, nil}, nil, true},
 	} {
 
 		test := test
@@ -205,9 +205,9 @@ V22 = "v22_2"
 		c.Assert(
 			merged,
 			qt.DeepEquals,
-			map[string]interface{}{
+			map[string]any{
 				"V1": "v1_1", "V2": "v2_2",
-				"V2s": map[string]interface{}{"V21": "v21_1", "V22": "v22_2"},
+				"V2s": map[string]any{"V21": "v21_1", "V22": "v22_2"},
 			})
 	}
 }
@@ -215,12 +215,12 @@ V22 = "v22_2"
 func TestCaseInsensitiveMapLookup(t *testing.T) {
 	c := qt.New(t)
 
-	m1 := reflect.ValueOf(map[string]interface{}{
+	m1 := reflect.ValueOf(map[string]any{
 		"a": 1,
 		"B": 2,
 	})
 
-	m2 := reflect.ValueOf(map[int]interface{}{
+	m2 := reflect.ValueOf(map[int]any{
 		1: 1,
 		2: 2,
 	})
diff --git a/tpl/collections/reflect_helpers.go b/tpl/collections/reflect_helpers.go
@@ -46,7 +46,7 @@ func numberToFloat(v reflect.Value) (float64, error) {
 // normalizes different numeric types if isNumber
 // or get the hash values if not Comparable (such as map or struct)
 // to make them comparable
-func normalize(v reflect.Value) interface{} {
+func normalize(v reflect.Value) any {
 	k := v.Kind()
 
 	switch {
@@ -67,8 +67,8 @@ func normalize(v reflect.Value) interface{} {
 
 // collects identities from the slices in seqs into a set. Numeric values are normalized,
 // pointers unwrapped.
-func collectIdentities(seqs ...interface{}) (map[interface{}]bool, error) {
-	seen := make(map[interface{}]bool)
+func collectIdentities(seqs ...any) (map[any]bool, error) {
+	seen := make(map[any]bool)
 	for _, seq := range seqs {
 		v := reflect.ValueOf(seq)
 		switch v.Kind() {
@@ -167,7 +167,7 @@ func convertNumber(v reflect.Value, to reflect.Kind) (reflect.Value, error) {
 	return n, nil
 }
 
-func newSliceElement(items interface{}) interface{} {
+func newSliceElement(items any) any {
 	tp := reflect.TypeOf(items)
 	if tp == nil {
 		return nil
diff --git a/tpl/collections/sort.go b/tpl/collections/sort.go
@@ -27,7 +27,7 @@ import (
 var sortComp = compare.New(true)
 
 // Sort returns a sorted sequence.
-func (ns *Namespace) Sort(seq interface{}, args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
 	if seq == nil {
 		return nil, errors.New("sequence must be provided")
 	}
@@ -167,7 +167,7 @@ func (p pairList) Less(i, j int) bool {
 }
 
 // sorts a pairList and returns a slice of sorted values
-func (p pairList) sort() interface{} {
+func (p pairList) sort() any {
 	if p.SortAsc {
 		sort.Sort(p)
 	} else {
diff --git a/tpl/collections/sort_test.go b/tpl/collections/sort_test.go
@@ -40,10 +40,10 @@ func TestSort(t *testing.T) {
 	}
 
 	for i, test := range []struct {
-		seq         interface{}
-		sortByField interface{}
+		seq         any
+		sortByField any
 		sortAsc     string
-		expect      interface{}
+		expect      any
 	}{
 		{[]string{"class1", "class2", "class3"}, nil, "asc", []string{"class1", "class2", "class3"}},
 		{[]string{"class3", "class1", "class2"}, nil, "asc", []string{"class1", "class2", "class3"}},
@@ -205,17 +205,17 @@ func TestSort(t *testing.T) {
 		},
 		// interface slice with missing elements
 		{
-			[]interface{}{
-				map[interface{}]interface{}{"Title": "Foo", "Weight": 10},
-				map[interface{}]interface{}{"Title": "Bar"},
-				map[interface{}]interface{}{"Title": "Zap", "Weight": 5},
+			[]any{
+				map[any]any{"Title": "Foo", "Weight": 10},
+				map[any]any{"Title": "Bar"},
+				map[any]any{"Title": "Zap", "Weight": 5},
 			},
 			"Weight",
 			"asc",
-			[]interface{}{
-				map[interface{}]interface{}{"Title": "Bar"},
-				map[interface{}]interface{}{"Title": "Zap", "Weight": 5},
-				map[interface{}]interface{}{"Title": "Foo", "Weight": 10},
+			[]any{
+				map[any]any{"Title": "Bar"},
+				map[any]any{"Title": "Zap", "Weight": 5},
+				map[any]any{"Title": "Foo", "Weight": 10},
 			},
 		},
 		// test boolean values
@@ -239,7 +239,7 @@ func TestSort(t *testing.T) {
 		{nil, nil, "asc", false},
 	} {
 		t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
-			var result interface{}
+			var result any
 			var err error
 			if test.sortByField == nil {
 				result, err = ns.Sort(test.seq)
diff --git a/tpl/collections/symdiff.go b/tpl/collections/symdiff.go
@@ -22,7 +22,7 @@ import (
 
 // SymDiff returns the symmetric difference of s1 and s2.
 // Arguments must be either a slice or an array of comparable types.
-func (ns *Namespace) SymDiff(s2, s1 interface{}) (interface{}, error) {
+func (ns *Namespace) SymDiff(s2, s1 any) (any, error) {
 	ids1, err := collectIdentities(s1)
 	if err != nil {
 		return nil, err
@@ -35,7 +35,7 @@ func (ns *Namespace) SymDiff(s2, s1 interface{}) (interface{}, error) {
 	var slice reflect.Value
 	var sliceElemType reflect.Type
 
-	for i, s := range []interface{}{s1, s2} {
+	for i, s := range []any{s1, s2} {
 		v := reflect.ValueOf(s)
 
 		switch v.Kind() {
diff --git a/tpl/collections/symdiff_test.go b/tpl/collections/symdiff_test.go
@@ -38,13 +38,13 @@ func TestSymDiff(t *testing.T) {
 	sp2 := []*StructWithSlice{xb, xe}
 
 	for i, test := range []struct {
-		s1       interface{}
-		s2       interface{}
-		expected interface{}
+		s1       any
+		s2       any
+		expected any
 	}{
 		{[]string{"a", "x", "b", "c"}, []string{"a", "b", "y", "c"}, []string{"x", "y"}},
 		{[]string{"a", "b", "c"}, []string{"a", "b", "c"}, []string{}},
-		{[]interface{}{"a", "b", nil}, []interface{}{"a"}, []interface{}{"b", nil}},
+		{[]any{"a", "b", nil}, []any{"a"}, []any{"b", nil}},
 		{[]int{1, 2, 3}, []int{3, 4}, []int{1, 2, 4}},
 		{[]int{1, 2, 3}, []int64{3, 4}, []int{1, 2, 4}},
 		{s1, s2, []TstX{{A: "b"}, {A: "e"}}},
diff --git a/tpl/collections/where.go b/tpl/collections/where.go
@@ -24,7 +24,7 @@ import (
 )
 
 // Where returns a filtered subset of a given data type.
-func (ns *Namespace) Where(seq, key interface{}, args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Where(seq, key any, args ...any) (any, error) {
 	seqv, isNil := indirect(reflect.ValueOf(seq))
 	if isNil {
 		return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(seq).Type().String())
@@ -84,7 +84,7 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
 	var ivp, imvp *int64
 	var fvp, fmvp *float64
 	var svp, smvp *string
-	var slv, slmv interface{}
+	var slv, slmv any
 	var ima []int64
 	var fma []float64
 	var sma []string
@@ -353,7 +353,7 @@ func evaluateSubElem(obj reflect.Value, elemName string) (reflect.Value, error) 
 
 // parseWhereArgs parses the end arguments to the where function.  Return a
 // match value and an operator, if one is defined.
-func parseWhereArgs(args ...interface{}) (mv reflect.Value, op string, err error) {
+func parseWhereArgs(args ...any) (mv reflect.Value, op string, err error) {
 	switch len(args) {
 	case 1:
 		mv = reflect.ValueOf(args[0])
@@ -373,7 +373,7 @@ func parseWhereArgs(args ...interface{}) (mv reflect.Value, op string, err error
 
 // checkWhereArray handles the where-matching logic when the seqv value is an
 // Array or Slice.
-func (ns *Namespace) checkWhereArray(seqv, kv, mv reflect.Value, path []string, op string) (interface{}, error) {
+func (ns *Namespace) checkWhereArray(seqv, kv, mv reflect.Value, path []string, op string) (any, error) {
 	rv := reflect.MakeSlice(seqv.Type(), 0, 0)
 
 	for i := 0; i < seqv.Len(); i++ {
@@ -419,7 +419,7 @@ func (ns *Namespace) checkWhereArray(seqv, kv, mv reflect.Value, path []string, 
 }
 
 // checkWhereMap handles the where-matching logic when the seqv value is a Map.
-func (ns *Namespace) checkWhereMap(seqv, kv, mv reflect.Value, path []string, op string) (interface{}, error) {
+func (ns *Namespace) checkWhereMap(seqv, kv, mv reflect.Value, path []string, op string) (any, error) {
 	rv := reflect.MakeMap(seqv.Type())
 	keys := seqv.MapKeys()
 	for _, k := range keys {
diff --git a/tpl/collections/where_test.go b/tpl/collections/where_test.go
@@ -43,11 +43,11 @@ func TestWhere(t *testing.T) {
 	d6 := d5.Add(1 * time.Hour)
 
 	type testt struct {
-		seq    interface{}
-		key    interface{}
+		seq    any
+		key    any
 		op     string
-		match  interface{}
-		expect interface{}
+		match  any
+		expect any
 	}
 
 	createTestVariants := func(test testt) []testt {
@@ -150,11 +150,11 @@ func TestWhere(t *testing.T) {
 		// Issue #8353
 		// String type mismatch.
 		{
-			seq: []map[string]interface{}{
+			seq: []map[string]any{
 				{"a": "1", "b": "2"}, {"a": "3", "b": template.HTML("4")}, {"a": "5", "x": "4"},
 			},
 			key: "b", match: "4",
-			expect: []map[string]interface{}{
+			expect: []map[string]any{
 				{"a": "3", "b": template.HTML("4")},
 			},
 		},
@@ -184,9 +184,9 @@ func TestWhere(t *testing.T) {
 			expect: []TstParams{{params: maps.Params{"i": 1, "color": "blue"}}, {params: maps.Params{"i": 3, "color": "blue"}}},
 		},
 		{
-			seq: []TstParams{{params: maps.Params{"nested": map[string]interface{}{"color": "indigo"}}}, {params: maps.Params{"nested": map[string]interface{}{"color": "blue"}}}},
+			seq: []TstParams{{params: maps.Params{"nested": map[string]any{"color": "indigo"}}}, {params: maps.Params{"nested": map[string]any{"color": "blue"}}}},
 			key: ".Params.NEsTED.COLOR", match: "blue",
-			expect: []TstParams{{params: maps.Params{"nested": map[string]interface{}{"color": "blue"}}}},
+			expect: []TstParams{{params: maps.Params{"nested": map[string]any{"color": "blue"}}}},
 		},
 		{
 			seq: []TstParams{{params: maps.Params{"i": 0, "color": "indigo"}}, {params: maps.Params{"i": 1, "color": "blue"}}, {params: maps.Params{"i": 2, "color": "green"}}, {params: maps.Params{"i": 3, "color": "blue"}}},
@@ -206,12 +206,12 @@ func TestWhere(t *testing.T) {
 		{
 			seq: []maps.Params{
 				{
-					"a": map[string]interface{}{
+					"a": map[string]any{
 						"b": "b1",
 					},
 				},
 				{
-					"a": map[string]interface{}{
+					"a": map[string]any{
 						"b": "b2",
 					},
 				},
@@ -219,7 +219,7 @@ func TestWhere(t *testing.T) {
 			key: "A.B", match: "b2",
 			expect: []maps.Params{
 				{
-					"a": map[string]interface{}{
+					"a": map[string]any{
 						"b": "b2",
 					},
 				},
@@ -598,38 +598,38 @@ func TestWhere(t *testing.T) {
 			expect: false,
 		},
 		{
-			seq: map[string]interface{}{
-				"foo": []interface{}{map[interface{}]interface{}{"a": 1, "b": 2}},
-				"bar": []interface{}{map[interface{}]interface{}{"a": 3, "b": 4}},
-				"zap": []interface{}{map[interface{}]interface{}{"a": 5, "b": 6}},
+			seq: map[string]any{
+				"foo": []any{map[any]any{"a": 1, "b": 2}},
+				"bar": []any{map[any]any{"a": 3, "b": 4}},
+				"zap": []any{map[any]any{"a": 5, "b": 6}},
 			},
 			key: "b", op: "in", match: ns.Slice(3, 4, 5),
-			expect: map[string]interface{}{
-				"bar": []interface{}{map[interface{}]interface{}{"a": 3, "b": 4}},
+			expect: map[string]any{
+				"bar": []any{map[any]any{"a": 3, "b": 4}},
 			},
 		},
 		{
-			seq: map[string]interface{}{
-				"foo": []interface{}{map[interface{}]interface{}{"a": 1, "b": 2}},
-				"bar": []interface{}{map[interface{}]interface{}{"a": 3, "b": 4}},
-				"zap": []interface{}{map[interface{}]interface{}{"a": 5, "b": 6}},
+			seq: map[string]any{
+				"foo": []any{map[any]any{"a": 1, "b": 2}},
+				"bar": []any{map[any]any{"a": 3, "b": 4}},
+				"zap": []any{map[any]any{"a": 5, "b": 6}},
 			},
 			key: "b", op: ">", match: 3,
-			expect: map[string]interface{}{
-				"bar": []interface{}{map[interface{}]interface{}{"a": 3, "b": 4}},
-				"zap": []interface{}{map[interface{}]interface{}{"a": 5, "b": 6}},
+			expect: map[string]any{
+				"bar": []any{map[any]any{"a": 3, "b": 4}},
+				"zap": []any{map[any]any{"a": 5, "b": 6}},
 			},
 		},
 		{
-			seq: map[string]interface{}{
-				"foo": []interface{}{maps.Params{"a": 1, "b": 2}},
-				"bar": []interface{}{maps.Params{"a": 3, "b": 4}},
-				"zap": []interface{}{maps.Params{"a": 5, "b": 6}},
+			seq: map[string]any{
+				"foo": []any{maps.Params{"a": 1, "b": 2}},
+				"bar": []any{maps.Params{"a": 3, "b": 4}},
+				"zap": []any{maps.Params{"a": 5, "b": 6}},
 			},
 			key: "B", op: ">", match: 3,
-			expect: map[string]interface{}{
-				"bar": []interface{}{maps.Params{"a": 3, "b": 4}},
-				"zap": []interface{}{maps.Params{"a": 5, "b": 6}},
+			expect: map[string]any{
+				"bar": []any{maps.Params{"a": 3, "b": 4}},
+				"zap": []any{maps.Params{"a": 5, "b": 6}},
 			},
 		},
 	} {
@@ -639,7 +639,7 @@ func TestWhere(t *testing.T) {
 			name := fmt.Sprintf("%d/%d %T %s %s", i, j, test.seq, test.op, test.key)
 			name = strings.ReplaceAll(name, "[]", "slice-of-")
 			t.Run(name, func(t *testing.T) {
-				var results interface{}
+				var results any
 				var err error
 
 				if len(test.op) > 0 {
@@ -788,10 +788,10 @@ func TestCheckCondition(t *testing.T) {
 		{reflect.ValueOf(123), reflect.ValueOf(123), "op", expect{false, true}},
 
 		// Issue #3718
-		{reflect.ValueOf([]interface{}{"a"}), reflect.ValueOf([]string{"a", "b"}), "intersect", expect{true, false}},
-		{reflect.ValueOf([]string{"a"}), reflect.ValueOf([]interface{}{"a", "b"}), "intersect", expect{true, false}},
-		{reflect.ValueOf([]interface{}{1, 2}), reflect.ValueOf([]int{1}), "intersect", expect{true, false}},
-		{reflect.ValueOf([]int{1}), reflect.ValueOf([]interface{}{1, 2}), "intersect", expect{true, false}},
+		{reflect.ValueOf([]any{"a"}), reflect.ValueOf([]string{"a", "b"}), "intersect", expect{true, false}},
+		{reflect.ValueOf([]string{"a"}), reflect.ValueOf([]any{"a", "b"}), "intersect", expect{true, false}},
+		{reflect.ValueOf([]any{1, 2}), reflect.ValueOf([]int{1}), "intersect", expect{true, false}},
+		{reflect.ValueOf([]int{1}), reflect.ValueOf([]any{1, 2}), "intersect", expect{true, false}},
 	} {
 		result, err := ns.checkCondition(test.value, test.match, test.op)
 		if test.expect.isError {
@@ -822,7 +822,7 @@ func TestEvaluateSubElem(t *testing.T) {
 	for i, test := range []struct {
 		value  reflect.Value
 		key    string
-		expect interface{}
+		expect any
 	}{
 		{reflect.ValueOf(tstx), "A", "foo"},
 		{reflect.ValueOf(&tstx), "TstRp", "rfoo"},
diff --git a/tpl/compare/compare.go b/tpl/compare/compare.go
@@ -40,7 +40,7 @@ type Namespace struct {
 // is not.  "Set" in this context means non-zero for numeric types and times;
 // non-zero length for strings, arrays, slices, and maps;
 // any boolean or struct value; or non-nil for any other types.
-func (*Namespace) Default(dflt interface{}, given ...interface{}) (interface{}, error) {
+func (*Namespace) Default(dflt any, given ...any) (any, error) {
 	// given is variadic because the following construct will not pass a piped
 	// argument when the key is missing:  {{ index . "key" | default "foo" }}
 	// The Go template will complain that we got 1 argument when we expected 2.
@@ -91,12 +91,12 @@ func (*Namespace) Default(dflt interface{}, given ...interface{}) (interface{}, 
 }
 
 // Eq returns the boolean truth of arg1 == arg2 || arg1 == arg3 || arg1 == arg4.
-func (n *Namespace) Eq(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Eq(first any, others ...any) bool {
 	if n.caseInsensitive {
 		panic("caseInsensitive not implemented for Eq")
 	}
 	n.checkComparisonArgCount(1, others...)
-	normalize := func(v interface{}) interface{} {
+	normalize := func(v any) any {
 		if types.IsNil(v) {
 			return nil
 		}
@@ -141,7 +141,7 @@ func (n *Namespace) Eq(first interface{}, others ...interface{}) bool {
 }
 
 // Ne returns the boolean truth of arg1 != arg2 && arg1 != arg3 && arg1 != arg4.
-func (n *Namespace) Ne(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Ne(first any, others ...any) bool {
 	n.checkComparisonArgCount(1, others...)
 	for _, other := range others {
 		if n.Eq(first, other) {
@@ -152,7 +152,7 @@ func (n *Namespace) Ne(first interface{}, others ...interface{}) bool {
 }
 
 // Ge returns the boolean truth of arg1 >= arg2 && arg1 >= arg3 && arg1 >= arg4.
-func (n *Namespace) Ge(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Ge(first any, others ...any) bool {
 	n.checkComparisonArgCount(1, others...)
 	for _, other := range others {
 		left, right := n.compareGet(first, other)
@@ -164,7 +164,7 @@ func (n *Namespace) Ge(first interface{}, others ...interface{}) bool {
 }
 
 // Gt returns the boolean truth of arg1 > arg2 && arg1 > arg3 && arg1 > arg4.
-func (n *Namespace) Gt(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Gt(first any, others ...any) bool {
 	n.checkComparisonArgCount(1, others...)
 	for _, other := range others {
 		left, right := n.compareGet(first, other)
@@ -176,7 +176,7 @@ func (n *Namespace) Gt(first interface{}, others ...interface{}) bool {
 }
 
 // Le returns the boolean truth of arg1 <= arg2 && arg1 <= arg3 && arg1 <= arg4.
-func (n *Namespace) Le(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Le(first any, others ...any) bool {
 	n.checkComparisonArgCount(1, others...)
 	for _, other := range others {
 		left, right := n.compareGet(first, other)
@@ -188,7 +188,7 @@ func (n *Namespace) Le(first interface{}, others ...interface{}) bool {
 }
 
 // Lt returns the boolean truth of arg1 < arg2 && arg1 < arg3 && arg1 < arg4.
-func (n *Namespace) Lt(first interface{}, others ...interface{}) bool {
+func (n *Namespace) Lt(first any, others ...any) bool {
 	n.checkComparisonArgCount(1, others...)
 	for _, other := range others {
 		left, right := n.compareGet(first, other)
@@ -199,7 +199,7 @@ func (n *Namespace) Lt(first interface{}, others ...interface{}) bool {
 	return true
 }
 
-func (n *Namespace) checkComparisonArgCount(min int, others ...interface{}) bool {
+func (n *Namespace) checkComparisonArgCount(min int, others ...any) bool {
 	if len(others) < min {
 		panic("missing arguments for comparison")
 	}
@@ -208,14 +208,14 @@ func (n *Namespace) checkComparisonArgCount(min int, others ...interface{}) bool
 
 // Conditional can be used as a ternary operator.
 // It returns a if condition, else b.
-func (n *Namespace) Conditional(condition bool, a, b interface{}) interface{} {
+func (n *Namespace) Conditional(condition bool, a, b any) any {
 	if condition {
 		return a
 	}
 	return b
 }
 
-func (ns *Namespace) compareGet(a interface{}, b interface{}) (float64, float64) {
+func (ns *Namespace) compareGet(a any, b any) (float64, float64) {
 	if ac, ok := a.(compare.Comparer); ok {
 		c := ac.Compare(b)
 		if c < 0 {
diff --git a/tpl/compare/compare_test.go b/tpl/compare/compare_test.go
@@ -49,7 +49,7 @@ type (
 	tstEqerType2 string
 )
 
-func (t tstEqerType2) Eq(other interface{}) bool {
+func (t tstEqerType2) Eq(other any) bool {
 	return cast.ToString(t) == cast.ToString(other)
 }
 
@@ -57,7 +57,7 @@ func (t tstEqerType2) String() string {
 	return string(t)
 }
 
-func (t tstEqerType1) Eq(other interface{}) bool {
+func (t tstEqerType1) Eq(other any) bool {
 	return cast.ToString(t) == cast.ToString(other)
 }
 
@@ -91,9 +91,9 @@ func TestDefaultFunc(t *testing.T) {
 	ns := New(false)
 
 	for i, test := range []struct {
-		dflt   interface{}
-		given  interface{}
-		expect interface{}
+		dflt   any
+		given  any
+		expect any
 	}{
 		{true, false, false},
 		{"5", 0, "5"},
@@ -149,33 +149,33 @@ func TestCompare(t *testing.T) {
 
 	n := New(false)
 
-	twoEq := func(a, b interface{}) bool {
+	twoEq := func(a, b any) bool {
 		return n.Eq(a, b)
 	}
 
-	twoGt := func(a, b interface{}) bool {
+	twoGt := func(a, b any) bool {
 		return n.Gt(a, b)
 	}
 
-	twoLt := func(a, b interface{}) bool {
+	twoLt := func(a, b any) bool {
 		return n.Lt(a, b)
 	}
 
-	twoGe := func(a, b interface{}) bool {
+	twoGe := func(a, b any) bool {
 		return n.Ge(a, b)
 	}
 
-	twoLe := func(a, b interface{}) bool {
+	twoLe := func(a, b any) bool {
 		return n.Le(a, b)
 	}
 
-	twoNe := func(a, b interface{}) bool {
+	twoNe := func(a, b any) bool {
 		return n.Ne(a, b)
 	}
 
 	for _, test := range []struct {
 		tstCompareType
-		funcUnderTest func(a, b interface{}) bool
+		funcUnderTest func(a, b any) bool
 	}{
 		{tstGt, twoGt},
 		{tstLt, twoLt},
@@ -188,10 +188,10 @@ func TestCompare(t *testing.T) {
 	}
 }
 
-func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b interface{}) bool) {
+func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b any) bool) {
 	for i, test := range []struct {
-		left            interface{}
-		right           interface{}
+		left            any
+		right           any
 		expectIndicator int
 	}{
 		{5, 8, -1},
@@ -272,16 +272,16 @@ func TestEqualExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{1, []interface{}{1, 2}, true},
-		{1, []interface{}{2, 1}, true},
-		{1, []interface{}{2, 3}, false},
-		{tstEqerType1("a"), []interface{}{tstEqerType1("a"), tstEqerType1("b")}, true},
-		{tstEqerType1("a"), []interface{}{tstEqerType1("b"), tstEqerType1("a")}, true},
-		{tstEqerType1("a"), []interface{}{tstEqerType1("b"), tstEqerType1("c")}, false},
+		{1, []any{1, 2}, true},
+		{1, []any{2, 1}, true},
+		{1, []any{2, 3}, false},
+		{tstEqerType1("a"), []any{tstEqerType1("a"), tstEqerType1("b")}, true},
+		{tstEqerType1("a"), []any{tstEqerType1("b"), tstEqerType1("a")}, true},
+		{tstEqerType1("a"), []any{tstEqerType1("b"), tstEqerType1("c")}, false},
 	} {
 
 		result := ns.Eq(test.first, test.others...)
@@ -297,13 +297,13 @@ func TestNotEqualExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{1, []interface{}{2, 3}, true},
-		{1, []interface{}{2, 1}, false},
-		{1, []interface{}{1, 2}, false},
+		{1, []any{2, 3}, true},
+		{1, []any{2, 1}, false},
+		{1, []any{1, 2}, false},
 	} {
 		result := ns.Ne(test.first, test.others...)
 		c.Assert(result, qt.Equals, test.expect)
@@ -317,14 +317,14 @@ func TestGreaterEqualExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{5, []interface{}{2, 3}, true},
-		{5, []interface{}{5, 5}, true},
-		{3, []interface{}{4, 2}, false},
-		{3, []interface{}{2, 4}, false},
+		{5, []any{2, 3}, true},
+		{5, []any{5, 5}, true},
+		{3, []any{4, 2}, false},
+		{3, []any{2, 4}, false},
 	} {
 		result := ns.Ge(test.first, test.others...)
 		c.Assert(result, qt.Equals, test.expect)
@@ -338,13 +338,13 @@ func TestGreaterThanExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{5, []interface{}{2, 3}, true},
-		{5, []interface{}{5, 4}, false},
-		{3, []interface{}{4, 2}, false},
+		{5, []any{2, 3}, true},
+		{5, []any{5, 4}, false},
+		{3, []any{4, 2}, false},
 	} {
 		result := ns.Gt(test.first, test.others...)
 		c.Assert(result, qt.Equals, test.expect)
@@ -358,14 +358,14 @@ func TestLessEqualExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{1, []interface{}{2, 3}, true},
-		{1, []interface{}{1, 2}, true},
-		{2, []interface{}{1, 2}, false},
-		{3, []interface{}{2, 4}, false},
+		{1, []any{2, 3}, true},
+		{1, []any{1, 2}, true},
+		{2, []any{1, 2}, false},
+		{3, []any{2, 4}, false},
 	} {
 		result := ns.Le(test.first, test.others...)
 		c.Assert(result, qt.Equals, test.expect)
@@ -379,14 +379,14 @@ func TestLessThanExtend(t *testing.T) {
 	ns := New(false)
 
 	for _, test := range []struct {
-		first  interface{}
-		others []interface{}
+		first  any
+		others []any
 		expect bool
 	}{
-		{1, []interface{}{2, 3}, true},
-		{1, []interface{}{1, 2}, false},
-		{2, []interface{}{1, 2}, false},
-		{3, []interface{}{2, 4}, false},
+		{1, []any{2, 3}, true},
+		{1, []any{1, 2}, false},
+		{2, []any{1, 2}, false},
+		{3, []any{2, 4}, false},
 	} {
 		result := ns.Lt(test.first, test.others...)
 		c.Assert(result, qt.Equals, test.expect)
diff --git a/tpl/compare/init.go b/tpl/compare/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Default,
diff --git a/tpl/crypto/crypto.go b/tpl/crypto/crypto.go
@@ -36,7 +36,7 @@ func New() *Namespace {
 type Namespace struct{}
 
 // MD5 hashes the given input and returns its MD5 checksum.
-func (ns *Namespace) MD5(in interface{}) (string, error) {
+func (ns *Namespace) MD5(in any) (string, error) {
 	conv, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
@@ -47,7 +47,7 @@ func (ns *Namespace) MD5(in interface{}) (string, error) {
 }
 
 // SHA1 hashes the given input and returns its SHA1 checksum.
-func (ns *Namespace) SHA1(in interface{}) (string, error) {
+func (ns *Namespace) SHA1(in any) (string, error) {
 	conv, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
@@ -58,7 +58,7 @@ func (ns *Namespace) SHA1(in interface{}) (string, error) {
 }
 
 // SHA256 hashes the given input and returns its SHA256 checksum.
-func (ns *Namespace) SHA256(in interface{}) (string, error) {
+func (ns *Namespace) SHA256(in any) (string, error) {
 	conv, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
@@ -69,7 +69,7 @@ func (ns *Namespace) SHA256(in interface{}) (string, error) {
 }
 
 // HMAC returns a cryptographic hash that uses a key to sign a message.
-func (ns *Namespace) HMAC(h interface{}, k interface{}, m interface{}) (string, error) {
+func (ns *Namespace) HMAC(h any, k any, m any) (string, error) {
 	ha, err := cast.ToStringE(h)
 	if err != nil {
 		return "", err
diff --git a/tpl/crypto/crypto_test.go b/tpl/crypto/crypto_test.go
@@ -26,8 +26,8 @@ func TestMD5(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		in     interface{}
-		expect interface{}
+		in     any
+		expect any
 	}{
 		{"Hello world, gophers!", "b3029f756f98f79e7f1b7f1d1f0dd53b"},
 		{"Lorem ipsum dolor", "06ce65ac476fc656bea3fca5d02cfd81"},
@@ -53,8 +53,8 @@ func TestSHA1(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		in     interface{}
-		expect interface{}
+		in     any
+		expect any
 	}{
 		{"Hello world, gophers!", "c8b5b0e33d408246e30f53e32b8f7627a7a649d4"},
 		{"Lorem ipsum dolor", "45f75b844be4d17b3394c6701768daf39419c99b"},
@@ -80,8 +80,8 @@ func TestSHA256(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		in     interface{}
-		expect interface{}
+		in     any
+		expect any
 	}{
 		{"Hello world, gophers!", "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46"},
 		{"Lorem ipsum dolor", "9b3e1beb7053e0f900a674dd1c99aca3355e1275e1b03d3cb1bc977f5154e196"},
@@ -107,10 +107,10 @@ func TestHMAC(t *testing.T) {
 	ns := New()
 
 	for i, test := range []struct {
-		hash   interface{}
-		key    interface{}
-		msg    interface{}
-		expect interface{}
+		hash   any
+		key    any
+		msg    any
+		expect any
 	}{
 		{"md5", "Secret key", "Hello world, gophers!", "36eb69b6bf2de96b6856fdee8bf89754"},
 		{"sha1", "Secret key", "Hello world, gophers!", "84a76647de6cd47ac6ae4258e3753f711172ce68"},
diff --git a/tpl/crypto/init.go b/tpl/crypto/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.MD5,
diff --git a/tpl/data/data.go b/tpl/data/data.go
@@ -63,7 +63,7 @@ type Namespace struct {
 // The data separator can be a comma, semi-colon, pipe, etc, but only one character.
 // If you provide multiple parts for the URL they will be joined together to the final URL.
 // GetCSV returns nil or a slice slice to use in a short code.
-func (ns *Namespace) GetCSV(sep string, args ...interface{}) (d [][]string, err error) {
+func (ns *Namespace) GetCSV(sep string, args ...any) (d [][]string, err error) {
 	url, headers := toURLAndHeaders(args)
 	cache := ns.cacheGetCSV
 
@@ -102,8 +102,8 @@ func (ns *Namespace) GetCSV(sep string, args ...interface{}) (d [][]string, err 
 // GetJSON expects one or n-parts of a URL to a resource which can either be a local or a remote one.
 // If you provide multiple parts they will be joined together to the final URL.
 // GetJSON returns nil or parsed JSON to use in a short code.
-func (ns *Namespace) GetJSON(args ...interface{}) (interface{}, error) {
-	var v interface{}
+func (ns *Namespace) GetJSON(args ...any) (any, error) {
+	var v any
 	url, headers := toURLAndHeaders(args)
 	cache := ns.cacheGetJSON
 
@@ -146,7 +146,7 @@ func addDefaultHeaders(req *http.Request, accepts ...string) {
 	}
 }
 
-func addUserProvidedHeaders(headers map[string]interface{}, req *http.Request) {
+func addUserProvidedHeaders(headers map[string]any, req *http.Request) {
 	if headers == nil {
 		return
 	}
@@ -179,7 +179,7 @@ func hasHeaderKey(m http.Header, key string) bool {
 	return ok
 }
 
-func toURLAndHeaders(urlParts []interface{}) (string, map[string]interface{}) {
+func toURLAndHeaders(urlParts []any) (string, map[string]any) {
 	if len(urlParts) == 0 {
 		return "", nil
 	}
diff --git a/tpl/data/data_test.go b/tpl/data/data_test.go
@@ -35,7 +35,7 @@ func TestGetCSV(t *testing.T) {
 		sep     string
 		url     string
 		content string
-		expect  interface{}
+		expect  any
 	}{
 		// Remotes
 		{
@@ -129,12 +129,12 @@ func TestGetJSON(t *testing.T) {
 	for i, test := range []struct {
 		url     string
 		content string
-		expect  interface{}
+		expect  any
 	}{
 		{
 			`http://success/`,
 			`{"gomeetup":["Sydney","San Francisco","Stockholm"]}`,
-			map[string]interface{}{"gomeetup": []interface{}{"Sydney", "San Francisco", "Stockholm"}},
+			map[string]any{"gomeetup": []any{"Sydney", "San Francisco", "Stockholm"}},
 		},
 		{
 			`http://malformed/`,
@@ -150,7 +150,7 @@ func TestGetJSON(t *testing.T) {
 		{
 			"pass/semi",
 			`{"gomeetup":["Sydney","San Francisco","Stockholm"]}`,
-			map[string]interface{}{"gomeetup": []interface{}{"Sydney", "San Francisco", "Stockholm"}},
+			map[string]any{"gomeetup": []any{"Sydney", "San Francisco", "Stockholm"}},
 		},
 		{
 			"fail/no-file",
@@ -160,7 +160,7 @@ func TestGetJSON(t *testing.T) {
 		{
 			`pass/üńīçøðê-url.json`,
 			`{"gomeetup":["Sydney","San Francisco","Stockholm"]}`,
-			map[string]interface{}{"gomeetup": []interface{}{"Sydney", "San Francisco", "Stockholm"}},
+			map[string]any{"gomeetup": []any{"Sydney", "San Francisco", "Stockholm"}},
 		},
 	} {
 
@@ -218,12 +218,12 @@ func TestHeaders(t *testing.T) {
 
 	for _, test := range []struct {
 		name    string
-		headers interface{}
+		headers any
 		assert  func(c *qt.C, headers string)
 	}{
 		{
 			`Misc header variants`,
-			map[string]interface{}{
+			map[string]any{
 				"Accept-Charset": "utf-8",
 				"Max-forwards":   "10",
 				"X-Int":          32,
@@ -254,7 +254,7 @@ func TestHeaders(t *testing.T) {
 		},
 		{
 			`Override User-Agent`,
-			map[string]interface{}{
+			map[string]any{
 				"User-Agent": "007",
 			},
 			func(c *qt.C, headers string) {
@@ -278,7 +278,7 @@ func TestHeaders(t *testing.T) {
 			})
 			defer func() { srv.Close() }()
 
-			testFunc := func(fn func(args ...interface{}) error) {
+			testFunc := func(fn func(args ...any) error) {
 				defer headers.Reset()
 				err := fn("http://example.org/api", "?foo", test.headers)
 
@@ -287,11 +287,11 @@ func TestHeaders(t *testing.T) {
 				test.assert(c, headers.String())
 			}
 
-			testFunc(func(args ...interface{}) error {
+			testFunc(func(args ...any) error {
 				_, err := ns.GetJSON(args...)
 				return err
 			})
-			testFunc(func(args ...interface{}) error {
+			testFunc(func(args ...any) error {
 				_, err := ns.GetCSV(",", args...)
 				return err
 			})
@@ -304,13 +304,13 @@ func TestHeaders(t *testing.T) {
 func TestToURLAndHeaders(t *testing.T) {
 	t.Parallel()
 	c := qt.New(t)
-	url, headers := toURLAndHeaders([]interface{}{"https://foo?id=", 32})
+	url, headers := toURLAndHeaders([]any{"https://foo?id=", 32})
 	c.Assert(url, qt.Equals, "https://foo?id=32")
 	c.Assert(headers, qt.IsNil)
 
-	url, headers = toURLAndHeaders([]interface{}{"https://foo?id=", 32, map[string]interface{}{"a": "b"}})
+	url, headers = toURLAndHeaders([]any{"https://foo?id=", 32, map[string]any{"a": "b"}})
 	c.Assert(url, qt.Equals, "https://foo?id=32")
-	c.Assert(headers, qt.DeepEquals, map[string]interface{}{"a": "b"})
+	c.Assert(headers, qt.DeepEquals, map[string]any{"a": "b"})
 }
 
 func TestParseCSV(t *testing.T) {
diff --git a/tpl/data/init.go b/tpl/data/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.GetCSV,
diff --git a/tpl/data/resources.go b/tpl/data/resources.go
@@ -44,7 +44,7 @@ func (ns *Namespace) getRemote(cache *filecache.Cache, unmarshal func([]byte) (b
 	if err := ns.deps.ExecHelper.Sec().CheckAllowedHTTPMethod("GET"); err != nil {
 		return err
 	}
-	
+
 	var headers bytes.Buffer
 	req.Header.Write(&headers)
 	id := helpers.MD5String(url + headers.String())
diff --git a/tpl/debug/debug.go b/tpl/debug/debug.go
@@ -35,6 +35,6 @@ type Namespace struct {
 // nicely.
 // Also note that the output from Dump may change from Hugo version to the next,
 // so don't depend on a specific output.
-func (ns *Namespace) Dump(val interface{}) string {
+func (ns *Namespace) Dump(val any) string {
 	return litter.Sdump(val)
 }
diff --git a/tpl/debug/init.go b/tpl/debug/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Dump,
diff --git a/tpl/diagrams/diagrams.go b/tpl/diagrams/diagrams.go
@@ -63,7 +63,7 @@ type Diagrams struct {
 	d *deps.Deps
 }
 
-func (d *Diagrams) Goat(v interface{}) SVGDiagram {
+func (d *Diagrams) Goat(v any) SVGDiagram {
 	var r io.Reader
 
 	switch vv := v.(type) {
diff --git a/tpl/diagrams/init.go b/tpl/diagrams/init.go
@@ -28,7 +28,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		return ns
diff --git a/tpl/encoding/encoding.go b/tpl/encoding/encoding.go
@@ -33,7 +33,7 @@ func New() *Namespace {
 type Namespace struct{}
 
 // Base64Decode returns the base64 decoding of the given content.
-func (ns *Namespace) Base64Decode(content interface{}) (string, error) {
+func (ns *Namespace) Base64Decode(content any) (string, error) {
 	conv, err := cast.ToStringE(content)
 	if err != nil {
 		return "", err
@@ -44,7 +44,7 @@ func (ns *Namespace) Base64Decode(content interface{}) (string, error) {
 }
 
 // Base64Encode returns the base64 encoding of the given content.
-func (ns *Namespace) Base64Encode(content interface{}) (string, error) {
+func (ns *Namespace) Base64Encode(content any) (string, error) {
 	conv, err := cast.ToStringE(content)
 	if err != nil {
 		return "", err
@@ -58,7 +58,7 @@ func (ns *Namespace) Base64Encode(content interface{}) (string, error) {
 // "prefix" and "indent".  Each JSON element in the output will begin on a new
 // line beginning with prefix followed by one or more copies of indent according
 // to the indentation nesting.
-func (ns *Namespace) Jsonify(args ...interface{}) (template.HTML, error) {
+func (ns *Namespace) Jsonify(args ...any) (template.HTML, error) {
 	var (
 		b   []byte
 		err error
diff --git a/tpl/encoding/encoding_test.go b/tpl/encoding/encoding_test.go
@@ -30,8 +30,8 @@ func TestBase64Decode(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{"YWJjMTIzIT8kKiYoKSctPUB+", "abc123!?$*&()'-=@~"},
 		// errors
@@ -57,8 +57,8 @@ func TestBase64Encode(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{"YWJjMTIzIT8kKiYoKSctPUB+", "WVdKak1USXpJVDhrS2lZb0tTY3RQVUIr"},
 		// errors
@@ -83,9 +83,9 @@ func TestJsonify(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		opts   interface{}
-		v      interface{}
-		expect interface{}
+		opts   any
+		v      any
+		expect any
 	}{
 		{nil, []string{"a", "b"}, template.HTML(`["a","b"]`)},
 		{map[string]string{"indent": "<i>"}, []string{"a", "b"}, template.HTML("[\n<i>\"a\",\n<i>\"b\"\n]")},
@@ -97,7 +97,7 @@ func TestJsonify(t *testing.T) {
 		{nil, math.NaN(), false},
 		{tstNoStringer{}, []string{"a", "b"}, false},
 	} {
-		args := []interface{}{}
+		args := []any{}
 
 		if test.opts != nil {
 			args = append(args, test.opts)
diff --git a/tpl/encoding/init.go b/tpl/encoding/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Base64Decode,
diff --git a/tpl/fmt/fmt.go b/tpl/fmt/fmt.go
@@ -48,23 +48,23 @@ type Namespace struct {
 }
 
 // Print returns string representation of the passed arguments.
-func (ns *Namespace) Print(a ...interface{}) string {
+func (ns *Namespace) Print(a ...any) string {
 	return _fmt.Sprint(a...)
 }
 
 // Printf returns a formatted string representation of the passed arguments.
-func (ns *Namespace) Printf(format string, a ...interface{}) string {
+func (ns *Namespace) Printf(format string, a ...any) string {
 	return _fmt.Sprintf(format, a...)
 }
 
 // Println returns string representation of the passed arguments ending with a newline.
-func (ns *Namespace) Println(a ...interface{}) string {
+func (ns *Namespace) Println(a ...any) string {
 	return _fmt.Sprintln(a...)
 }
 
 // Errorf formats according to a format specifier and logs an ERROR.
 // It returns an empty string.
-func (ns *Namespace) Errorf(format string, a ...interface{}) string {
+func (ns *Namespace) Errorf(format string, a ...any) string {
 	ns.distinctLogger.Errorf(format, a...)
 	return ""
 }
@@ -72,14 +72,14 @@ func (ns *Namespace) Errorf(format string, a ...interface{}) string {
 // Erroridf formats according to a format specifier and logs an ERROR and
 // an information text that the error with the given ID can be suppressed in config.
 // It returns an empty string.
-func (ns *Namespace) Erroridf(id, format string, a ...interface{}) string {
+func (ns *Namespace) Erroridf(id, format string, a ...any) string {
 	ns.distinctLogger.Errorsf(id, format, a...)
 	return ""
 }
 
 // Warnf formats according to a format specifier and logs a WARNING.
 // It returns an empty string.
-func (ns *Namespace) Warnf(format string, a ...interface{}) string {
+func (ns *Namespace) Warnf(format string, a ...any) string {
 	ns.distinctLogger.Warnf(format, a...)
 	return ""
 }
diff --git a/tpl/fmt/init.go b/tpl/fmt/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Print,
diff --git a/tpl/hugo/init.go b/tpl/hugo/init.go
@@ -27,7 +27,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return h, nil },
+			Context: func(args ...any) (any, error) { return h, nil },
 		}
 
 		// We just add the Hugo struct as the namespace here. No method mappings.
diff --git a/tpl/images/images.go b/tpl/images/images.go
@@ -55,7 +55,7 @@ type Namespace struct {
 
 // Config returns the image.Config for the specified path relative to the
 // working directory.
-func (ns *Namespace) Config(path interface{}) (image.Config, error) {
+func (ns *Namespace) Config(path any) (image.Config, error) {
 	filename, err := cast.ToStringE(path)
 	if err != nil {
 		return image.Config{}, err
@@ -92,7 +92,7 @@ func (ns *Namespace) Config(path interface{}) (image.Config, error) {
 	return config, nil
 }
 
-func (ns *Namespace) Filter(args ...interface{}) (resource.Image, error) {
+func (ns *Namespace) Filter(args ...any) (resource.Image, error) {
 	if len(args) < 2 {
 		return nil, errors.New("must provide an image and one or more filters")
 	}
diff --git a/tpl/images/images_test.go b/tpl/images/images_test.go
@@ -32,9 +32,9 @@ import (
 type tstNoStringer struct{}
 
 var configTests = []struct {
-	path   interface{}
+	path   any
 	input  []byte
-	expect interface{}
+	expect any
 }{
 	{
 		path:  "a.png",
diff --git a/tpl/images/init.go b/tpl/images/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Config,
diff --git a/tpl/inflect/inflect.go b/tpl/inflect/inflect.go
@@ -38,7 +38,7 @@ type Namespace struct{}
 //     Example:  "my-first-post" -> "My first post"
 //     Example:  "103" -> "103rd"
 //     Example:  52 -> "52nd"
-func (ns *Namespace) Humanize(in interface{}) (string, error) {
+func (ns *Namespace) Humanize(in any) (string, error) {
 	word, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
@@ -59,7 +59,7 @@ func (ns *Namespace) Humanize(in interface{}) (string, error) {
 }
 
 // Pluralize returns the plural form of a single word.
-func (ns *Namespace) Pluralize(in interface{}) (string, error) {
+func (ns *Namespace) Pluralize(in any) (string, error) {
 	word, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
@@ -69,7 +69,7 @@ func (ns *Namespace) Pluralize(in interface{}) (string, error) {
 }
 
 // Singularize returns the singular form of a single word.
-func (ns *Namespace) Singularize(in interface{}) (string, error) {
+func (ns *Namespace) Singularize(in any) (string, error) {
 	word, err := cast.ToStringE(in)
 	if err != nil {
 		return "", err
diff --git a/tpl/inflect/inflect_test.go b/tpl/inflect/inflect_test.go
@@ -13,9 +13,9 @@ func TestInflect(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		fn     func(i interface{}) (string, error)
-		in     interface{}
-		expect interface{}
+		fn     func(i any) (string, error)
+		in     any
+		expect any
 	}{
 		{ns.Humanize, "MyCamel", "My camel"},
 		{ns.Humanize, "óbito", "Óbito"},
diff --git a/tpl/inflect/init.go b/tpl/inflect/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Humanize,
diff --git a/tpl/internal/go_templates/texttemplate/hugo_template.go b/tpl/internal/go_templates/texttemplate/hugo_template.go
@@ -48,7 +48,7 @@ type ExecHelper interface {
 
 // Executer executes a given template.
 type Executer interface {
-	ExecuteWithContext(ctx context.Context, p Preparer, wr io.Writer, data interface{}) error
+	ExecuteWithContext(ctx context.Context, p Preparer, wr io.Writer, data any) error
 }
 
 type executer struct {
@@ -72,7 +72,7 @@ const (
 )
 
 // Note: The context is currently not fully implemeted in Hugo. This is a work in progress.
-func (t *executer) ExecuteWithContext(ctx context.Context, p Preparer, wr io.Writer, data interface{}) error {
+func (t *executer) ExecuteWithContext(ctx context.Context, p Preparer, wr io.Writer, data any) error {
 	tmpl, err := p.Prepare()
 	if err != nil {
 		return err
@@ -101,7 +101,7 @@ func (t *executer) ExecuteWithContext(ctx context.Context, p Preparer, wr io.Wri
 	return tmpl.executeWithState(state, value)
 }
 
-func (t *executer) Execute(p Preparer, wr io.Writer, data interface{}) error {
+func (t *executer) Execute(p Preparer, wr io.Writer, data any) error {
 	tmpl, err := p.Prepare()
 	if err != nil {
 		return err
diff --git a/tpl/internal/resourcehelpers/helpers.go b/tpl/internal/resourcehelpers/helpers.go
@@ -26,7 +26,7 @@ import (
 )
 
 // We allow string or a map as the first argument in some cases.
-func ResolveIfFirstArgIsString(args []interface{}) (resources.ResourceTransformer, string, bool) {
+func ResolveIfFirstArgIsString(args []any) (resources.ResourceTransformer, string, bool) {
 	if len(args) != 2 {
 		return nil, "", false
 	}
@@ -41,7 +41,7 @@ func ResolveIfFirstArgIsString(args []interface{}) (resources.ResourceTransforme
 }
 
 // This roundabout way of doing it is needed to get both pipeline behaviour and options as arguments.
-func ResolveArgs(args []interface{}) (resources.ResourceTransformer, map[string]interface{}, error) {
+func ResolveArgs(args []any) (resources.ResourceTransformer, map[string]any, error) {
 	if len(args) == 0 {
 		return nil, nil, errors.New("no Resource provided in transformation")
 	}
@@ -56,7 +56,7 @@ func ResolveArgs(args []interface{}) (resources.ResourceTransformer, map[string]
 
 	r, ok := args[1].(resources.ResourceTransformer)
 	if !ok {
-		if _, ok := args[1].(map[string]interface{}); !ok {
+		if _, ok := args[1].(map[string]any); !ok {
 			return nil, nil, fmt.Errorf("no Resource provided in transformation")
 		}
 		return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
diff --git a/tpl/internal/templatefuncsRegistry.go b/tpl/internal/templatefuncsRegistry.go
@@ -49,7 +49,7 @@ type TemplateFuncsNamespace struct {
 	Name string
 
 	// This is the method receiver.
-	Context func(v ...interface{}) (interface{}, error)
+	Context func(v ...any) (any, error)
 
 	// Additional info, aliases and examples, per method name.
 	MethodMappings map[string]TemplateFuncMethodMapping
@@ -59,7 +59,7 @@ type TemplateFuncsNamespace struct {
 type TemplateFuncsNamespaces []*TemplateFuncsNamespace
 
 // AddMethodMapping adds a method to a template function namespace.
-func (t *TemplateFuncsNamespace) AddMethodMapping(m interface{}, aliases []string, examples [][2]string) {
+func (t *TemplateFuncsNamespace) AddMethodMapping(m any, aliases []string, examples [][2]string) {
 	if t.MethodMappings == nil {
 		t.MethodMappings = make(map[string]TemplateFuncMethodMapping)
 	}
@@ -88,7 +88,7 @@ func (t *TemplateFuncsNamespace) AddMethodMapping(m interface{}, aliases []strin
 // TemplateFuncMethodMapping represents a mapping of functions to methods for a
 // given namespace.
 type TemplateFuncMethodMapping struct {
-	Method interface{}
+	Method any
 
 	// Any template funcs aliases. This is mainly motivated by keeping
 	// backwards compatibility, but some new template funcs may also make
@@ -104,7 +104,7 @@ type TemplateFuncMethodMapping struct {
 	Examples [][2]string
 }
 
-func methodToName(m interface{}) string {
+func methodToName(m any) string {
 	name := runtime.FuncForPC(reflect.ValueOf(m).Pointer()).Name()
 	name = filepath.Ext(name)
 	name = strings.TrimPrefix(name, ".")
diff --git a/tpl/js/init.go b/tpl/js/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		return ns
diff --git a/tpl/js/js.go b/tpl/js/js.go
@@ -39,10 +39,10 @@ type Namespace struct {
 }
 
 // Build processes the given Resource with ESBuild.
-func (ns *Namespace) Build(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) Build(args ...any) (resource.Resource, error) {
 	var (
 		r          resources.ResourceTransformer
-		m          map[string]interface{}
+		m          map[string]any
 		targetPath string
 		err        error
 		ok         bool
@@ -58,7 +58,7 @@ func (ns *Namespace) Build(args ...interface{}) (resource.Resource, error) {
 	}
 
 	if targetPath != "" {
-		m = map[string]interface{}{"targetPath": targetPath}
+		m = map[string]any{"targetPath": targetPath}
 	}
 
 	return ns.client.Process(r, m)
diff --git a/tpl/lang/init.go b/tpl/lang/init.go
@@ -27,7 +27,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Translate,
diff --git a/tpl/lang/lang.go b/tpl/lang/lang.go
@@ -43,8 +43,8 @@ type Namespace struct {
 }
 
 // Translate returns a translated string for id.
-func (ns *Namespace) Translate(id interface{}, args ...interface{}) (string, error) {
-	var templateData interface{}
+func (ns *Namespace) Translate(id any, args ...any) (string, error) {
+	var templateData any
 
 	if len(args) > 0 {
 		if len(args) > 1 {
@@ -62,7 +62,7 @@ func (ns *Namespace) Translate(id interface{}, args ...interface{}) (string, err
 }
 
 // FormatNumber formats number with the given precision for the current language.
-func (ns *Namespace) FormatNumber(precision, number interface{}) (string, error) {
+func (ns *Namespace) FormatNumber(precision, number any) (string, error) {
 	p, n, err := ns.castPrecisionNumber(precision, number)
 	if err != nil {
 		return "", err
@@ -72,7 +72,7 @@ func (ns *Namespace) FormatNumber(precision, number interface{}) (string, error)
 
 // FormatPercent formats number with the given precision for the current language.
 // Note that the number is assumed to be a percentage.
-func (ns *Namespace) FormatPercent(precision, number interface{}) (string, error) {
+func (ns *Namespace) FormatPercent(precision, number any) (string, error) {
 	p, n, err := ns.castPrecisionNumber(precision, number)
 	if err != nil {
 		return "", err
@@ -84,7 +84,7 @@ func (ns *Namespace) FormatPercent(precision, number interface{}) (string, error
 // for the current language.
 //
 // The return value is formatted with at least two decimal places.
-func (ns *Namespace) FormatCurrency(precision, currency, number interface{}) (string, error) {
+func (ns *Namespace) FormatCurrency(precision, currency, number any) (string, error) {
 	p, n, err := ns.castPrecisionNumber(precision, number)
 	if err != nil {
 		return "", err
@@ -100,7 +100,7 @@ func (ns *Namespace) FormatCurrency(precision, currency, number interface{}) (st
 // for the current language in accounting notation.
 //
 // The return value is formatted with at least two decimal places.
-func (ns *Namespace) FormatAccounting(precision, currency, number interface{}) (string, error) {
+func (ns *Namespace) FormatAccounting(precision, currency, number any) (string, error) {
 	p, n, err := ns.castPrecisionNumber(precision, number)
 	if err != nil {
 		return "", err
@@ -112,7 +112,7 @@ func (ns *Namespace) FormatAccounting(precision, currency, number interface{}) (
 	return ns.translator.FmtAccounting(n, p, c), nil
 }
 
-func (ns *Namespace) castPrecisionNumber(precision, number interface{}) (uint64, float64, error) {
+func (ns *Namespace) castPrecisionNumber(precision, number any) (uint64, float64, error) {
 	p, err := cast.ToUint64E(precision)
 	if err != nil {
 		return 0, 0, err
@@ -139,7 +139,7 @@ func (ns *Namespace) castPrecisionNumber(precision, number interface{}) (uint64,
 // So, with precision set to 0, 1.5 becomes `2`, and 1.4 becomes `1`.
 //
 // For a simpler function that adapts to the current language, see FormatNumber.
-func (ns *Namespace) FormatNumberCustom(precision, number interface{}, options ...interface{}) (string, error) {
+func (ns *Namespace) FormatNumberCustom(precision, number any, options ...any) (string, error) {
 	prec, err := cast.ToIntE(precision)
 	if err != nil {
 		return "", err
@@ -240,16 +240,16 @@ func (ns *Namespace) FormatNumberCustom(precision, number interface{}, options .
 // NumFmt is deprecated, use FormatNumberCustom.
 // We renamed this in Hugo 0.87.
 // Deprecated: Use FormatNumberCustom
-func (ns *Namespace) NumFmt(precision, number interface{}, options ...interface{}) (string, error) {
+func (ns *Namespace) NumFmt(precision, number any, options ...any) (string, error) {
 	return ns.FormatNumberCustom(precision, number, options...)
 }
 
 type pagesLanguageMerger interface {
-	MergeByLanguageInterface(other interface{}) (interface{}, error)
+	MergeByLanguageInterface(other any) (any, error)
 }
 
 // Merge creates a union of pages from two languages.
-func (ns *Namespace) Merge(p2, p1 interface{}) (interface{}, error) {
+func (ns *Namespace) Merge(p2, p1 any) (any, error) {
 	merger, ok := p1.(pagesLanguageMerger)
 	if !ok {
 		return nil, fmt.Errorf("language merge not supported for %T", p1)
diff --git a/tpl/math/init.go b/tpl/math/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Add,
diff --git a/tpl/math/math.go b/tpl/math/math.go
@@ -33,12 +33,12 @@ func New() *Namespace {
 type Namespace struct{}
 
 // Add adds two numbers.
-func (ns *Namespace) Add(a, b interface{}) (interface{}, error) {
+func (ns *Namespace) Add(a, b any) (any, error) {
 	return _math.DoArithmetic(a, b, '+')
 }
 
 // Ceil returns the least integer value greater than or equal to x.
-func (ns *Namespace) Ceil(x interface{}) (float64, error) {
+func (ns *Namespace) Ceil(x any) (float64, error) {
 	xf, err := cast.ToFloat64E(x)
 	if err != nil {
 		return 0, errors.New("Ceil operator can't be used with non-float value")
@@ -48,12 +48,12 @@ func (ns *Namespace) Ceil(x interface{}) (float64, error) {
 }
 
 // Div divides two numbers.
-func (ns *Namespace) Div(a, b interface{}) (interface{}, error) {
+func (ns *Namespace) Div(a, b any) (any, error) {
 	return _math.DoArithmetic(a, b, '/')
 }
 
 // Floor returns the greatest integer value less than or equal to x.
-func (ns *Namespace) Floor(x interface{}) (float64, error) {
+func (ns *Namespace) Floor(x any) (float64, error) {
 	xf, err := cast.ToFloat64E(x)
 	if err != nil {
 		return 0, errors.New("Floor operator can't be used with non-float value")
@@ -63,7 +63,7 @@ func (ns *Namespace) Floor(x interface{}) (float64, error) {
 }
 
 // Log returns the natural logarithm of a number.
-func (ns *Namespace) Log(a interface{}) (float64, error) {
+func (ns *Namespace) Log(a any) (float64, error) {
 	af, err := cast.ToFloat64E(a)
 	if err != nil {
 		return 0, errors.New("Log operator can't be used with non integer or float value")
@@ -73,7 +73,7 @@ func (ns *Namespace) Log(a interface{}) (float64, error) {
 }
 
 // Max returns the greater of two numbers.
-func (ns *Namespace) Max(a, b interface{}) (float64, error) {
+func (ns *Namespace) Max(a, b any) (float64, error) {
 	af, erra := cast.ToFloat64E(a)
 	bf, errb := cast.ToFloat64E(b)
 
@@ -85,7 +85,7 @@ func (ns *Namespace) Max(a, b interface{}) (float64, error) {
 }
 
 // Min returns the smaller of two numbers.
-func (ns *Namespace) Min(a, b interface{}) (float64, error) {
+func (ns *Namespace) Min(a, b any) (float64, error) {
 	af, erra := cast.ToFloat64E(a)
 	bf, errb := cast.ToFloat64E(b)
 
@@ -97,7 +97,7 @@ func (ns *Namespace) Min(a, b interface{}) (float64, error) {
 }
 
 // Mod returns a % b.
-func (ns *Namespace) Mod(a, b interface{}) (int64, error) {
+func (ns *Namespace) Mod(a, b any) (int64, error) {
 	ai, erra := cast.ToInt64E(a)
 	bi, errb := cast.ToInt64E(b)
 
@@ -113,7 +113,7 @@ func (ns *Namespace) Mod(a, b interface{}) (int64, error) {
 }
 
 // ModBool returns the boolean of a % b.  If a % b == 0, return true.
-func (ns *Namespace) ModBool(a, b interface{}) (bool, error) {
+func (ns *Namespace) ModBool(a, b any) (bool, error) {
 	res, err := ns.Mod(a, b)
 	if err != nil {
 		return false, err
@@ -123,12 +123,12 @@ func (ns *Namespace) ModBool(a, b interface{}) (bool, error) {
 }
 
 // Mul multiplies two numbers.
-func (ns *Namespace) Mul(a, b interface{}) (interface{}, error) {
+func (ns *Namespace) Mul(a, b any) (any, error) {
 	return _math.DoArithmetic(a, b, '*')
 }
 
 // Pow returns a raised to the power of b.
-func (ns *Namespace) Pow(a, b interface{}) (float64, error) {
+func (ns *Namespace) Pow(a, b any) (float64, error) {
 	af, erra := cast.ToFloat64E(a)
 	bf, errb := cast.ToFloat64E(b)
 
@@ -140,7 +140,7 @@ func (ns *Namespace) Pow(a, b interface{}) (float64, error) {
 }
 
 // Round returns the nearest integer, rounding half away from zero.
-func (ns *Namespace) Round(x interface{}) (float64, error) {
+func (ns *Namespace) Round(x any) (float64, error) {
 	xf, err := cast.ToFloat64E(x)
 	if err != nil {
 		return 0, errors.New("Round operator can't be used with non-float value")
@@ -150,7 +150,7 @@ func (ns *Namespace) Round(x interface{}) (float64, error) {
 }
 
 // Sqrt returns the square root of a number.
-func (ns *Namespace) Sqrt(a interface{}) (float64, error) {
+func (ns *Namespace) Sqrt(a any) (float64, error) {
 	af, err := cast.ToFloat64E(a)
 	if err != nil {
 		return 0, errors.New("Sqrt operator can't be used with non integer or float value")
@@ -160,7 +160,7 @@ func (ns *Namespace) Sqrt(a interface{}) (float64, error) {
 }
 
 // Sub subtracts two numbers.
-func (ns *Namespace) Sub(a, b interface{}) (interface{}, error) {
+func (ns *Namespace) Sub(a, b any) (any, error) {
 	return _math.DoArithmetic(a, b, '-')
 }
 
diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go
@@ -27,10 +27,10 @@ func TestBasicNSArithmetic(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		fn     func(a, b interface{}) (interface{}, error)
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		fn     func(a, b any) (any, error)
+		a      any
+		b      any
+		expect any
 	}{
 		{ns.Add, 4, 2, int64(6)},
 		{ns.Add, 1.0, "foo", false},
@@ -60,8 +60,8 @@ func TestCeil(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		x      interface{}
-		expect interface{}
+		x      any
+		expect any
 	}{
 		{0.1, 1.0},
 		{0.5, 1.0},
@@ -93,8 +93,8 @@ func TestFloor(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		x      interface{}
-		expect interface{}
+		x      any
+		expect any
 	}{
 		{0.1, 0.0},
 		{0.5, 0.0},
@@ -126,8 +126,8 @@ func TestLog(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{1, float64(0)},
 		{3, float64(1.0986)},
@@ -167,8 +167,8 @@ func TestSqrt(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{81, float64(9)},
 		{0.25, float64(0.5)},
@@ -206,9 +206,9 @@ func TestMod(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		a      any
+		b      any
+		expect any
 	}{
 		{3, 2, int64(1)},
 		{3, 1, int64(0)},
@@ -246,9 +246,9 @@ func TestModBool(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		a      any
+		b      any
+		expect any
 	}{
 		{3, 3, true},
 		{3, 2, false},
@@ -292,8 +292,8 @@ func TestRound(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		x      interface{}
-		expect interface{}
+		x      any
+		expect any
 	}{
 		{0.1, 0.0},
 		{0.5, 1.0},
@@ -325,9 +325,9 @@ func TestPow(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		a      any
+		b      any
+		expect any
 	}{
 		{0, 0, float64(1)},
 		{2, 0, float64(1)},
@@ -365,9 +365,9 @@ func TestMax(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		a      any
+		b      any
+		expect any
 	}{
 		{-1, -1, float64(-1)},
 		{-1, 0, float64(0)},
@@ -404,9 +404,9 @@ func TestMin(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
+		a      any
+		b      any
+		expect any
 	}{
 		{-1, -1, float64(-1)},
 		{-1, 0, float64(-1)},
diff --git a/tpl/openapi/openapi3/init.go b/tpl/openapi/openapi3/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Unmarshal,
diff --git a/tpl/openapi/openapi3/openapi3.go b/tpl/openapi/openapi3/openapi3.go
@@ -54,7 +54,7 @@ func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*kopenapi3.T, er
 		return nil, errors.New("no Key set in Resource")
 	}
 
-	v, err := ns.cache.GetOrCreate(key, func() (interface{}, error) {
+	v, err := ns.cache.GetOrCreate(key, func() (any, error) {
 		f := metadecoders.FormatFromMediaType(r.MediaType())
 		if f == "" {
 			return nil, errors.Errorf("MIME %q not supported", r.MediaType())
diff --git a/tpl/os/init.go b/tpl/os/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Getenv,
diff --git a/tpl/os/os.go b/tpl/os/os.go
@@ -53,7 +53,7 @@ type Namespace struct {
 
 // Getenv retrieves the value of the environment variable named by the key.
 // It returns the value, which will be empty if the variable is not present.
-func (ns *Namespace) Getenv(key interface{}) (string, error) {
+func (ns *Namespace) Getenv(key any) (string, error) {
 	skey, err := cast.ToStringE(key)
 	if err != nil {
 		return "", nil
@@ -85,7 +85,7 @@ func readFile(fs afero.Fs, filename string) (string, error) {
 // ReadFile reads the file named by filename relative to the configured WorkingDir.
 // It returns the contents as a string.
 // There is an upper size limit set at 1 megabytes.
-func (ns *Namespace) ReadFile(i interface{}) (string, error) {
+func (ns *Namespace) ReadFile(i any) (string, error) {
 	s, err := cast.ToStringE(i)
 	if err != nil {
 		return "", err
@@ -99,7 +99,7 @@ func (ns *Namespace) ReadFile(i interface{}) (string, error) {
 }
 
 // ReadDir lists the directory contents relative to the configured WorkingDir.
-func (ns *Namespace) ReadDir(i interface{}) ([]_os.FileInfo, error) {
+func (ns *Namespace) ReadDir(i any) ([]_os.FileInfo, error) {
 	path, err := cast.ToStringE(i)
 	if err != nil {
 		return nil, err
@@ -114,7 +114,7 @@ func (ns *Namespace) ReadDir(i interface{}) ([]_os.FileInfo, error) {
 }
 
 // FileExists checks whether a file exists under the given path.
-func (ns *Namespace) FileExists(i interface{}) (bool, error) {
+func (ns *Namespace) FileExists(i any) (bool, error) {
 	path, err := cast.ToStringE(i)
 	if err != nil {
 		return false, err
@@ -133,7 +133,7 @@ func (ns *Namespace) FileExists(i interface{}) (bool, error) {
 }
 
 // Stat returns the os.FileInfo structure describing file.
-func (ns *Namespace) Stat(i interface{}) (_os.FileInfo, error) {
+func (ns *Namespace) Stat(i any) (_os.FileInfo, error) {
 	path, err := cast.ToStringE(i)
 	if err != nil {
 		return nil, err
diff --git a/tpl/os/os_test.go b/tpl/os/os_test.go
@@ -34,7 +34,7 @@ func TestReadFile(t *testing.T) {
 
 	for _, test := range []struct {
 		filename string
-		expect   interface{}
+		expect   any
 	}{
 		{filepath.FromSlash("/f/f1.txt"), "f1-content"},
 		{filepath.FromSlash("f/f1.txt"), "f1-content"},
@@ -64,7 +64,7 @@ func TestFileExists(t *testing.T) {
 
 	for _, test := range []struct {
 		filename string
-		expect   interface{}
+		expect   any
 	}{
 		{filepath.FromSlash("/f/f1.txt"), true},
 		{filepath.FromSlash("f/f1.txt"), true},
@@ -91,7 +91,7 @@ func TestStat(t *testing.T) {
 
 	for _, test := range []struct {
 		filename string
-		expect   interface{}
+		expect   any
 	}{
 		{filepath.FromSlash("/f/f1.txt"), int64(10)},
 		{filepath.FromSlash("f/f1.txt"), int64(10)},
diff --git a/tpl/partials/init.go b/tpl/partials/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    namespaceName,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Include,
diff --git a/tpl/partials/partials.go b/tpl/partials/partials.go
@@ -43,7 +43,7 @@ var TestTemplateProvider deps.ResourceProvider
 
 type partialCacheKey struct {
 	name    string
-	variant interface{}
+	variant any
 }
 
 func (k partialCacheKey) templateName() string {
@@ -56,18 +56,18 @@ func (k partialCacheKey) templateName() string {
 // partialCache represents a cache of partials protected by a mutex.
 type partialCache struct {
 	sync.RWMutex
-	p map[partialCacheKey]interface{}
+	p map[partialCacheKey]any
 }
 
 func (p *partialCache) clear() {
 	p.Lock()
 	defer p.Unlock()
-	p.p = make(map[partialCacheKey]interface{})
+	p.p = make(map[partialCacheKey]any)
 }
 
 // New returns a new instance of the templates-namespaced template functions.
 func New(deps *deps.Deps) *Namespace {
-	cache := &partialCache{p: make(map[partialCacheKey]interface{})}
+	cache := &partialCache{p: make(map[partialCacheKey]any)}
 	deps.BuildStartListeners.Add(
 		func() {
 			cache.clear()
@@ -87,12 +87,12 @@ type Namespace struct {
 
 // contextWrapper makes room for a return value in a partial invocation.
 type contextWrapper struct {
-	Arg    interface{}
-	Result interface{}
+	Arg    any
+	Result any
 }
 
 // Set sets the return value and returns an empty string.
-func (c *contextWrapper) Set(in interface{}) string {
+func (c *contextWrapper) Set(in any) string {
 	c.Result = in
 	return ""
 }
@@ -102,7 +102,7 @@ func (c *contextWrapper) Set(in interface{}) string {
 // Else, the rendered output will be returned:
 // A string if the partial is a text/template, or template.HTML when html/template.
 // Note that ctx is provided by Hugo, not the end user.
-func (ns *Namespace) Include(ctx context.Context, name string, contextList ...interface{}) (interface{}, error) {
+func (ns *Namespace) Include(ctx context.Context, name string, contextList ...any) (any, error) {
 	name, result, err := ns.include(ctx, name, contextList...)
 	if err != nil {
 		return result, err
@@ -117,8 +117,8 @@ func (ns *Namespace) Include(ctx context.Context, name string, contextList ...in
 
 // include is a helper function that lookups and executes the named partial.
 // Returns the final template name and the rendered output.
-func (ns *Namespace) include(ctx context.Context, name string, dataList ...interface{}) (string, interface{}, error) {
-	var data interface{}
+func (ns *Namespace) include(ctx context.Context, name string, dataList ...any) (string, any, error) {
+	var data any
 	if len(dataList) > 0 {
 		data = dataList[0]
 	}
@@ -167,7 +167,7 @@ func (ns *Namespace) include(ctx context.Context, name string, dataList ...inter
 		return "", nil, err
 	}
 
-	var result interface{}
+	var result any
 
 	if ctx, ok := data.(*contextWrapper); ok {
 		result = ctx.Result
@@ -182,7 +182,7 @@ func (ns *Namespace) include(ctx context.Context, name string, dataList ...inter
 
 // IncludeCached executes and caches partial templates.  The cache is created with name+variants as the key.
 // Note that ctx is provided by Hugo, not the end user.
-func (ns *Namespace) IncludeCached(ctx context.Context, name string, context interface{}, variants ...interface{}) (interface{}, error) {
+func (ns *Namespace) IncludeCached(ctx context.Context, name string, context any, variants ...any) (any, error) {
 	key, err := createKey(name, variants...)
 	if err != nil {
 		return nil, err
@@ -198,8 +198,8 @@ func (ns *Namespace) IncludeCached(ctx context.Context, name string, context int
 	return result, err
 }
 
-func createKey(name string, variants ...interface{}) (partialCacheKey, error) {
-	var variant interface{}
+func createKey(name string, variants ...any) (partialCacheKey, error) {
+	var variant any
 
 	if len(variants) > 1 {
 		variant = helpers.HashString(variants...)
@@ -221,7 +221,7 @@ func createKey(name string, variants ...interface{}) (partialCacheKey, error) {
 
 var errUnHashable = errors.New("unhashable")
 
-func (ns *Namespace) getOrCreate(ctx context.Context, key partialCacheKey, context interface{}) (result interface{}, err error) {
+func (ns *Namespace) getOrCreate(ctx context.Context, key partialCacheKey, context any) (result any, err error) {
 	start := time.Now()
 	defer func() {
 		if r := recover(); r != nil {
diff --git a/tpl/partials/partials_test.go b/tpl/partials/partials_test.go
@@ -21,9 +21,9 @@ import (
 
 func TestCreateKey(t *testing.T) {
 	c := qt.New(t)
-	m := make(map[interface{}]bool)
+	m := make(map[any]bool)
 
-	create := func(name string, variants ...interface{}) partialCacheKey {
+	create := func(name string, variants ...any) partialCacheKey {
 		k, err := createKey(name, variants...)
 		c.Assert(err, qt.IsNil)
 		m[k] = true
diff --git a/tpl/path/init.go b/tpl/path/init.go
@@ -29,7 +29,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Split,
diff --git a/tpl/path/path.go b/tpl/path/path.go
@@ -52,7 +52,7 @@ func (df DirFile) String() string {
 // it is empty if there is no dot.
 // The input path is passed into filepath.ToSlash converting any Windows slashes
 // to forward slashes.
-func (ns *Namespace) Ext(path interface{}) (string, error) {
+func (ns *Namespace) Ext(path any) (string, error) {
 	spath, err := cast.ToStringE(path)
 	if err != nil {
 		return "", err
@@ -70,7 +70,7 @@ func (ns *Namespace) Ext(path interface{}) (string, error) {
 // slash.
 // The input path is passed into filepath.ToSlash converting any Windows slashes
 // to forward slashes.
-func (ns *Namespace) Dir(path interface{}) (string, error) {
+func (ns *Namespace) Dir(path any) (string, error) {
 	spath, err := cast.ToStringE(path)
 	if err != nil {
 		return "", err
@@ -85,7 +85,7 @@ func (ns *Namespace) Dir(path interface{}) (string, error) {
 // If the path consists entirely of slashes, Base returns "/".
 // The input path is passed into filepath.ToSlash converting any Windows slashes
 // to forward slashes.
-func (ns *Namespace) Base(path interface{}) (string, error) {
+func (ns *Namespace) Base(path any) (string, error) {
 	spath, err := cast.ToStringE(path)
 	if err != nil {
 		return "", err
@@ -101,7 +101,7 @@ func (ns *Namespace) Base(path interface{}) (string, error) {
 // The input path is passed into filepath.ToSlash converting any Windows slashes
 // to forward slashes.
 // The returned values have the property that path = dir+file.
-func (ns *Namespace) Split(path interface{}) (DirFile, error) {
+func (ns *Namespace) Split(path any) (DirFile, error) {
 	spath, err := cast.ToStringE(path)
 	if err != nil {
 		return DirFile{}, err
@@ -118,7 +118,7 @@ func (ns *Namespace) Split(path interface{}) (DirFile, error) {
 // to forward slashes.
 // The result is Cleaned; in particular,
 // all empty strings are ignored.
-func (ns *Namespace) Join(elements ...interface{}) (string, error) {
+func (ns *Namespace) Join(elements ...any) (string, error) {
 	var pathElements []string
 	for _, elem := range elements {
 		switch v := elem.(type) {
@@ -126,7 +126,7 @@ func (ns *Namespace) Join(elements ...interface{}) (string, error) {
 			for _, e := range v {
 				pathElements = append(pathElements, filepath.ToSlash(e))
 			}
-		case []interface{}:
+		case []any:
 			for _, e := range v {
 				elemStr, err := cast.ToStringE(e)
 				if err != nil {
@@ -147,7 +147,7 @@ func (ns *Namespace) Join(elements ...interface{}) (string, error) {
 
 // Clean replaces the separators used with standard slashes and then
 // extraneous slashes are removed.
-func (ns *Namespace) Clean(path interface{}) (string, error) {
+func (ns *Namespace) Clean(path any) (string, error) {
 	spath, err := cast.ToStringE(path)
 
 	if err != nil {
diff --git a/tpl/path/path_test.go b/tpl/path/path_test.go
@@ -31,8 +31,8 @@ func TestBase(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		path   interface{}
-		expect interface{}
+		path   any
+		expect any
 	}{
 		{filepath.FromSlash(`foo/bar.txt`), `bar.txt`},
 		{filepath.FromSlash(`foo/bar/txt `), `txt `},
@@ -61,8 +61,8 @@ func TestDir(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		path   interface{}
-		expect interface{}
+		path   any
+		expect any
 	}{
 		{filepath.FromSlash(`foo/bar.txt`), `foo`},
 		{filepath.FromSlash(`foo/bar/txt `), `foo/bar`},
@@ -91,8 +91,8 @@ func TestExt(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		path   interface{}
-		expect interface{}
+		path   any
+		expect any
 	}{
 		{filepath.FromSlash(`foo/bar.json`), `.json`},
 		{`foo.bar.txt `, `.txt `},
@@ -119,21 +119,21 @@ func TestJoin(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		elements interface{}
-		expect   interface{}
+		elements any
+		expect   any
 	}{
 		{
 			[]string{"", "baz", filepath.FromSlash(`foo/bar.txt`)},
 			`baz/foo/bar.txt`,
 		},
 		{
-			[]interface{}{"", "baz", DirFile{"big", "john"}, filepath.FromSlash(`foo/bar.txt`)},
+			[]any{"", "baz", DirFile{"big", "john"}, filepath.FromSlash(`foo/bar.txt`)},
 			`baz/big|john/foo/bar.txt`,
 		},
 		{nil, ""},
 		// errors
 		{tstNoStringer{}, false},
-		{[]interface{}{"", tstNoStringer{}}, false},
+		{[]any{"", tstNoStringer{}}, false},
 	} {
 
 		result, err := ns.Join(test.elements)
@@ -153,8 +153,8 @@ func TestSplit(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		path   interface{}
-		expect interface{}
+		path   any
+		expect any
 	}{
 		{filepath.FromSlash(`foo/bar.txt`), DirFile{`foo/`, `bar.txt`}},
 		{filepath.FromSlash(`foo/bar/txt `), DirFile{`foo/bar/`, `txt `}},
@@ -181,8 +181,8 @@ func TestClean(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		path   interface{}
-		expect interface{}
+		path   any
+		expect any
 	}{
 		{filepath.FromSlash(`foo/bar.txt`), `foo/bar.txt`},
 		{filepath.FromSlash(`foo/bar/txt`), `foo/bar/txt`},
diff --git a/tpl/reflect/init.go b/tpl/reflect/init.go
@@ -27,7 +27,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.IsMap,
diff --git a/tpl/reflect/reflect.go b/tpl/reflect/reflect.go
@@ -26,11 +26,11 @@ func New() *Namespace {
 type Namespace struct{}
 
 // IsMap reports whether v is a map.
-func (ns *Namespace) IsMap(v interface{}) bool {
+func (ns *Namespace) IsMap(v any) bool {
 	return reflect.ValueOf(v).Kind() == reflect.Map
 }
 
 // IsSlice reports whether v is a slice.
-func (ns *Namespace) IsSlice(v interface{}) bool {
+func (ns *Namespace) IsSlice(v any) bool {
 	return reflect.ValueOf(v).Kind() == reflect.Slice
 }
diff --git a/tpl/reflect/reflect_test.go b/tpl/reflect/reflect_test.go
@@ -26,8 +26,8 @@ type tstNoStringer struct{}
 func TestIsMap(t *testing.T) {
 	c := qt.New(t)
 	for _, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{map[int]int{1: 1}, true},
 		{"foo", false},
@@ -41,8 +41,8 @@ func TestIsMap(t *testing.T) {
 func TestIsSlice(t *testing.T) {
 	c := qt.New(t)
 	for _, test := range []struct {
-		v      interface{}
-		expect interface{}
+		v      any
+		expect any
 	}{
 		{[]int{1, 2}, true},
 		{"foo", false},
diff --git a/tpl/resources/init.go b/tpl/resources/init.go
@@ -30,7 +30,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Get,
diff --git a/tpl/resources/resources.go b/tpl/resources/resources.go
@@ -110,7 +110,7 @@ func (ns *Namespace) getscssClientDartSass() (*dartsass.Client, error) {
 // Get locates the filename given in Hugo's assets filesystem and
 // creates a Resource object that can be used for
 // further transformations.
-func (ns *Namespace) Get(filename interface{}) (resource.Resource, error) {
+func (ns *Namespace) Get(filename any) (resource.Resource, error) {
 	filenamestr, err := cast.ToStringE(filename)
 	if err != nil {
 		return nil, err
@@ -125,8 +125,8 @@ func (ns *Namespace) Get(filename interface{}) (resource.Resource, error) {
 //
 // Note: This method does not return any error as a second argument,
 // for any error situations the error can be checked in .Err.
-func (ns *Namespace) GetRemote(args ...interface{}) resource.Resource {
-	get := func(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) GetRemote(args ...any) resource.Resource {
+	get := func(args ...any) (resource.Resource, error) {
 		if len(args) < 1 {
 			return nil, errors.New("must provide an URL")
 		}
@@ -136,7 +136,7 @@ func (ns *Namespace) GetRemote(args ...interface{}) resource.Resource {
 			return nil, err
 		}
 
-		var options map[string]interface{}
+		var options map[string]any
 
 		if len(args) > 1 {
 			options, err = maps.ToStringMapE(args[1])
@@ -163,7 +163,7 @@ func (ns *Namespace) GetRemote(args ...interface{}) resource.Resource {
 // It looks for files in the assets file system.
 //
 // See Match for a more complete explanation about the rules used.
-func (ns *Namespace) GetMatch(pattern interface{}) (resource.Resource, error) {
+func (ns *Namespace) GetMatch(pattern any) (resource.Resource, error) {
 	patternStr, err := cast.ToStringE(pattern)
 	if err != nil {
 		return nil, err
@@ -188,7 +188,7 @@ func (ns *Namespace) GetMatch(pattern interface{}) (resource.Resource, error) {
 // It looks for files in the assets file system.
 //
 // See Match for a more complete explanation about the rules used.
-func (ns *Namespace) Match(pattern interface{}) (resource.Resources, error) {
+func (ns *Namespace) Match(pattern any) (resource.Resources, error) {
 	patternStr, err := cast.ToStringE(pattern)
 	if err != nil {
 		return nil, err
@@ -199,7 +199,7 @@ func (ns *Namespace) Match(pattern interface{}) (resource.Resources, error) {
 
 // Concat concatenates a slice of Resource objects. These resources must
 // (currently) be of the same Media Type.
-func (ns *Namespace) Concat(targetPathIn interface{}, r interface{}) (resource.Resource, error) {
+func (ns *Namespace) Concat(targetPathIn any, r any) (resource.Resource, error) {
 	targetPath, err := cast.ToStringE(targetPathIn)
 	if err != nil {
 		return nil, err
@@ -224,7 +224,7 @@ func (ns *Namespace) Concat(targetPathIn interface{}, r interface{}) (resource.R
 }
 
 // FromString creates a Resource from a string published to the relative target path.
-func (ns *Namespace) FromString(targetPathIn, contentIn interface{}) (resource.Resource, error) {
+func (ns *Namespace) FromString(targetPathIn, contentIn any) (resource.Resource, error) {
 	targetPath, err := cast.ToStringE(targetPathIn)
 	if err != nil {
 		return nil, err
@@ -239,7 +239,7 @@ func (ns *Namespace) FromString(targetPathIn, contentIn interface{}) (resource.R
 
 // ExecuteAsTemplate creates a Resource from a Go template, parsed and executed with
 // the given data, and published to the relative target path.
-func (ns *Namespace) ExecuteAsTemplate(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) ExecuteAsTemplate(args ...any) (resource.Resource, error) {
 	if len(args) != 3 {
 		return nil, fmt.Errorf("must provide targetPath, the template data context and a Resource object")
 	}
@@ -259,7 +259,7 @@ func (ns *Namespace) ExecuteAsTemplate(args ...interface{}) (resource.Resource, 
 
 // Fingerprint transforms the given Resource with a MD5 hash of the content in
 // the RelPermalink and Permalink.
-func (ns *Namespace) Fingerprint(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) Fingerprint(args ...any) (resource.Resource, error) {
 	if len(args) < 1 || len(args) > 2 {
 		return nil, errors.New("must provide a Resource and (optional) crypto algo")
 	}
@@ -292,7 +292,7 @@ func (ns *Namespace) Minify(r resources.ResourceTransformer) (resource.Resource,
 
 // ToCSS converts the given Resource to CSS. You can optional provide an Options
 // object or a target path (string) as first argument.
-func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) ToCSS(args ...any) (resource.Resource, error) {
 	const (
 		// Transpiler implementation can be controlled from the client by
 		// setting the 'transpiler' option.
@@ -303,7 +303,7 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
 
 	var (
 		r          resources.ResourceTransformer
-		m          map[string]interface{}
+		m          map[string]any
 		targetPath string
 		err        error
 		ok         bool
@@ -346,7 +346,7 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
 	}
 
 	if m == nil {
-		m = make(map[string]interface{})
+		m = make(map[string]any)
 	}
 	if targetPath != "" {
 		m["targetPath"] = targetPath
@@ -362,7 +362,7 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
 }
 
 // PostCSS processes the given Resource with PostCSS
-func (ns *Namespace) PostCSS(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) {
 	r, m, err := resourcehelpers.ResolveArgs(args)
 	if err != nil {
 		return nil, err
@@ -383,7 +383,7 @@ func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedReso
 }
 
 // Babel processes the given Resource with Babel.
-func (ns *Namespace) Babel(args ...interface{}) (resource.Resource, error) {
+func (ns *Namespace) Babel(args ...any) (resource.Resource, error) {
 	r, m, err := resourcehelpers.ResolveArgs(args)
 	if err != nil {
 		return nil, err
diff --git a/tpl/safe/init.go b/tpl/safe/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.CSS,
diff --git a/tpl/safe/safe.go b/tpl/safe/safe.go
@@ -31,43 +31,43 @@ func New() *Namespace {
 type Namespace struct{}
 
 // CSS returns a given string as html/template CSS content.
-func (ns *Namespace) CSS(a interface{}) (template.CSS, error) {
+func (ns *Namespace) CSS(a any) (template.CSS, error) {
 	s, err := cast.ToStringE(a)
 	return template.CSS(s), err
 }
 
 // HTML returns a given string as html/template HTML content.
-func (ns *Namespace) HTML(a interface{}) (template.HTML, error) {
+func (ns *Namespace) HTML(a any) (template.HTML, error) {
 	s, err := cast.ToStringE(a)
 	return template.HTML(s), err
 }
 
 // HTMLAttr returns a given string as html/template HTMLAttr content.
-func (ns *Namespace) HTMLAttr(a interface{}) (template.HTMLAttr, error) {
+func (ns *Namespace) HTMLAttr(a any) (template.HTMLAttr, error) {
 	s, err := cast.ToStringE(a)
 	return template.HTMLAttr(s), err
 }
 
 // JS returns the given string as a html/template JS content.
-func (ns *Namespace) JS(a interface{}) (template.JS, error) {
+func (ns *Namespace) JS(a any) (template.JS, error) {
 	s, err := cast.ToStringE(a)
 	return template.JS(s), err
 }
 
 // JSStr returns the given string as a html/template JSStr content.
-func (ns *Namespace) JSStr(a interface{}) (template.JSStr, error) {
+func (ns *Namespace) JSStr(a any) (template.JSStr, error) {
 	s, err := cast.ToStringE(a)
 	return template.JSStr(s), err
 }
 
 // URL returns a given string as html/template URL content.
-func (ns *Namespace) URL(a interface{}) (template.URL, error) {
+func (ns *Namespace) URL(a any) (template.URL, error) {
 	s, err := cast.ToStringE(a)
 	return template.URL(s), err
 }
 
 // SanitizeURL returns a given string as html/template URL content.
-func (ns *Namespace) SanitizeURL(a interface{}) (string, error) {
+func (ns *Namespace) SanitizeURL(a any) (string, error) {
 	s, err := cast.ToStringE(a)
 	return helpers.SanitizeURL(s), err
 }
diff --git a/tpl/safe/safe_test.go b/tpl/safe/safe_test.go
@@ -29,8 +29,8 @@ func TestCSS(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{`a[href =~ "//example.com"]#foo`, template.CSS(`a[href =~ "//example.com"]#foo`)},
 		// errors
@@ -56,8 +56,8 @@ func TestHTML(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{`Hello, <b>World</b> &amp;tc!`, template.HTML(`Hello, <b>World</b> &amp;tc!`)},
 		// errors
@@ -83,8 +83,8 @@ func TestHTMLAttr(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{` dir="ltr"`, template.HTMLAttr(` dir="ltr"`)},
 		// errors
@@ -109,8 +109,8 @@ func TestJS(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{`c && alert("Hello, World!");`, template.JS(`c && alert("Hello, World!");`)},
 		// errors
@@ -136,8 +136,8 @@ func TestJSStr(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{`Hello, World & O'Reilly\x21`, template.JSStr(`Hello, World & O'Reilly\x21`)},
 		// errors
@@ -163,8 +163,8 @@ func TestURL(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{`greeting=H%69&addressee=(World)`, template.URL(`greeting=H%69&addressee=(World)`)},
 		// errors
@@ -190,8 +190,8 @@ func TestSanitizeURL(t *testing.T) {
 	ns := New()
 
 	for _, test := range []struct {
-		a      interface{}
-		expect interface{}
+		a      any
+		expect any
 	}{
 		{"http://foo/../../bar", "http://foo/bar"},
 		// errors
diff --git a/tpl/site/init.go b/tpl/site/init.go
@@ -27,7 +27,7 @@ func init() {
 		s := d.Site
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return s, nil },
+			Context: func(args ...any) (any, error) { return s, nil },
 		}
 
 		if s == nil {
diff --git a/tpl/strings/init.go b/tpl/strings/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Chomp,
diff --git a/tpl/strings/regexp.go b/tpl/strings/regexp.go
@@ -22,7 +22,7 @@ import (
 
 // FindRE returns a list of strings that match the regular expression. By default all matches
 // will be included. The number of matches can be limited with an optional third parameter.
-func (ns *Namespace) FindRE(expr string, content interface{}, limit ...interface{}) ([]string, error) {
+func (ns *Namespace) FindRE(expr string, content any, limit ...any) ([]string, error) {
 	re, err := reCache.Get(expr)
 	if err != nil {
 		return nil, err
@@ -48,7 +48,7 @@ func (ns *Namespace) FindRE(expr string, content interface{}, limit ...interface
 // ReplaceRE returns a copy of s, replacing all matches of the regular
 // expression pattern with the replacement text repl. The number of replacements
 // can be limited with an optional fourth parameter.
-func (ns *Namespace) ReplaceRE(pattern, repl, s interface{}, n ...interface{}) (_ string, err error) {
+func (ns *Namespace) ReplaceRE(pattern, repl, s any, n ...any) (_ string, err error) {
 	sp, err := cast.ToStringE(pattern)
 	if err != nil {
 		return
diff --git a/tpl/strings/regexp_test.go b/tpl/strings/regexp_test.go
@@ -25,9 +25,9 @@ func TestFindRE(t *testing.T) {
 
 	for _, test := range []struct {
 		expr    string
-		content interface{}
-		limit   interface{}
-		expect  interface{}
+		content any
+		limit   any
+		expect  any
 	}{
 		{"[G|g]o", "Hugo is a static site generator written in Go.", 2, []string{"go", "Go"}},
 		{"[G|g]o", "Hugo is a static site generator written in Go.", -1, []string{"go", "Go"}},
@@ -55,16 +55,16 @@ func TestReplaceRE(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		pattern interface{}
-		repl    interface{}
-		s       interface{}
-		n       []interface{}
-		expect  interface{}
+		pattern any
+		repl    any
+		s       any
+		n       []any
+		expect  any
 	}{
 		{"^https?://([^/]+).*", "$1", "http://gohugo.io/docs", nil, "gohugo.io"},
 		{"^https?://([^/]+).*", "$2", "http://gohugo.io/docs", nil, ""},
 		{"(ab)", "AB", "aabbaab", nil, "aABbaAB"},
-		{"(ab)", "AB", "aabbaab", []interface{}{1}, "aABbaab"},
+		{"(ab)", "AB", "aabbaab", []any{1}, "aABbaab"},
 		// errors
 		{"(ab", "AB", "aabb", nil, false}, // invalid re
 		{tstNoStringer{}, "$2", "http://gohugo.io/docs", nil, false},
diff --git a/tpl/strings/strings.go b/tpl/strings/strings.go
@@ -45,7 +45,7 @@ type Namespace struct {
 }
 
 // CountRunes returns the number of runes in s, excluding whitespace.
-func (ns *Namespace) CountRunes(s interface{}) (int, error) {
+func (ns *Namespace) CountRunes(s any) (int, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return 0, _errors.Wrap(err, "Failed to convert content to string")
@@ -62,7 +62,7 @@ func (ns *Namespace) CountRunes(s interface{}) (int, error) {
 }
 
 // RuneCount returns the number of runes in s.
-func (ns *Namespace) RuneCount(s interface{}) (int, error) {
+func (ns *Namespace) RuneCount(s any) (int, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return 0, _errors.Wrap(err, "Failed to convert content to string")
@@ -71,7 +71,7 @@ func (ns *Namespace) RuneCount(s interface{}) (int, error) {
 }
 
 // CountWords returns the approximate word count in s.
-func (ns *Namespace) CountWords(s interface{}) (int, error) {
+func (ns *Namespace) CountWords(s any) (int, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return 0, _errors.Wrap(err, "Failed to convert content to string")
@@ -101,7 +101,7 @@ func (ns *Namespace) CountWords(s interface{}) (int, error) {
 
 // Count counts the number of non-overlapping instances of substr in s.
 // If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
-func (ns *Namespace) Count(substr, s interface{}) (int, error) {
+func (ns *Namespace) Count(substr, s any) (int, error) {
 	substrs, err := cast.ToStringE(substr)
 	if err != nil {
 		return 0, _errors.Wrap(err, "Failed to convert substr to string")
@@ -114,7 +114,7 @@ func (ns *Namespace) Count(substr, s interface{}) (int, error) {
 }
 
 // Chomp returns a copy of s with all trailing newline characters removed.
-func (ns *Namespace) Chomp(s interface{}) (interface{}, error) {
+func (ns *Namespace) Chomp(s any) (any, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -130,7 +130,7 @@ func (ns *Namespace) Chomp(s interface{}) (interface{}, error) {
 }
 
 // Contains reports whether substr is in s.
-func (ns *Namespace) Contains(s, substr interface{}) (bool, error) {
+func (ns *Namespace) Contains(s, substr any) (bool, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return false, err
@@ -145,7 +145,7 @@ func (ns *Namespace) Contains(s, substr interface{}) (bool, error) {
 }
 
 // ContainsAny reports whether any Unicode code points in chars are within s.
-func (ns *Namespace) ContainsAny(s, chars interface{}) (bool, error) {
+func (ns *Namespace) ContainsAny(s, chars any) (bool, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return false, err
@@ -160,7 +160,7 @@ func (ns *Namespace) ContainsAny(s, chars interface{}) (bool, error) {
 }
 
 // HasPrefix tests whether the input s begins with prefix.
-func (ns *Namespace) HasPrefix(s, prefix interface{}) (bool, error) {
+func (ns *Namespace) HasPrefix(s, prefix any) (bool, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return false, err
@@ -175,7 +175,7 @@ func (ns *Namespace) HasPrefix(s, prefix interface{}) (bool, error) {
 }
 
 // HasSuffix tests whether the input s begins with suffix.
-func (ns *Namespace) HasSuffix(s, suffix interface{}) (bool, error) {
+func (ns *Namespace) HasSuffix(s, suffix any) (bool, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return false, err
@@ -192,7 +192,7 @@ func (ns *Namespace) HasSuffix(s, suffix interface{}) (bool, error) {
 // Replace returns a copy of the string s with all occurrences of old replaced
 // with new.  The number of replacements can be limited with an optional fourth
 // parameter.
-func (ns *Namespace) Replace(s, old, new interface{}, limit ...interface{}) (string, error) {
+func (ns *Namespace) Replace(s, old, new any, limit ...any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -223,7 +223,7 @@ func (ns *Namespace) Replace(s, old, new interface{}, limit ...interface{}) (str
 // SliceString slices a string by specifying a half-open range with
 // two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
 // The end index can be omitted, it defaults to the string's length.
-func (ns *Namespace) SliceString(a interface{}, startEnd ...interface{}) (string, error) {
+func (ns *Namespace) SliceString(a any, startEnd ...any) (string, error) {
 	aStr, err := cast.ToStringE(a)
 	if err != nil {
 		return "", err
@@ -267,7 +267,7 @@ func (ns *Namespace) SliceString(a interface{}, startEnd ...interface{}) (string
 }
 
 // Split slices an input string into all substrings separated by delimiter.
-func (ns *Namespace) Split(a interface{}, delimiter string) ([]string, error) {
+func (ns *Namespace) Split(a any, delimiter string) ([]string, error) {
 	aStr, err := cast.ToStringE(a)
 	if err != nil {
 		return []string{}, err
@@ -288,7 +288,7 @@ func (ns *Namespace) Split(a interface{}, delimiter string) ([]string, error) {
 // In addition, borrowing from the extended behavior described at http://php.net/substr,
 // if length is given and is negative, then that many characters will be omitted from
 // the end of string.
-func (ns *Namespace) Substr(a interface{}, nums ...interface{}) (string, error) {
+func (ns *Namespace) Substr(a any, nums ...any) (string, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", err
@@ -363,7 +363,7 @@ func (ns *Namespace) Substr(a interface{}, nums ...interface{}) (string, error) 
 
 // Title returns a copy of the input s with all Unicode letters that begin words
 // mapped to their title case.
-func (ns *Namespace) Title(s interface{}) (string, error) {
+func (ns *Namespace) Title(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -373,7 +373,7 @@ func (ns *Namespace) Title(s interface{}) (string, error) {
 }
 
 // FirstUpper returns a string with the first character as upper case.
-func (ns *Namespace) FirstUpper(s interface{}) (string, error) {
+func (ns *Namespace) FirstUpper(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -384,7 +384,7 @@ func (ns *Namespace) FirstUpper(s interface{}) (string, error) {
 
 // ToLower returns a copy of the input s with all Unicode letters mapped to their
 // lower case.
-func (ns *Namespace) ToLower(s interface{}) (string, error) {
+func (ns *Namespace) ToLower(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -395,7 +395,7 @@ func (ns *Namespace) ToLower(s interface{}) (string, error) {
 
 // ToUpper returns a copy of the input s with all Unicode letters mapped to their
 // upper case.
-func (ns *Namespace) ToUpper(s interface{}) (string, error) {
+func (ns *Namespace) ToUpper(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -406,7 +406,7 @@ func (ns *Namespace) ToUpper(s interface{}) (string, error) {
 
 // Trim returns a string with all leading and trailing characters defined
 // contained in cutset removed.
-func (ns *Namespace) Trim(s, cutset interface{}) (string, error) {
+func (ns *Namespace) Trim(s, cutset any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -422,7 +422,7 @@ func (ns *Namespace) Trim(s, cutset interface{}) (string, error) {
 
 // TrimLeft returns a slice of the string s with all leading characters
 // contained in cutset removed.
-func (ns *Namespace) TrimLeft(cutset, s interface{}) (string, error) {
+func (ns *Namespace) TrimLeft(cutset, s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -438,7 +438,7 @@ func (ns *Namespace) TrimLeft(cutset, s interface{}) (string, error) {
 
 // TrimPrefix returns s without the provided leading prefix string. If s doesn't
 // start with prefix, s is returned unchanged.
-func (ns *Namespace) TrimPrefix(prefix, s interface{}) (string, error) {
+func (ns *Namespace) TrimPrefix(prefix, s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -454,7 +454,7 @@ func (ns *Namespace) TrimPrefix(prefix, s interface{}) (string, error) {
 
 // TrimRight returns a slice of the string s with all trailing characters
 // contained in cutset removed.
-func (ns *Namespace) TrimRight(cutset, s interface{}) (string, error) {
+func (ns *Namespace) TrimRight(cutset, s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -470,7 +470,7 @@ func (ns *Namespace) TrimRight(cutset, s interface{}) (string, error) {
 
 // TrimSuffix returns s without the provided trailing suffix string. If s
 // doesn't end with suffix, s is returned unchanged.
-func (ns *Namespace) TrimSuffix(suffix, s interface{}) (string, error) {
+func (ns *Namespace) TrimSuffix(suffix, s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -485,7 +485,7 @@ func (ns *Namespace) TrimSuffix(suffix, s interface{}) (string, error) {
 }
 
 // Repeat returns a new string consisting of count copies of the string s.
-func (ns *Namespace) Repeat(n, s interface{}) (string, error) {
+func (ns *Namespace) Repeat(n, s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
diff --git a/tpl/strings/strings_test.go b/tpl/strings/strings_test.go
@@ -33,8 +33,8 @@ func TestChomp(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"\n a\n", "\n a"},
 		{"\n a\n\n", "\n a"},
@@ -68,8 +68,8 @@ func TestContains(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		substr interface{}
+		s      any
+		substr any
 		expect bool
 		isErr  bool
 	}{
@@ -106,8 +106,8 @@ func TestContainsAny(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		substr interface{}
+		s      any
+		substr any
 		expect bool
 		isErr  bool
 	}{
@@ -150,8 +150,8 @@ func TestCountRunes(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"foo bar", 6},
 		{"旁边", 2},
@@ -177,8 +177,8 @@ func TestRuneCount(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"foo bar", 7},
 		{"旁边", 2},
@@ -204,8 +204,8 @@ func TestCountWords(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"Do Be Do Be Do", 5},
 		{"旁边", 2},
@@ -234,9 +234,9 @@ func TestHasPrefix(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		prefix interface{}
-		expect interface{}
+		s      any
+		prefix any
+		expect any
 		isErr  bool
 	}{
 		{"abcd", "ab", true, false},
@@ -268,9 +268,9 @@ func TestHasSuffix(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		suffix interface{}
-		expect interface{}
+		s      any
+		suffix any
+		expect any
 		isErr  bool
 	}{
 		{"abcd", "cd", true, false},
@@ -302,11 +302,11 @@ func TestReplace(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		old    interface{}
-		new    interface{}
-		limit  interface{}
-		expect interface{}
+		s      any
+		old    any
+		new    any
+		limit  any
+		expect any
 	}{
 		{"aab", "a", "b", nil, "bbb"},
 		{"11a11", 1, 2, nil, "22a22"},
@@ -346,10 +346,10 @@ func TestSliceString(t *testing.T) {
 
 	var err error
 	for _, test := range []struct {
-		v1     interface{}
-		v2     interface{}
-		v3     interface{}
-		expect interface{}
+		v1     any
+		v2     any
+		v3     any
+		expect any
 	}{
 		{"abc", 1, 2, "b"},
 		{"abc", 1, 3, "bc"},
@@ -408,9 +408,9 @@ func TestSplit(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		v1     interface{}
+		v1     any
 		v2     string
-		expect interface{}
+		expect any
 	}{
 		{"a, b", ", ", []string{"a", "b"}},
 		{"a & b & c", " & ", []string{"a", "b", "c"}},
@@ -437,10 +437,10 @@ func TestSubstr(t *testing.T) {
 
 	var err error
 	for _, test := range []struct {
-		v1     interface{}
-		v2     interface{}
-		v3     interface{}
-		expect interface{}
+		v1     any
+		v2     any
+		v3     any
+		expect any
 	}{
 		{"abc", 1, 2, "bc"},
 		{"abc", 0, 1, "a"},
@@ -511,8 +511,8 @@ func TestTitle(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"test", "Test"},
 		{template.HTML("hypertext"), "Hypertext"},
@@ -538,8 +538,8 @@ func TestToLower(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"TEST", "test"},
 		{template.HTML("LoWeR"), "lower"},
@@ -565,8 +565,8 @@ func TestToUpper(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"test", "TEST"},
 		{template.HTML("UpPeR"), "UPPER"},
@@ -592,9 +592,9 @@ func TestTrim(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		cutset interface{}
-		expect interface{}
+		s      any
+		cutset any
+		expect any
 	}{
 		{"abba", "a", "bb"},
 		{"abba", "ab", ""},
@@ -626,9 +626,9 @@ func TestTrimLeft(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		cutset interface{}
-		expect interface{}
+		s      any
+		cutset any
+		expect any
 	}{
 		{"abba", "a", "bba"},
 		{"abba", "ab", ""},
@@ -661,9 +661,9 @@ func TestTrimPrefix(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		prefix interface{}
-		expect interface{}
+		s      any
+		prefix any
+		expect any
 	}{
 		{"aabbaa", "a", "abbaa"},
 		{"aabb", "b", "aabb"},
@@ -691,9 +691,9 @@ func TestTrimRight(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		cutset interface{}
-		expect interface{}
+		s      any
+		cutset any
+		expect any
 	}{
 		{"abba", "a", "abb"},
 		{"abba", "ab", ""},
@@ -726,9 +726,9 @@ func TestTrimSuffix(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		suffix interface{}
-		expect interface{}
+		s      any
+		suffix any
+		expect any
 	}{
 		{"aabbaa", "a", "aabba"},
 		{"aabb", "b", "aab"},
@@ -756,9 +756,9 @@ func TestRepeat(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		s      interface{}
-		n      interface{}
-		expect interface{}
+		s      any
+		n      any
+		expect any
 	}{
 		{"yo", "2", "yoyo"},
 		{"~", "16", "~~~~~~~~~~~~~~~~"},
diff --git a/tpl/strings/truncate.go b/tpl/strings/truncate.go
@@ -40,12 +40,12 @@ type htmlTag struct {
 }
 
 // Truncate truncates a given string to the specified length.
-func (ns *Namespace) Truncate(a interface{}, options ...interface{}) (template.HTML, error) {
+func (ns *Namespace) Truncate(a any, options ...any) (template.HTML, error) {
 	length, err := cast.ToIntE(a)
 	if err != nil {
 		return "", err
 	}
-	var textParam interface{}
+	var textParam any
 	var ellipsis string
 
 	switch len(options) {
diff --git a/tpl/strings/truncate_test.go b/tpl/strings/truncate_test.go
@@ -25,10 +25,10 @@ func TestTruncate(t *testing.T) {
 
 	var err error
 	cases := []struct {
-		v1    interface{}
-		v2    interface{}
-		v3    interface{}
-		want  interface{}
+		v1    any
+		v2    any
+		v3    any
+		want  any
 		isErr bool
 	}{
 		{10, "I am a test sentence", nil, template.HTML("I am a …"), false},
diff --git a/tpl/template.go b/tpl/template.go
@@ -53,8 +53,8 @@ type UnusedTemplatesProvider interface {
 // TemplateHandler finds and executes templates.
 type TemplateHandler interface {
 	TemplateFinder
-	Execute(t Template, wr io.Writer, data interface{}) error
-	ExecuteWithContext(ctx context.Context, t Template, wr io.Writer, data interface{}) error
+	Execute(t Template, wr io.Writer, data any) error
+	ExecuteWithContext(ctx context.Context, t Template, wr io.Writer, data any) error
 	LookupLayout(d output.LayoutDescriptor, f output.Format) (Template, bool, error)
 	HasTemplate(name string) bool
 }
@@ -149,7 +149,7 @@ type TemplateFuncGetter interface {
 
 // GetDataFromContext returns the template data context (usually .Page) from ctx if set.
 // NOte: This is not fully implemented yet.
-func GetDataFromContext(ctx context.Context) interface{} {
+func GetDataFromContext(ctx context.Context) any {
 	return ctx.Value(texttemplate.DataContextKey)
 }
 
diff --git a/tpl/templates/init.go b/tpl/templates/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Exists,
diff --git a/tpl/time/init.go b/tpl/time/init.go
@@ -32,7 +32,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name: name,
-			Context: func(args ...interface{}) (interface{}, error) {
+			Context: func(args ...any) (any, error) {
 				// Handle overlapping "time" namespace and func.
 				//
 				// If no args are passed to `time`, assume namespace usage and
diff --git a/tpl/time/time.go b/tpl/time/time.go
@@ -42,7 +42,7 @@ type Namespace struct {
 
 // AsTime converts the textual representation of the datetime string into
 // a time.Time interface.
-func (ns *Namespace) AsTime(v interface{}, args ...interface{}) (interface{}, error) {
+func (ns *Namespace) AsTime(v any, args ...any) (any, error) {
 	loc := ns.location
 	if len(args) > 0 {
 		locStr, err := cast.ToStringE(args[0])
@@ -62,7 +62,7 @@ func (ns *Namespace) AsTime(v interface{}, args ...interface{}) (interface{}, er
 // Format converts the textual representation of the datetime string into
 // the other form or returns it of the time.Time value. These are formatted
 // with the layout string
-func (ns *Namespace) Format(layout string, v interface{}) (string, error) {
+func (ns *Namespace) Format(layout string, v any) (string, error) {
 	t, err := htime.ToTimeInDefaultLocationE(v, ns.location)
 	if err != nil {
 		return "", err
@@ -82,7 +82,7 @@ func (ns *Namespace) Now() _time.Time {
 // such as "300ms", "-1.5h" or "2h45m".
 // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
 // See https://golang.org/pkg/time/#ParseDuration
-func (ns *Namespace) ParseDuration(in interface{}) (_time.Duration, error) {
+func (ns *Namespace) ParseDuration(in any) (_time.Duration, error) {
 	s, err := cast.ToStringE(in)
 	if err != nil {
 		return 0, err
@@ -109,7 +109,7 @@ var durationUnits = map[string]_time.Duration{
 
 // Duration converts the given number to a time.Duration.
 // Unit is one of nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m or hour/h.
-func (ns *Namespace) Duration(unit interface{}, number interface{}) (_time.Duration, error) {
+func (ns *Namespace) Duration(unit any, number any) (_time.Duration, error) {
 	unitStr, err := cast.ToStringE(unit)
 	if err != nil {
 		return 0, err
diff --git a/tpl/time/time_test.go b/tpl/time/time_test.go
@@ -32,8 +32,8 @@ func TestTimeLocation(t *testing.T) {
 	for i, test := range []struct {
 		name     string
 		value    string
-		location interface{}
-		expect   interface{}
+		location any
+		expect   any
 	}{
 		{"Empty location", "2020-10-20", "", "2020-10-20 00:00:00 +0000 UTC"},
 		{"New location", "2020-10-20", nil, "2020-10-20 00:00:00 -0400 AST"},
@@ -53,7 +53,7 @@ func TestTimeLocation(t *testing.T) {
 		{"Invalid time value", "invalid-value", "", false},
 	} {
 		t.Run(test.name, func(t *testing.T) {
-			var args []interface{}
+			var args []any
 			if test.location != nil {
 				args = append(args, test.location)
 			}
@@ -90,8 +90,8 @@ func TestFormat(t *testing.T) {
 
 		for i, test := range []struct {
 			layout string
-			value  interface{}
-			expect interface{}
+			value  any
+			expect any
 		}{
 			{"Monday, Jan 2, 2006", "2015-01-21", "Wednesday, Jan 21, 2015"},
 			{"Monday, Jan 2, 2006", time.Date(2015, time.January, 21, 0, 0, 0, 0, time.UTC), "Wednesday, Jan 21, 2015"},
@@ -146,9 +146,9 @@ func TestDuration(t *testing.T) {
 	ns := New(translators.GetTranslator("en"), time.UTC)
 
 	for i, test := range []struct {
-		unit   interface{}
-		num    interface{}
-		expect interface{}
+		unit   any
+		num    any
+		expect any
 	}{
 		{"nanosecond", 10, 10 * time.Nanosecond},
 		{"ns", 10, 10 * time.Nanosecond},
diff --git a/tpl/tplimpl/template.go b/tpl/tplimpl/template.go
@@ -118,7 +118,7 @@ func newIdentity(name string) identity.Manager {
 	return identity.NewManager(identity.NewPathIdentity(files.ComponentFolderLayouts, name))
 }
 
-func newStandaloneTextTemplate(funcs map[string]interface{}) tpl.TemplateParseFinder {
+func newStandaloneTextTemplate(funcs map[string]any) tpl.TemplateParseFinder {
 	return &textTemplateWrapperWithLock{
 		RWMutex:  &sync.RWMutex{},
 		Template: texttemplate.New("").Funcs(funcs),
@@ -127,7 +127,7 @@ func newStandaloneTextTemplate(funcs map[string]interface{}) tpl.TemplateParseFi
 
 func newTemplateExec(d *deps.Deps) (*templateExec, error) {
 	exec, funcs := newTemplateExecuter(d)
-	funcMap := make(map[string]interface{})
+	funcMap := make(map[string]any)
 	for k, v := range funcs {
 		funcMap[k] = v.Interface()
 	}
@@ -184,7 +184,7 @@ func newTemplateExec(d *deps.Deps) (*templateExec, error) {
 	return e, nil
 }
 
-func newTemplateNamespace(funcs map[string]interface{}) *templateNamespace {
+func newTemplateNamespace(funcs map[string]any) *templateNamespace {
 	return &templateNamespace{
 		prototypeHTML: htmltemplate.New("").Funcs(funcs),
 		prototypeText: texttemplate.New("").Funcs(funcs),
@@ -225,11 +225,11 @@ func (t templateExec) Clone(d *deps.Deps) *templateExec {
 	return &t
 }
 
-func (t *templateExec) Execute(templ tpl.Template, wr io.Writer, data interface{}) error {
+func (t *templateExec) Execute(templ tpl.Template, wr io.Writer, data any) error {
 	return t.ExecuteWithContext(context.Background(), templ, wr, data)
 }
 
-func (t *templateExec) ExecuteWithContext(ctx context.Context, templ tpl.Template, wr io.Writer, data interface{}) error {
+func (t *templateExec) ExecuteWithContext(ctx context.Context, templ tpl.Template, wr io.Writer, data any) error {
 	if rlocker, ok := templ.(types.RLocker); ok {
 		rlocker.RLock()
 		defer rlocker.RUnlock()
diff --git a/tpl/tplimpl/template_ast_transformers_test.go b/tpl/tplimpl/template_ast_transformers_test.go
@@ -88,7 +88,7 @@ func TestCollectInfo(t *testing.T) {
 		{"Basic config map", "{{ $_hugo_config := `" + configStr + "`  }}", tpl.ParseInfo{Config: tpl.ParseConfig{Version: 42}}},
 	}
 
-	echo := func(in interface{}) interface{} {
+	echo := func(in any) any {
 		return in
 	}
 
@@ -129,7 +129,7 @@ func TestPartialReturn(t *testing.T) {
 `, true},
 	}
 
-	echo := func(in interface{}) interface{} {
+	echo := func(in any) any {
 		return in
 	}
 
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
@@ -174,7 +174,7 @@ func newTemplateExecuter(d *deps.Deps) (texttemplate.Executer, map[string]reflec
 	), funcsv
 }
 
-func createFuncMap(d *deps.Deps) map[string]interface{} {
+func createFuncMap(d *deps.Deps) map[string]any {
 	funcMap := template.FuncMap{}
 
 	// Merge the namespace funcs
diff --git a/tpl/transform/init.go b/tpl/transform/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.Emojify,
diff --git a/tpl/transform/remarshal.go b/tpl/transform/remarshal.go
@@ -17,8 +17,8 @@ import (
 // It is not a general purpose YAML to TOML converter etc., and may
 // change without notice if it serves a purpose in the docs.
 // Format is one of json, yaml or toml.
-func (ns *Namespace) Remarshal(format string, data interface{}) (string, error) {
-	var meta map[string]interface{}
+func (ns *Namespace) Remarshal(format string, data any) (string, error) {
+	var meta map[string]any
 
 	format = strings.TrimSpace(strings.ToLower(format))
 
@@ -27,7 +27,7 @@ func (ns *Namespace) Remarshal(format string, data interface{}) (string, error) 
 		return "", err
 	}
 
-	if m, ok := data.(map[string]interface{}); ok {
+	if m, ok := data.(map[string]any); ok {
 		meta = m
 	} else {
 		from, err := cast.ToStringE(data)
@@ -65,10 +65,10 @@ func (ns *Namespace) Remarshal(format string, data interface{}) (string, error) 
 // The unmarshal/marshal dance is extremely type lossy, and we need
 // to make sure that integer types prints as "43" and not "43.0" in
 // all formats, hence this hack.
-func applyMarshalTypes(m map[string]interface{}) {
+func applyMarshalTypes(m map[string]any) {
 	for k, v := range m {
 		switch t := v.(type) {
-		case map[string]interface{}:
+		case map[string]any:
 			applyMarshalTypes(t)
 		case float64:
 			i := int64(t)
diff --git a/tpl/transform/remarshal_test.go b/tpl/transform/remarshal_test.go
@@ -184,7 +184,7 @@ a = "b"
 	})
 
 	c.Run("Map input", func(c *qt.C) {
-		input := map[string]interface{}{
+		input := map[string]any{
 			"hello": "world",
 		}
 
diff --git a/tpl/transform/transform.go b/tpl/transform/transform.go
@@ -51,7 +51,7 @@ type Namespace struct {
 // Emojify returns a copy of s with all emoji codes replaced with actual emojis.
 //
 // See http://www.emoji-cheat-sheet.com/
-func (ns *Namespace) Emojify(s interface{}) (template.HTML, error) {
+func (ns *Namespace) Emojify(s any) (template.HTML, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -62,13 +62,13 @@ func (ns *Namespace) Emojify(s interface{}) (template.HTML, error) {
 
 // Highlight returns a copy of s as an HTML string with syntax
 // highlighting applied.
-func (ns *Namespace) Highlight(s interface{}, lang string, opts ...interface{}) (template.HTML, error) {
+func (ns *Namespace) Highlight(s any, lang string, opts ...any) (template.HTML, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
 	}
 
-	var optsv interface{}
+	var optsv any
 	if len(opts) > 0 {
 		optsv = opts[0]
 	}
@@ -79,8 +79,8 @@ func (ns *Namespace) Highlight(s interface{}, lang string, opts ...interface{}) 
 }
 
 // HighlightCodeBlock highlights a code block on the form received in the codeblock render hooks.
-func (ns *Namespace) HighlightCodeBlock(ctx hooks.CodeblockContext, opts ...interface{}) (highlight.HightlightResult, error) {
-	var optsv interface{}
+func (ns *Namespace) HighlightCodeBlock(ctx hooks.CodeblockContext, opts ...any) (highlight.HightlightResult, error) {
+	var optsv any
 	if len(opts) > 0 {
 		optsv = opts[0]
 	}
@@ -96,7 +96,7 @@ func (ns *Namespace) CanHighlight(lang string) bool {
 }
 
 // HTMLEscape returns a copy of s with reserved HTML characters escaped.
-func (ns *Namespace) HTMLEscape(s interface{}) (string, error) {
+func (ns *Namespace) HTMLEscape(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -107,7 +107,7 @@ func (ns *Namespace) HTMLEscape(s interface{}) (string, error) {
 
 // HTMLUnescape returns a copy of with HTML escape requences converted to plain
 // text.
-func (ns *Namespace) HTMLUnescape(s interface{}) (string, error) {
+func (ns *Namespace) HTMLUnescape(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
@@ -117,7 +117,7 @@ func (ns *Namespace) HTMLUnescape(s interface{}) (string, error) {
 }
 
 // Markdownify renders a given input from Markdown to HTML.
-func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) {
+func (ns *Namespace) Markdownify(s any) (template.HTML, error) {
 
 	home := ns.deps.Site.Home()
 	if home == nil {
@@ -135,7 +135,7 @@ func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) {
 }
 
 // Plainify returns a copy of s with all HTML tags removed.
-func (ns *Namespace) Plainify(s interface{}) (string, error) {
+func (ns *Namespace) Plainify(s any) (string, error) {
 	ss, err := cast.ToStringE(s)
 	if err != nil {
 		return "", err
diff --git a/tpl/transform/transform_test.go b/tpl/transform/transform_test.go
@@ -42,8 +42,8 @@ func TestEmojify(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{":notamoji:", template.HTML(":notamoji:")},
 		{"I :heart: Hugo", template.HTML("I ❤️ Hugo")},
@@ -72,10 +72,10 @@ func TestHighlight(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
+		s      any
 		lang   string
-		opts   interface{}
-		expect interface{}
+		opts   any
+		expect any
 	}{
 		{"func boo() {}", "go", "", "boo"},
 		{"func boo() {}", "go", nil, "boo"},
@@ -117,8 +117,8 @@ func TestHTMLEscape(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{`"Foo & Bar's Diner" <y@z>`, `&#34;Foo &amp; Bar&#39;s Diner&#34; &lt;y@z&gt;`},
 		{"Hugo & Caddy > Wordpress & Apache", "Hugo &amp; Caddy &gt; Wordpress &amp; Apache"},
@@ -147,8 +147,8 @@ func TestHTMLUnescape(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{`&quot;Foo &amp; Bar&#39;s Diner&quot; &lt;y@z&gt;`, `"Foo & Bar's Diner" <y@z>`},
 		{"Hugo &amp; Caddy &gt; Wordpress &amp; Apache", "Hugo & Caddy > Wordpress & Apache"},
@@ -177,8 +177,8 @@ func TestMarkdownify(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"Hello **World!**", template.HTML("Hello <strong>World!</strong>")},
 		{[]byte("Hello Bytes **World!**"), template.HTML("Hello Bytes <strong>World!</strong>")},
@@ -233,8 +233,8 @@ func TestPlainify(t *testing.T) {
 	ns := transform.New(b.H.Deps)
 
 	for _, test := range []struct {
-		s      interface{}
-		expect interface{}
+		s      any
+		expect any
 	}{
 		{"<em>Note:</em> blah <b>blah</b>", "Note: blah blah"},
 		// errors
diff --git a/tpl/transform/unmarshal.go b/tpl/transform/unmarshal.go
@@ -33,18 +33,18 @@ import (
 // Unmarshal unmarshals the data given, which can be either a string, json.RawMessage
 // or a Resource. Supported formats are JSON, TOML, YAML, and CSV.
 // You can optionally provide an options map as the first argument.
-func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) {
+func (ns *Namespace) Unmarshal(args ...any) (any, error) {
 	if len(args) < 1 || len(args) > 2 {
 		return nil, errors.New("unmarshal takes 1 or 2 arguments")
 	}
 
-	var data interface{}
+	var data any
 	decoder := metadecoders.Default
 
 	if len(args) == 1 {
 		data = args[0]
 	} else {
-		m, ok := args[0].(map[string]interface{})
+		m, ok := args[0].(map[string]any)
 		if !ok {
 			return nil, errors.New("first argument must be a map")
 		}
@@ -69,7 +69,7 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) {
 			key += decoder.OptionsKey()
 		}
 
-		return ns.cache.GetOrCreate(key, func() (interface{}, error) {
+		return ns.cache.GetOrCreate(key, func() (any, error) {
 			f := metadecoders.FormatFromMediaType(r.MediaType())
 			if f == "" {
 				return nil, errors.Errorf("MIME %q not supported", r.MediaType())
@@ -101,7 +101,7 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) {
 
 	key := helpers.MD5String(dataStr)
 
-	return ns.cache.GetOrCreate(key, func() (interface{}, error) {
+	return ns.cache.GetOrCreate(key, func() (any, error) {
 		f := decoder.FormatFromContentString(dataStr)
 		if f == "" {
 			return nil, errors.New("unknown format")
@@ -111,7 +111,7 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) {
 	})
 }
 
-func decodeDecoder(m map[string]interface{}) (metadecoders.Decoder, error) {
+func decodeDecoder(m map[string]any) (metadecoders.Decoder, error) {
 	opts := metadecoders.Default
 
 	if m == nil {
@@ -144,7 +144,7 @@ func decodeDecoder(m map[string]interface{}) (metadecoders.Decoder, error) {
 	return opts, err
 }
 
-func stringToRune(v interface{}) (rune, error) {
+func stringToRune(v any) (rune, error) {
 	s, err := cast.ToStringE(v)
 	if err != nil {
 		return 0, err
diff --git a/tpl/transform/unmarshal_test.go b/tpl/transform/unmarshal_test.go
@@ -87,34 +87,34 @@ func TestUnmarshal(t *testing.T) {
 
 	ns := transform.New(b.H.Deps)
 
-	assertSlogan := func(m map[string]interface{}) {
+	assertSlogan := func(m map[string]any) {
 		b.Assert(m["slogan"], qt.Equals, "Hugo Rocks!")
 	}
 
 	for _, test := range []struct {
-		data    interface{}
-		options interface{}
-		expect  interface{}
+		data    any
+		options any
+		expect  any
 	}{
-		{`{ "slogan": "Hugo Rocks!" }`, nil, func(m map[string]interface{}) {
+		{`{ "slogan": "Hugo Rocks!" }`, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{`slogan: "Hugo Rocks!"`, nil, func(m map[string]interface{}) {
+		{`slogan: "Hugo Rocks!"`, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{`slogan = "Hugo Rocks!"`, nil, func(m map[string]interface{}) {
+		{`slogan = "Hugo Rocks!"`, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{testContentResource{key: "r1", content: `slogan: "Hugo Rocks!"`, mime: media.YAMLType}, nil, func(m map[string]interface{}) {
+		{testContentResource{key: "r1", content: `slogan: "Hugo Rocks!"`, mime: media.YAMLType}, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{testContentResource{key: "r1", content: `{ "slogan": "Hugo Rocks!" }`, mime: media.JSONType}, nil, func(m map[string]interface{}) {
+		{testContentResource{key: "r1", content: `{ "slogan": "Hugo Rocks!" }`, mime: media.JSONType}, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{testContentResource{key: "r1", content: `slogan = "Hugo Rocks!"`, mime: media.TOMLType}, nil, func(m map[string]interface{}) {
+		{testContentResource{key: "r1", content: `slogan = "Hugo Rocks!"`, mime: media.TOMLType}, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
-		{testContentResource{key: "r1", content: `<root><slogan>Hugo Rocks!</slogan></root>"`, mime: media.XMLType}, nil, func(m map[string]interface{}) {
+		{testContentResource{key: "r1", content: `<root><slogan>Hugo Rocks!</slogan></root>"`, mime: media.XMLType}, nil, func(m map[string]any) {
 			assertSlogan(m)
 		}},
 		{testContentResource{key: "r1", content: `1997,Ford,E350,"ac, abs, moon",3000.00
@@ -124,18 +124,18 @@ func TestUnmarshal(t *testing.T) {
 			b.Assert(len(first), qt.Equals, 5)
 			b.Assert(first[1], qt.Equals, "Ford")
 		}},
-		{testContentResource{key: "r1", content: `a;b;c`, mime: media.CSVType}, map[string]interface{}{"delimiter": ";"}, func(r [][]string) {
+		{testContentResource{key: "r1", content: `a;b;c`, mime: media.CSVType}, map[string]any{"delimiter": ";"}, func(r [][]string) {
 			b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 		}},
 		{"a,b,c", nil, func(r [][]string) {
 			b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 		}},
-		{"a;b;c", map[string]interface{}{"delimiter": ";"}, func(r [][]string) {
+		{"a;b;c", map[string]any{"delimiter": ";"}, func(r [][]string) {
 			b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 		}},
 		{testContentResource{key: "r1", content: `
 % This is a comment
-a;b;c`, mime: media.CSVType}, map[string]interface{}{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
+a;b;c`, mime: media.CSVType}, map[string]any{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
 			b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 		}},
 		// errors
@@ -149,21 +149,21 @@ a;b;c`, mime: media.CSVType}, map[string]interface{}{"DElimiter": ";", "Comment"
 
 		ns.Reset()
 
-		var args []interface{}
+		var args []any
 
 		if test.options != nil {
-			args = []interface{}{test.options, test.data}
+			args = []any{test.options, test.data}
 		} else {
-			args = []interface{}{test.data}
+			args = []any{test.data}
 		}
 
 		result, err := ns.Unmarshal(args...)
 
 		if bb, ok := test.expect.(bool); ok && !bb {
 			b.Assert(err, qt.Not(qt.IsNil))
-		} else if fn, ok := test.expect.(func(m map[string]interface{})); ok {
+		} else if fn, ok := test.expect.(func(m map[string]any)); ok {
 			b.Assert(err, qt.IsNil)
-			m, ok := result.(map[string]interface{})
+			m, ok := result.(map[string]any)
 			b.Assert(ok, qt.Equals, true)
 			fn(m)
 		} else if fn, ok := test.expect.(func(r [][]string)); ok {
diff --git a/tpl/urls/init.go b/tpl/urls/init.go
@@ -26,7 +26,7 @@ func init() {
 
 		ns := &internal.TemplateFuncsNamespace{
 			Name:    name,
-			Context: func(args ...interface{}) (interface{}, error) { return ctx, nil },
+			Context: func(args ...any) (any, error) { return ctx, nil },
 		}
 
 		ns.AddMethodMapping(ctx.AbsURL,
diff --git a/tpl/urls/urls.go b/tpl/urls/urls.go
@@ -41,7 +41,7 @@ type Namespace struct {
 }
 
 // AbsURL takes a given string and converts it to an absolute URL.
-func (ns *Namespace) AbsURL(a interface{}) (template.HTML, error) {
+func (ns *Namespace) AbsURL(a any) (template.HTML, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", nil
@@ -52,7 +52,7 @@ func (ns *Namespace) AbsURL(a interface{}) (template.HTML, error) {
 
 // Parse parses rawurl into a URL structure. The rawurl may be relative or
 // absolute.
-func (ns *Namespace) Parse(rawurl interface{}) (*url.URL, error) {
+func (ns *Namespace) Parse(rawurl any) (*url.URL, error) {
 	s, err := cast.ToStringE(rawurl)
 	if err != nil {
 		return nil, _errors.Wrap(err, "Error in Parse")
@@ -63,7 +63,7 @@ func (ns *Namespace) Parse(rawurl interface{}) (*url.URL, error) {
 
 // RelURL takes a given string and prepends the relative path according to a
 // page's position in the project directory structure.
-func (ns *Namespace) RelURL(a interface{}) (template.HTML, error) {
+func (ns *Namespace) RelURL(a any) (template.HTML, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", nil
@@ -73,7 +73,7 @@ func (ns *Namespace) RelURL(a interface{}) (template.HTML, error) {
 }
 
 // URLize returns the given argument formatted as URL.
-func (ns *Namespace) URLize(a interface{}) (string, error) {
+func (ns *Namespace) URLize(a any) (string, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", nil
@@ -82,7 +82,7 @@ func (ns *Namespace) URLize(a interface{}) (string, error) {
 }
 
 // Anchorize creates sanitized anchor names that are compatible with Blackfriday.
-func (ns *Namespace) Anchorize(a interface{}) (string, error) {
+func (ns *Namespace) Anchorize(a any) (string, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", nil
@@ -91,7 +91,7 @@ func (ns *Namespace) Anchorize(a interface{}) (string, error) {
 }
 
 // Ref returns the absolute URL path to a given content item.
-func (ns *Namespace) Ref(in interface{}, args interface{}) (template.HTML, error) {
+func (ns *Namespace) Ref(in any, args any) (template.HTML, error) {
 	p, ok := in.(urls.RefLinker)
 	if !ok {
 		return "", errors.New("invalid Page received in Ref")
@@ -105,7 +105,7 @@ func (ns *Namespace) Ref(in interface{}, args interface{}) (template.HTML, error
 }
 
 // RelRef returns the relative URL path to a given content item.
-func (ns *Namespace) RelRef(in interface{}, args interface{}) (template.HTML, error) {
+func (ns *Namespace) RelRef(in any, args any) (template.HTML, error) {
 	p, ok := in.(urls.RefLinker)
 	if !ok {
 		return "", errors.New("invalid Page received in RelRef")
@@ -119,22 +119,22 @@ func (ns *Namespace) RelRef(in interface{}, args interface{}) (template.HTML, er
 	return template.HTML(s), err
 }
 
-func (ns *Namespace) refArgsToMap(args interface{}) (map[string]interface{}, error) {
+func (ns *Namespace) refArgsToMap(args any) (map[string]any, error) {
 	var (
 		s  string
 		of string
 	)
 
 	v := args
-	if _, ok := v.([]interface{}); ok {
+	if _, ok := v.([]any); ok {
 		v = cast.ToStringSlice(v)
 	}
 
 	switch v := v.(type) {
-	case map[string]interface{}:
+	case map[string]any:
 		return v, nil
 	case map[string]string:
-		m := make(map[string]interface{})
+		m := make(map[string]any)
 		for k, v := range v {
 			m[k] = v
 		}
@@ -157,7 +157,7 @@ func (ns *Namespace) refArgsToMap(args interface{}) (map[string]interface{}, err
 
 	}
 
-	return map[string]interface{}{
+	return map[string]any{
 		"path":         s,
 		"outputFormat": of,
 	}, nil
@@ -165,7 +165,7 @@ func (ns *Namespace) refArgsToMap(args interface{}) (map[string]interface{}, err
 
 // RelLangURL takes a given string and prepends the relative path according to a
 // page's position in the project directory structure and the current language.
-func (ns *Namespace) RelLangURL(a interface{}) (template.HTML, error) {
+func (ns *Namespace) RelLangURL(a any) (template.HTML, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", err
@@ -177,7 +177,7 @@ func (ns *Namespace) RelLangURL(a interface{}) (template.HTML, error) {
 // AbsLangURL takes a given string and converts it to an absolute URL according
 // to a page's position in the project directory structure and the current
 // language.
-func (ns *Namespace) AbsLangURL(a interface{}) (template.HTML, error) {
+func (ns *Namespace) AbsLangURL(a any) (template.HTML, error) {
 	s, err := cast.ToStringE(a)
 	if err != nil {
 		return "", err
diff --git a/tpl/urls/urls_test.go b/tpl/urls/urls_test.go
@@ -34,8 +34,8 @@ func TestParse(t *testing.T) {
 	c := qt.New(t)
 
 	for _, test := range []struct {
-		rawurl interface{}
-		expect interface{}
+		rawurl any
+		expect any
 	}{
 		{
 			"http://www.google.com",
diff --git a/transform/urlreplacers/absurlreplacer_test.go b/transform/urlreplacers/absurlreplacer_test.go
@@ -233,4 +233,4 @@ type test struct {
 	expected string
 }
 
-type errorf func(string, ...interface{})
+type errorf func(string, ...any)