--- /dev/null
--- /dev/null
++# Config file for codespell.
++# https://github.com/codespell-project/codespell#using-a-config-file
++
++[codespell]
++
++# Comma separated list of dirs to be skipped.
++skip = _vendor,.cspell.json,chroma.css,chroma_dark.css
++
++# Comma separated list of words to be ignored. Words must be lowercased.
++ignore-words-list = abl,edn,te,ue,trys,januar,womens,crossreferences
++
++# Check file names as well.
++check-filenames = true
--- /dev/null
+{
+ "version": "0.2",
+ "allowCompoundWords": true,
+ "files": [
+ "**/*.md"
+ ],
+ "flagWords": [
+ "alot",
+ "hte",
+ "langauge",
+ "reccommend",
+ "seperate",
+ "teh"
+ ],
+ "ignorePaths": [
+ "**/emojis.md",
+ "**/commands/*",
+ "**/showcase/*",
+ "**/tools/*"
+ ],
+ "ignoreRegExpList": [
+ "# cspell: ignore fenced code blocks",
+ "^(\\s*`{3,}).*[\\s\\S]*?^\\1$",
+ "# cspell: ignore words joined with dot",
+ "\\w+\\.\\w+",
+ "# cspell: ignore strings within backticks",
+ "`.+`",
+ "# cspell: ignore strings within double quotes",
+ "\".+\"",
+ "# cspell: ignore strings within brackets",
+ "\\[.+\\]",
+ "# cspell: ignore strings within parentheses",
+ "\\(.+\\)",
+ "# cspell: ignore words that begin with a slash",
+ "/\\w+",
+ "# cspell: ignore everything within action delimiters",
+ "\\{\\{.+\\}\\}",
+ "# cspell: ignore everything after a right arrow",
+ "\\s+→\\s+.+"
+ ],
+ "language": "en",
+ "words": [
+ "composability",
+ "configurators",
+ "defang",
+ "deindent",
+ "downscale",
+ "downscaling",
+ "exif",
+ "geolocalized",
+ "grayscale",
+ "marshal",
+ "marshaling",
+ "multihost",
+ "multiplatfom",
+ "performantly",
+ "preconfigured",
+ "prerendering",
+ "redirection",
+ "redirections",
+ "subexpression",
+ "suppressible",
+ "templating",
+ "transpile",
+ "unmarshal",
+ "unmarshaling",
+ "unmarshals",
+ "# ----------------------------------------------------------------------",
+ "# cspell: ignore hugo terminology",
+ "# ----------------------------------------------------------------------",
++ "alignx",
+ "attrlink",
+ "canonify",
+ "codeowners",
+ "dynacache",
+ "eturl",
+ "getenv",
+ "gohugo",
+ "gohugoio",
+ "keyvals",
+ "leftdelim",
+ "linkify",
+ "numworkermultiplier",
+ "rightdelim",
+ "shortcode",
+ "stringifier",
+ "struct",
+ "toclevels",
++ "unmarshal",
+ "unpublishdate",
+ "zgotmplz",
+ "# ----------------------------------------------------------------------",
+ "# cspell: ignore foreign language words",
+ "# ----------------------------------------------------------------------",
+ "bezpieczeństwo",
+ "blatt",
+ "buch",
+ "descripción",
+ "dokumentation",
+ "erklärungen",
+ "libros",
+ "mercredi",
+ "miesiąc",
+ "miesiąc",
+ "miesiąca",
+ "miesiące",
+ "miesięcy",
+ "misérables",
+ "mittwoch",
+ "muchos",
+ "novembre",
+ "otro",
+ "pocos",
+ "produkte",
+ "projekt",
+ "prywatność",
+ "referenz",
+ "régime",
+ "# ----------------------------------------------------------------------",
+ "# cspell: ignore names",
+ "# ----------------------------------------------------------------------",
+ "Atishay",
+ "Cosette",
+ "Eliott",
+ "Furet",
+ "Gregor",
+ "Jaco",
+ "Lanczos",
+ "Ninke",
+ "Noll",
+ "Pastorius",
+ "Samsa",
+ "Stucki",
+ "Thénardier",
+ "WASI",
+ "# ----------------------------------------------------------------------",
+ "# cspell: ignore operating systems and software packages",
+ "# ----------------------------------------------------------------------",
+ "asciidoctor",
+ "brotli",
+ "cifs",
+ "corejs",
+ "disqus",
+ "docutils",
+ "dpkg",
+ "doas",
+ "eopkg",
+ "gitee",
+ "goldmark",
+ "katex",
+ "kubuntu",
+ "lubuntu",
+ "mathjax",
+ "nosql",
+ "pandoc",
+ "pkgin",
+ "rclone",
+ "xubuntu",
+ "# ----------------------------------------------------------------------",
+ "# cspell: ignore miscellaneous",
+ "# ----------------------------------------------------------------------",
+ "achristie",
++ "ccpa",
++ "crpa",
+ "ddmaurier",
+ "dring",
+ "fleqn",
+ "inor",
+ "jausten",
+ "jdoe",
+ "jsmith",
+ "leqno",
+ "milli",
+ "rgba",
+ "rsmith",
+ "tdewolff",
+ "tjones",
++ "vcard",
+ "wcag",
+ "xfeff"
+ ]
+}
--- /dev/null
--- /dev/null
++blank_issues_enabled: false
--- /dev/null
--- /dev/null
++---
++name: Default
++about: This is the default issue template.
++labels:
++ - NeedsTriage
++---
--- /dev/null
+name: "Check spelling"
+on:
+ push:
+ pull_request:
+ branches-ignore:
+ - "dependabot/**"
+
+permissions:
+ contents: read
+
+jobs:
+ spellcheck:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: streetsidesoftware/cspell-action@v5
+ with:
+ check_dot_files: false
+ files: content/**/*.md
+ incremental_files_only: true
+ inline: warning
+ strict: false
++ - uses: codespell-project/actions-codespell@v2
++ with:
++ check_filenames: true
++ check_hidden: true
++ # by default, codespell uses configuration from the .codespellrc
--- /dev/null
- /public
++.DS_Store
++.hugo_build.lock
+/.idea
+/.vscode
- node_modules
+/dist
- .DS_Store
- trace.out
- .hugo_build.lock
- resources/_gen/images/
++/public
++hugo_stats.json
++node_modules/
+nohup.out
++package-lock.json
++public/
++resources/
++trace.out
--- /dev/null
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
++See [content/LICENSE.md](content/LICENSE.md) for the license of the content of this repository.
+
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
++The theme (layouts, CSS, JavaScript etc.) of this repository has no open source license. It is custom made for the Hugo sites and is not meant for reuse.
--- /dev/null
+<a href="https://gohugo.io/"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/static/images/hugo-logo-wide.svg?sanitize=true" alt="Hugo" width="565"></a>
+
+A fast and flexible static site generator built with love by [bep], [spf13], and [friends] in [Go].
+
+---
+
+[](https://app.netlify.com/sites/gohugoio/deploys)
+[](https://gohugo.io/contribute/documentation/)
+
+This is the repository for the [Hugo](https://github.com/gohugoio/hugo) documentation site.
+
+Please see the [contributing] section for guidelines, examples, and process.
+
+[bep]: https://github.com/bep
+[spf13]: https://github.com/spf13
+[friends]: https://github.com/gohugoio/hugo/graphs/contributors
+[go]: https://go.dev/
+[contributing]: https://gohugo.io/contribute/documentation
++
++# Install
++
++```bash
++npm i
++hugo server
++```
++
++**Note:** We're working on removing the need to run `npm i` for local development. Stay tuned.
--- /dev/null
- You can insert these definitions in other pages using the `glossary-term` shortcode, so they must be self-contained.
+---
+title: {{ replace .File.ContentBaseName "-" " " }}
++reference:
+---
+
+<!--
- Do this:
++Glossary terms are maintained on dedicated individual pages within the documentation. These pages act as a central repository for all term definitions, although they are not directly visible to site visitors.
+
- A _foo_ is big bar.
-
- Not this:
-
- A big bar.
-
- Italicize the term whenever you use it in the definition.
-
- An exception to this rule occurs when a term is an alias for another. In such cases, it is sufficient to use the phrase 'See [page kind]'."
++Definitions must be presented in complete sentences, with the first sentence always explicitly introducing the term being defined. The first occurrence of the term itself, along with any other referenced glossary terms, should be presented in italics within the definition. However, when a term is an alias for another term, the definition can simply state "See [page kind]" (e.g., "See [page kind]"). These guidelines aim to enhance the readability and consistency of all glossary definitions.
+
++The "reference" field in the front matter of each definition page should be used to include a "See details" link at the end of the definition. This allows for flexible placement of the definition within the documentation while maintaining a central source for the definition itself. The value in the "reference" field must correspond to the logical path of the relevant page within the documentation structure.
+-->
--- /dev/null
--- /dev/null
++/* The ordeer of these does not matter. */
++@import "./content.css";
++@import "./fonts.css";
++@import "./helpers.css";
++@import "./shortcodes.css";
++@import "./tableofcontents.css";
++@import "./view-transitions.css";
--- /dev/null
--- /dev/null
++/* Background */ .bg { background-color: var(--color-light); }
++/* PreWrapper */ .chroma { background-color: var(--color-light); }
++/* Other */ .chroma .x { }
++/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
++/* CodeLine */ .chroma .cl { }
++/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
++/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
++/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
++/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
++/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
++/* Line */ .chroma .line { display: flex; }
++/* Keyword */ .chroma .k { font-weight: bold }
++/* KeywordConstant */ .chroma .kc { font-weight: bold }
++/* KeywordDeclaration */ .chroma .kd { font-weight: bold }
++/* KeywordNamespace */ .chroma .kn { font-weight: bold }
++/* KeywordPseudo */ .chroma .kp { font-weight: bold }
++/* KeywordReserved */ .chroma .kr { font-weight: bold }
++/* KeywordType */ .chroma .kt { color: #445588; font-weight: bold }
++/* Name */ .chroma .n { }
++/* NameAttribute */ .chroma .na { color: #008080 }
++/* NameBuiltin */ .chroma .nb { color: #999999 }
++/* NameBuiltinPseudo */ .chroma .bp { }
++/* NameClass */ .chroma .nc { color: #445588; font-weight: bold }
++/* NameConstant */ .chroma .no { color: #008080 }
++/* NameDecorator */ .chroma .nd { }
++/* NameEntity */ .chroma .ni { color: #800080 }
++/* NameException */ .chroma .ne { color: #990000; font-weight: bold }
++/* NameFunction */ .chroma .nf { color: #990000; font-weight: bold }
++/* NameFunctionMagic */ .chroma .fm { }
++/* NameLabel */ .chroma .nl { }
++/* NameNamespace */ .chroma .nn { color: #555555 }
++/* NameOther */ .chroma .nx { }
++/* NameProperty */ .chroma .py { }
++/* NameTag */ .chroma .nt { color: #000080 }
++/* NameVariable */ .chroma .nv { color: #008080 }
++/* NameVariableClass */ .chroma .vc { }
++/* NameVariableGlobal */ .chroma .vg { }
++/* NameVariableInstance */ .chroma .vi { }
++/* NameVariableMagic */ .chroma .vm { }
++/* Literal */ .chroma .l { }
++/* LiteralDate */ .chroma .ld { }
++/* LiteralString */ .chroma .s { color: #bb8844 }
++/* LiteralStringAffix */ .chroma .sa { color: #bb8844 }
++/* LiteralStringBacktick */ .chroma .sb { color: #bb8844 }
++/* LiteralStringChar */ .chroma .sc { color: #bb8844 }
++/* LiteralStringDelimiter */ .chroma .dl { color: #bb8844 }
++/* LiteralStringDoc */ .chroma .sd { color: #bb8844 }
++/* LiteralStringDouble */ .chroma .s2 { color: #bb8844 }
++/* LiteralStringEscape */ .chroma .se { color: #bb8844 }
++/* LiteralStringHeredoc */ .chroma .sh { color: #bb8844 }
++/* LiteralStringInterpol */ .chroma .si { color: #bb8844 }
++/* LiteralStringOther */ .chroma .sx { color: #bb8844 }
++/* LiteralStringRegex */ .chroma .sr { color: #808000 }
++/* LiteralStringSingle */ .chroma .s1 { color: #bb8844 }
++/* LiteralStringSymbol */ .chroma .ss { color: #bb8844 }
++/* LiteralNumber */ .chroma .m { color: #009999 }
++/* LiteralNumberBin */ .chroma .mb { color: #009999 }
++/* LiteralNumberFloat */ .chroma .mf { color: #009999 }
++/* LiteralNumberHex */ .chroma .mh { color: #009999 }
++/* LiteralNumberInteger */ .chroma .mi { color: #009999 }
++/* LiteralNumberIntegerLong */ .chroma .il { color: #009999 }
++/* LiteralNumberOct */ .chroma .mo { color: #009999 }
++/* Operator */ .chroma .o { font-weight: bold }
++/* OperatorWord */ .chroma .ow { font-weight: bold }
++/* Punctuation */ .chroma .p { }
++/* Comment */ .chroma .c { color: #999988; font-style: italic }
++/* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic }
++/* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic }
++/* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic }
++/* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic }
++/* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold }
++/* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold }
++/* Generic */ .chroma .g { }
++/* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd }
++/* GenericEmph */ .chroma .ge { font-style: italic }
++/* GenericError */ .chroma .gr { color: #aa0000 }
++/* GenericHeading */ .chroma .gh { color: #999999 }
++/* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd }
++/* GenericOutput */ .chroma .go { color: #888888 }
++/* GenericPrompt */ .chroma .gp { color: #555555 }
++/* GenericStrong */ .chroma .gs { font-weight: bold }
++/* GenericSubheading */ .chroma .gu { color: #aaaaaa }
++/* GenericTraceback */ .chroma .gt { color: #aa0000 }
++/* GenericUnderline */ .chroma .gl { text-decoration: underline }
++/* TextWhitespace */ .chroma .w { color: #bbbbbb }
--- /dev/null
--- /dev/null
++/* Background */.dark .bg { background-color: var(--color-dark); }
++/* PreWrapper */ .dark .chroma { background-color: var(--color-dark); }
++/* Other */ .dark .chroma .x { }
++/* Error */ .dark .chroma .err { color: #ef6155 }
++/* CodeLine */ .dark .chroma .cl { }
++/* LineTableTD */ .dark .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
++/* LineTable */ .dark .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
++/* LineHighlight */ .dark .chroma .hl { background-color: #ffffcc }
++/* LineNumbersTable */ .dark .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
++/* LineNumbers */ .dark .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
++/* Line */ .dark .chroma .line { display: flex; }
++/* Keyword */ .dark .chroma .k { color: #815ba4 }
++/* KeywordConstant */ .dark .chroma .kc { color: #815ba4 }
++/* KeywordDeclaration */ .dark .chroma .kd { color: #815ba4 }
++/* KeywordNamespace */ .dark .chroma .kn { color: #5bc4bf }
++/* KeywordPseudo */ .dark .chroma .kp { color: #815ba4 }
++/* KeywordReserved */ .dark .chroma .kr { color: #815ba4 }
++/* KeywordType */ .dark .chroma .kt { color: #fec418 }
++/* Name */ .dark .chroma .n { }
++/* NameAttribute */ .dark .chroma .na { color: #06b6ef }
++/* NameBuiltin */ .dark .chroma .nb { }
++/* NameBuiltinPseudo */ .dark .chroma .bp { }
++/* NameClass */ .dark .chroma .nc { color: #fec418 }
++/* NameConstant */ .dark .chroma .no { color: #ef6155 }
++/* NameDecorator */ .dark .chroma .nd { color: #5bc4bf }
++/* NameEntity */ .dark .chroma .ni { }
++/* NameException */ .dark .chroma .ne { color: #ef6155 }
++/* NameFunction */ .dark .chroma .nf { color: #06b6ef }
++/* NameFunctionMagic */ .dark .chroma .fm { }
++/* NameLabel */ .dark .chroma .nl { }
++/* NameNamespace */ .dark .chroma .nn { color: #fec418 }
++/* NameOther */ .dark .chroma .nx { color: #06b6ef }
++/* NameProperty */ .dark .chroma .py { }
++/* NameTag */ .dark .chroma .nt { color: #5bc4bf }
++/* NameVariable */ .dark .chroma .nv { color: #ef6155 }
++/* NameVariableClass */ .dark .chroma .vc { }
++/* NameVariableGlobal */ .dark .chroma .vg { }
++/* NameVariableInstance */ .dark .chroma .vi { }
++/* NameVariableMagic */ .dark .chroma .vm { }
++/* Literal */ .dark .chroma .l { color: #f99b15 }
++/* LiteralDate */ .dark .chroma .ld { color: #48b685 }
++/* LiteralString */ .dark .chroma .s { color: #48b685 }
++/* LiteralStringAffix */ .dark .chroma .sa { color: #48b685 }
++/* LiteralStringBacktick */ .dark .chroma .sb { color: #48b685 }
++/* LiteralStringChar */ .dark .chroma .sc { }
++/* LiteralStringDelimiter */ .dark .chroma .dl { color: #48b685 }
++/* LiteralStringDoc */ .dark .chroma .sd { color: #776e71 }
++/* LiteralStringDouble */ .dark .chroma .s2 { color: #48b685 }
++/* LiteralStringEscape */ .dark .chroma .se { color: #f99b15 }
++/* LiteralStringHeredoc */ .dark .chroma .sh { color: #48b685 }
++/* LiteralStringInterpol */ .dark .chroma .si { color: #f99b15 }
++/* LiteralStringOther */ .dark .chroma .sx { color: #48b685 }
++/* LiteralStringRegex */ .dark .chroma .sr { color: #48b685 }
++/* LiteralStringSingle */ .dark .chroma .s1 { color: #48b685 }
++/* LiteralStringSymbol */ .dark .chroma .ss { color: #48b685 }
++/* LiteralNumber */ .dark .chroma .m { color: #f99b15 }
++/* LiteralNumberBin */ .dark .chroma .mb { color: #f99b15 }
++/* LiteralNumberFloat */ .dark .chroma .mf { color: #f99b15 }
++/* LiteralNumberHex */ .dark .chroma .mh { color: #f99b15 }
++/* LiteralNumberInteger */ .dark .chroma .mi { color: #f99b15 }
++/* LiteralNumberIntegerLong */ .dark .chroma .il { color: #f99b15 }
++/* LiteralNumberOct */ .dark .chroma .mo { color: #f99b15 }
++/* Operator */ .dark .chroma .o { color: #5bc4bf }
++/* OperatorWord */ .dark .chroma .ow { color: #5bc4bf }
++/* Punctuation */ .dark .chroma .p { }
++/* Comment */ .dark .chroma .c { color: #776e71 }
++/* CommentHashbang */ .dark .chroma .ch { color: #776e71 }
++/* CommentMultiline */ .dark .chroma .cm { color: #776e71 }
++/* CommentSingle */ .dark .chroma .c1 { color: #776e71 }
++/* CommentSpecial */ .dark .chroma .cs { color: #776e71 }
++/* CommentPreproc */ .dark .chroma .cp { color: #776e71 }
++/* CommentPreprocFile */ .dark .chroma .cpf { color: #776e71 }
++/* Generic */ .dark .chroma .g { }
++/* GenericDeleted */ .dark .chroma .gd { color: #ef6155 }
++/* GenericEmph */ .dark .chroma .ge { font-style: italic }
++/* GenericError */ .dark .chroma .gr { }
++/* GenericHeading */ .dark .chroma .gh { font-weight: bold }
++/* GenericInserted */ .dark .chroma .gi { color: #48b685 }
++/* GenericOutput */ .dark .chroma .go { }
++/* GenericPrompt */ .dark .chroma .gp { color: #776e71; font-weight: bold }
++/* GenericStrong */ .dark .chroma .gs { font-weight: bold }
++/* GenericSubheading */ .dark .chroma .gu { color: #5bc4bf; font-weight: bold }
++/* GenericTraceback */ .dark .chroma .gt { }
++/* GenericUnderline */ .dark .chroma .gl { }
++/* TextWhitespace */ .dark .chroma .w { }
--- /dev/null
--- /dev/null
++@import "./chroma_dark.css";
++@import "./chroma.css";
++@import "./highlight.css";
++
++/* Some contrast ratio fixes as reported by Google Page Speed. */
++.chroma .c1 {
++ @apply text-gray-500;
++}
++
++.dark .chroma .c1 {
++ @apply text-gray-400;
++}
++
++.highlight code {
++ @apply text-sm;
++}
++
++.content {
++ @apply prose prose-sm sm:prose-base prose-stone max-w-none dark:prose-invert dark:text-slate-200;
++ /* headings */
++ @apply prose-h4:font-bold prose-h5:font-bold prose-h6:font-bold;
++ /* lead */
++ @apply prose-lead:text-slate-500 prose-lead:text-xl prose-lead:mt-2 sm:prose-lead:mt-4 prose-lead:leading-relaxed dark:prose-lead:text-slate-400;
++ /* links */
++ @apply prose-a:text-primary prose-a:hover:text-primary/70 prose-a:underline;
++ @apply prose-a:prose-code:underline prose-a:prose-code:hover:text-primary/70 prose-a:prose-code:hover:underline;
++ /* pre */
++ @apply prose-pre:text-gray-800 prose-pre:border-1 prose-pre:border-gray-100 prose-pre:bg-light dark:prose-pre:bg-dark dark:prose-pre:ring-1 dark:prose-pre:ring-slate-300/10;
++ /* code */
++ @apply prose-code:px-0.5 prose-code:text-gray-500 prose-code:dark:text-gray-300 border-none;
++ @apply prose-code:before:hidden prose-code:after:hidden prose-code:font-mono;
++ /* tables */
++ @apply prose-table:border-2 prose-table:border-gray-100 prose-table:dark:border-gray-800 prose-table:relative prose-table:overflow-scroll prose-table:prose-th:font-bold prose-table:prose-th:bg-blue-500 dark:prose-table:prose-th:bg-blue-500/50 prose-table:prose-th:p-2 prose-table:prose-td:p-2 prose-table:prose-th:text-white;
++ /* hr */
++ @apply dark:prose-hr:border-slate-800;
++
++ h6 + * {
++ @apply mt-2;
++ }
++}
++
++/* This will not match highlighting inside e.g. the code-toggle shortcode. */
++/* For more fine grained control of this, see components/shortcodes.css. */
++.content > .highlight,
++.content dd > .highlight,
++.content li > .highlight {
++ @apply border-1 border-gray-200 dark:border-slate-600 mt-6 mb-8;
++}
--- /dev/null
--- /dev/null
++@font-face {
++ font-family: "Mulish";
++ font-style: normal;
++ src: url("../fonts/Mulish-VariableFont_wght.ttf") format("truetype");
++ font-weight: 1 999;
++ font-display: swap;
++}
++
++@font-face {
++ font-family: "Mulish";
++ font-style: italic;
++ src: url("../fonts/Mulish-Italic-VariableFont_wght.ttf") format("truetype");
++ font-weight: 1 999;
++ font-display: swap;
++}
--- /dev/null
--- /dev/null
++/* Helper class to limit a text block to two lines. */
++.two-lines-ellipsis {
++ display: block;
++ display: -webkit-box;
++ -webkit-line-clamp: 2;
++ -webkit-box-orient: vertical;
++ overflow: hidden;
++ text-overflow: ellipsis;
++}
++
++/* Helper class to limit a text block to three lines. */
++.three-lines-ellipsis {
++ display: block;
++ display: -webkit-box;
++ -webkit-line-clamp: 3;
++ -webkit-box-orient: vertical;
++ overflow: hidden;
++ text-overflow: ellipsis;
++}
--- /dev/null
--- /dev/null
++.highlight {
++ @apply bg-light dark:bg-dark rounded-none;
++}
++
++.highlight pre {
++ @apply m-0 p-3 w-full h-full overflow-x-auto dark:border-black rounded-none;
++}
++
++.highlight pre code {
++ @apply m-0 p-0 w-full h-full;
++}
--- /dev/null
--- /dev/null
++.shortcode-code {
++ .highlight {
++ }
++}
--- /dev/null
--- /dev/null
++.tableofcontents {
++ ul {
++ @apply list-none;
++ li {
++ @apply mb-2;
++ a {
++ @apply text-primary;
++ &:hover {
++ @apply text-primary/60;
++ }
++ }
++ }
++ }
++}
--- /dev/null
--- /dev/null
++/* Global slight fade */
++::view-transition-old(root),
++::view-transition-new(root) {
++ animation-duration: 200ms;
++}
++
++::view-transition-old(qr),
++::view-transition-new(qr) {
++ animation-duration: 800ms;
++ animation-delay: 250ms;
++}
++
++.view-transition-qr {
++ view-transition-name: qr;
++}
++
++/* Turbo styles */
++.turbo-progress-bar {
++ @apply bg-blue-500;
++ opacity: 0.35;
++ height: 3px;
++}
--- /dev/null
--- /dev/null
++@import "tailwindcss";
++@plugin "@tailwindcss/typography";
++@variant dark (&:where(.dark, .dark *));
++
++@import "components/all.css";
++
++/* TailwindCSS ignores files in .gitignore, so make it explicit. */
++@source "hugo_stats.json";
++
++@theme {
++ /* Breakpoints. */
++ --breakpoint-sm: 40rem;
++ --breakpoint-md: 48rem;
++ --breakpoint-lg: 68rem; /* Default 64rem; */
++ --breakpoint-xl: 80rem;
++ --breakpoint-2xl: 96rem;
++
++ /* Colors. */
++ --color-primary: var(--color-blue-600);
++ --color-dark: #000;
++ --color-light: var(--color-gray-50);
++ --color-accent: var(--color-orange-500);
++ --color-accent-light: var(--color-pink-500);
++ --color-accent-dark: var(--color-green-500);
++
++ /* https://www.tints.dev/blue/0594CB */
++ --color-blue-50: #e1f6fe;
++ --color-blue-100: #c3edfe;
++ --color-blue-200: #88dbfc;
++ --color-blue-300: #4cc9fb;
++ --color-blue-400: #15b9f9;
++ --color-blue-500: #0594cb;
++ --color-blue-600: #0477a4;
++ --color-blue-700: #035677;
++ --color-blue-800: #023a50;
++ --color-blue-900: #011d28;
++ --color-blue-950: #000e14;
++
++ /* https://www.tints.dev/orange/EBB951 */
++ --color-orange-50: #fdf8ed;
++ --color-orange-100: #fbf1da;
++ --color-orange-200: #f7e4ba;
++ --color-orange-300: #f3d596;
++ --color-orange-400: #efc976;
++ --color-orange-500: #ebb951;
++ --color-orange-600: #e5a51a;
++ --color-orange-700: #a97a13;
++ --color-orange-800: #72520d;
++ --color-orange-900: #372806;
++ --color-orange-950: #1b1403;
++
++ /* https://www.tints.dev/pink/FF4088 */
++ --color-pink-50: #ffebf2;
++ --color-pink-100: #ffdbe9;
++ --color-pink-200: #ffb3d0;
++ --color-pink-300: #ff8fba;
++ --color-pink-400: #ff66a1;
++ --color-pink-500: #ff4088;
++ --color-pink-600: #ff0062;
++ --color-pink-700: #c2004a;
++ --color-pink-800: #800031;
++ --color-pink-900: #420019;
++ --color-pink-950: #1f000c;
++
++ /* https://www.tints.dev/green/33BA91 */
++ --color-green-50: #ebfaf5;
++ --color-green-100: #d3f3e9;
++ --color-green-200: #abe8d6;
++ --color-green-300: #7fdcc0;
++ --color-green-400: #53d0aa;
++ --color-green-500: #33ba91;
++ --color-green-600: #299474;
++ --color-green-700: #1f7058;
++ --color-green-800: #154c3b;
++ --color-green-900: #0a241c;
++ --color-green-950: #051410;
++
++ /* Fonts. */
++ --font-sans: "Mulish", ui-sans-serif, system-ui, sans-serif,
++ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
++}
++
++html {
++ scroll-padding-top: 100px;
++}
++
++body {
++ @apply antialiased font-sans text-black dark:text-gray-100;
++}
++
++.p-safe-area-x {
++ padding-left: env(safe-area-inset-left);
++ padding-right: env(safe-area-inset-right);
++}
++
++.p-safe-area-y {
++ padding-top: env(safe-area-inset-top);
++ padding-bottom: env(safe-area-inset-bottom);
++}
++
++.px-main {
++ padding-left: max(env(safe-area-inset-left), 1rem);
++ padding-right: max(env(safe-area-inset-right), 1rem);
++}
++
++@media screen(md) {
++ .px-main {
++ padding-left: max(env(safe-area-inset-left), 2rem);
++ padding-right: max(env(safe-area-inset-right), 2rem);
++ }
++}
++
++@media screen(lg) {
++ .px-main {
++ padding-left: max(env(safe-area-inset-left), 3rem);
++ padding-right: max(env(safe-area-inset-right), 3rem);
++ }
++}
++
++/* Algolia DocSearch */
++.algolia-docsearch-suggestion--highlight {
++ color: var(--color-primary);
++}
--- /dev/null
--- /dev/null
++<svg width="150" height="36" viewBox="0 0 150 36" fill="none" xmlns="http://www.w3.org/2000/svg">
++<path fill-rule="evenodd" clip-rule="evenodd" d="M38.9337 13.4895H41.1147C41.4378 13.4895 41.8417 13.4895 42.1648 13.4895C42.5686 13.4895 42.8917 13.4087 43.2148 13.2472C43.5379 13.0856 43.7803 12.9241 43.9418 12.6818C44.1034 12.4394 44.2649 12.0355 44.2649 11.6317C44.2649 11.2278 44.1841 10.8239 44.0226 10.5816C43.861 10.3393 43.6187 10.0969 43.3764 10.0162C43.1341 9.85461 42.811 9.77384 42.4879 9.77384C42.1648 9.69306 41.7609 9.69306 41.4378 9.69306H39.0145V13.4895H38.9337ZM35.2181 6.46204H41.7609C42.6494 6.46204 43.4572 6.54282 44.1841 6.70437C44.9919 6.86592 45.6381 7.18902 46.2035 7.51212C46.769 7.916 47.2536 8.40065 47.5767 9.12763C47.8998 9.77384 48.0614 10.6624 48.0614 11.6317C48.0614 12.8433 47.7383 13.8934 47.0921 14.7011C46.4459 15.5089 45.5573 16.0743 44.3457 16.3166L48.6268 23.5057H44.1841L40.63 16.7205H38.7722V23.5057H35.0565V6.46204H35.2181Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M53.3926 17.6091C53.3926 18.4976 53.6349 19.2246 54.1195 19.79C54.6042 20.3554 55.3312 20.5977 56.2197 20.5977C57.1082 20.5977 57.8352 20.3554 58.3199 19.79C58.8045 19.2246 59.0468 18.4976 59.0468 17.6091C59.0468 16.7205 58.8045 15.9935 58.3199 15.4281C57.8352 14.8627 57.1082 14.6204 56.2197 14.6204C55.3312 14.6204 54.6042 14.8627 54.1195 15.4281C53.6349 16.0743 53.3926 16.7205 53.3926 17.6091ZM49.8384 17.6091C49.8384 16.6397 50 15.832 50.3231 15.105C50.6462 14.378 51.1308 13.7318 51.6963 13.1664C52.2617 12.601 52.9887 12.1971 53.7157 11.9548C54.5234 11.6317 55.3312 11.5509 56.2197 11.5509C57.1082 11.5509 57.916 11.7124 58.7237 11.9548C59.5315 12.2779 60.1777 12.6818 60.7431 13.1664C61.3086 13.7318 61.7932 14.378 62.1163 15.105C62.4394 15.832 62.601 16.7205 62.601 17.6091C62.601 18.5784 62.4394 19.3861 62.1163 20.1131C61.7932 20.8401 61.3086 21.4863 60.7431 22.0517C60.1777 22.6171 59.4507 23.021 58.7237 23.2633C57.916 23.5864 57.1082 23.6672 56.2197 23.6672C55.3312 23.6672 54.5234 23.5057 53.7157 23.2633C52.9079 22.9402 52.2617 22.5364 51.6963 22.0517C51.1308 21.4863 50.6462 20.8401 50.3231 20.1131C50 19.3861 49.8384 18.5784 49.8384 17.6091Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M75.929 23.5057H72.4556V21.8902H72.3748C72.2133 22.1325 72.0517 22.3748 71.8902 22.5364C71.7286 22.7787 71.4863 22.9403 71.1632 23.1826C70.8401 23.3441 70.517 23.5057 70.1939 23.5865C69.79 23.6672 69.4669 23.748 68.9823 23.748C68.0937 23.748 67.3668 23.5865 66.8013 23.3441C66.2359 23.1018 65.832 22.6979 65.5089 22.2133C65.1858 21.7286 65.0243 21.1632 64.8627 20.4362C64.782 19.79 64.7012 19.063 64.7012 18.2553V11.7932H68.2553V17.5283C68.2553 17.8514 68.2553 18.1745 68.2553 18.5784C68.2553 18.9015 68.3361 19.3054 68.4976 19.5477C68.6592 19.79 68.8207 20.1131 69.063 20.2747C69.3054 20.4362 69.6285 20.5978 70.1131 20.5978C70.5978 20.5978 70.9209 20.517 71.244 20.3554C71.5671 20.1939 71.7286 19.9516 71.8902 19.7092C72.0517 19.4669 72.1325 19.1438 72.2133 18.7399C72.2941 18.4168 72.2941 18.013 72.2941 17.6091V11.7932H75.929V23.5057Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M86.3489 14.7011H83.1987V18.5784C83.1987 18.9015 83.1987 19.2246 83.2794 19.4669C83.2794 19.7092 83.3602 19.9515 83.5218 20.1131C83.6026 20.2746 83.7641 20.4362 84.0064 20.5977C84.2488 20.6785 84.5719 20.7593 84.895 20.7593C85.0565 20.7593 85.2988 20.7593 85.6219 20.6785C85.945 20.6785 86.1874 20.517 86.3489 20.4362V23.4249C85.945 23.5864 85.5412 23.6672 85.1373 23.748C84.7334 23.8288 84.2488 23.8288 83.8449 23.8288C83.2795 23.8288 82.714 23.748 82.1486 23.6672C81.6639 23.5057 81.1793 23.3441 80.7754 23.021C80.3715 22.7787 80.1292 22.3748 79.8869 21.8902C79.6446 21.4055 79.5638 20.9208 79.5638 20.2746V14.7011H77.3021V11.7932H79.5638V8.31988H83.1179V11.7932H86.2681V14.7011H86.3489Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M96.1228 16.3166C96.1228 15.6704 95.9612 15.1858 95.5573 14.7819C95.1535 14.378 94.588 14.1357 93.9418 14.1357C93.5379 14.1357 93.2148 14.2165 92.8917 14.2973C92.5686 14.4588 92.3263 14.6204 92.084 14.7819C91.8417 15.0242 91.6801 15.1858 91.5993 15.5089C91.5186 15.7512 91.4378 16.0743 91.357 16.3166H96.1228ZM99.1922 21.4863C98.6268 22.2133 97.8998 22.7787 97.0113 23.1826C96.1228 23.5864 95.2342 23.748 94.2649 23.748C93.3764 23.748 92.5686 23.5864 91.7609 23.3441C90.9531 23.021 90.3069 22.6171 89.7415 22.1325C89.1761 21.567 88.6914 20.9208 88.3683 20.1939C88.0452 19.4669 87.8837 18.5784 87.8837 17.6898C87.8837 16.7205 88.0452 15.9128 88.3683 15.1858C88.6914 14.4588 89.1761 13.8126 89.7415 13.2472C90.3069 12.6817 91.0339 12.2779 91.7609 12.0355C92.5686 11.7124 93.3764 11.6317 94.2649 11.6317C95.0727 11.6317 95.8804 11.7932 96.5266 12.0355C97.1728 12.3586 97.7383 12.7625 98.2229 13.2472C98.7076 13.8126 99.0307 14.4588 99.273 15.1858C99.5153 15.9128 99.6769 16.8013 99.6769 17.6898V18.8207H91.357C91.5186 19.5477 91.8417 20.0323 92.3263 20.4362C92.811 20.8401 93.3764 21.0824 94.1034 21.0824C94.6688 21.0824 95.1535 20.9208 95.5573 20.6785C95.9612 20.4362 96.2843 20.0323 96.6074 19.6284L99.1922 21.4863Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M108.562 11.147L104.766 17.0436H108.562V11.147ZM108.562 20.1131H101.212V17.0436L108.078 6.46205H111.955V17.0436H114.136V20.1131H111.955V23.5057H108.481V20.1131H108.562Z" fill="#FFC63C"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M116.478 6.46205H122.052L126.01 17.6091L129.968 6.46205H135.541V23.5057H131.826V10.42H131.745L127.302 23.5057H124.475L120.194 10.42V23.5057H116.478V6.46205Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M146.446 16.3166C146.446 15.6704 146.284 15.1858 145.88 14.7819C145.477 14.378 144.911 14.1357 144.265 14.1357C143.861 14.1357 143.538 14.2165 143.215 14.2973C142.892 14.4588 142.649 14.6204 142.407 14.7819C142.165 15.0242 142.003 15.1858 141.922 15.5089C141.842 15.7512 141.761 16.0743 141.68 16.3166H146.446ZM149.515 21.4863C148.95 22.2133 148.223 22.7787 147.334 23.1826C146.446 23.5864 145.557 23.748 144.588 23.748C143.7 23.748 142.892 23.5864 142.084 23.3441C141.276 23.021 140.63 22.6171 140.065 22.1325C139.499 21.567 139.015 20.9208 138.691 20.1939C138.368 19.4669 138.207 18.5784 138.207 17.6898C138.207 16.7205 138.368 15.9128 138.691 15.1858C139.015 14.4588 139.499 13.8126 140.065 13.2472C140.63 12.6817 141.357 12.2779 142.084 12.0355C142.892 11.7124 143.7 11.6317 144.588 11.6317C145.396 11.6317 146.204 11.7932 146.85 12.0355C147.496 12.3586 148.061 12.7625 148.546 13.2472C149.031 13.8126 149.354 14.4588 149.596 15.1858C149.838 15.9128 150 16.8013 150 17.6898V18.8207H141.68C141.842 19.5477 142.165 20.0323 142.649 20.4362C143.134 20.8401 143.7 21.0824 144.426 21.0824C144.992 21.0824 145.477 20.9208 145.88 20.6785C146.284 20.4362 146.607 20.0323 146.931 19.6284L149.515 21.4863Z" fill="#425277"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M28.1906 1.53473C28.1906 0.646204 28.9176 0 29.7253 0C30.6139 0 31.2601 0.726979 31.2601 1.53473C31.2601 2.42326 30.5331 3.06947 29.7253 3.06947C28.9176 3.15024 28.1906 2.42326 28.1906 1.53473Z" fill="#FF6400"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1.53473C0 0.726979 0.726979 0 1.53473 0C2.42326 0 3.15024 0.726979 3.15024 1.53473C3.15024 2.42326 2.42326 3.15024 1.53473 3.15024C0.726979 3.15024 0 2.42326 0 1.53473Z" fill="#FF6400"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M22.2941 33.6834C22.2941 32.7948 23.021 32.1486 23.8288 32.1486C24.7173 32.1486 25.3635 32.8756 25.3635 33.6834C25.3635 34.5719 24.6366 35.2181 23.8288 35.2181C23.021 35.2181 22.2941 34.5719 22.2941 33.6834Z" fill="#FF6400"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M20.0323 6.62363C20.2746 6.86595 20.2746 7.18906 20.0323 7.35061L17.3667 10.0162C17.1244 10.2585 17.2051 10.4201 17.5283 10.5816C19.063 11.1471 20.2746 12.3587 20.7593 13.8126C20.84 14.055 21.0824 14.1357 21.3247 13.9742L23.9903 11.3086C24.2326 11.0663 24.5557 11.0663 24.7173 11.3086L27.0598 13.6511C27.3021 13.8934 27.4636 13.8126 27.4636 13.4895V4.20036C27.4636 4.03881 27.3829 3.95804 27.2213 3.95804H17.8514C17.5282 3.95804 17.5282 4.11959 17.6898 4.36191L20.0323 6.62363ZM13.7318 10.5008C13.9741 10.4201 14.0549 10.1777 13.8934 9.93542L11.2278 7.26983C10.9854 7.0275 10.9854 6.7044 11.2278 6.54285L13.5703 4.20036C13.8126 3.95804 13.7318 3.79649 13.4087 3.79649H4.2003C4.03875 3.95804 3.8772 4.03881 3.8772 4.20036V13.4895C3.8772 13.8126 4.03875 13.8126 4.28107 13.6511L6.62356 11.3086C6.86589 11.0663 7.18899 11.0663 7.35054 11.3086L10.0161 13.9742C10.2585 14.2165 10.42 14.1357 10.5816 13.8126C11.0662 12.2779 12.2778 11.0663 13.7318 10.5008ZM15.9127 21.1632C15.5896 21.1632 15.5089 21.4055 15.5896 21.6479L17.1244 25.0404C17.2051 25.2828 17.1244 25.6059 16.882 25.7674L13.8934 27.1406C13.651 27.3021 13.651 27.4637 13.8934 27.5445L22.6171 30.6947C22.7787 30.7755 22.9402 30.6947 22.9402 30.5332L26.1712 21.8094C26.252 21.5671 26.1712 21.4055 25.8481 21.5671L22.8594 22.9403C22.6171 23.1018 22.294 22.9403 22.1324 22.6979L20.4362 19.063C20.3554 18.8207 20.1131 18.8207 19.9515 18.9823C19.4669 19.6285 18.8207 20.1939 18.0129 20.5978C17.5282 20.8401 16.882 21.0017 16.3166 21.0824C16.3166 21.0824 16.0743 21.1632 15.9127 21.1632Z" fill="#FFC63C"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7124 15.6705C11.7124 13.4895 13.4895 11.7932 15.5896 11.7932C17.7706 11.7932 19.4668 13.5703 19.4668 15.6705C19.4668 17.8514 17.6898 19.6285 15.5896 19.6285C13.4895 19.5477 11.7124 17.8514 11.7124 15.6705Z" fill="#FF6400"/>
++</svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 255 180" fill="none" xmlns="http://www.w3.org/2000/svg">
++<rect fill="#AD1E1E"/>
++<path d="M29.25 60.5C31.1167 60.0667 32.85 59.85 34.45 59.85C36.05 59.85 37.4 59.9 38.5 60V72.5C39.2 72 40.1333 71.5667 41.3 71.2C42.4667 70.8 43.5833 70.6 44.65 70.6C48.2833 70.6 50.8333 71.5333 52.3 73.4C53.7667 75.2667 54.5 78.45 54.5 82.95C54.5 85.45 54.15 87.6167 53.45 89.45C52.7833 91.25 51.8667 92.6333 50.7 93.6C48.5 95.4667 45.9 96.4 42.9 96.4C40.6333 96.4 38.4 95.8333 36.2 94.7C35.5667 95.5667 34.8333 96 34 96H31.5V66.05C30.3333 65.65 29.4167 65.0833 28.75 64.35L29.25 60.5ZM42.5 91.3C45.7 91.3 47.3 88.6167 47.3 83.25C47.3 80.4167 47.0167 78.5 46.45 77.5C45.9167 76.4667 44.9667 75.95 43.6 75.95C41.5333 75.95 39.8333 76.5 38.5 77.6V90.45C39.9333 91.0167 41.2667 91.3 42.5 91.3ZM69.1555 96.4C65.1555 96.4 62.1388 95.3333 60.1055 93.2C58.1055 91.0667 57.1055 87.9667 57.1055 83.9C57.1055 81.4333 57.4555 79.3167 58.1555 77.55C58.8555 75.75 59.8055 74.3667 61.0055 73.4C63.3388 71.5333 66.0555 70.6 69.1555 70.6C72.2555 70.6 74.6221 71.4 76.2555 73C77.9221 74.5667 78.7555 77.4 78.7555 81.5C78.7555 83.9 77.5721 85.1 75.2055 85.1H64.3555C64.4888 87.2 65.0221 88.6833 65.9555 89.55C66.9221 90.4167 68.4388 90.85 70.5055 90.85C71.6388 90.85 72.7221 90.7167 73.7555 90.45C74.7888 90.1833 75.5388 89.9167 76.0055 89.65L76.7055 89.25L78.2055 93.25C78.0055 93.4833 77.7055 93.7833 77.3055 94.15C76.9388 94.4833 75.9721 94.95 74.4055 95.55C72.8721 96.1167 71.1221 96.4 69.1555 96.4ZM72.3055 80.65C72.3721 80.1833 72.4055 79.6167 72.4055 78.95C72.4055 78.2833 72.1388 77.5833 71.6055 76.85C71.0721 76.0833 70.1388 75.7 68.8055 75.7C67.5055 75.7 66.5055 76.1 65.8055 76.9C65.1055 77.7 64.6388 79.05 64.4055 80.95L72.3055 80.65ZM81.2754 71C83.1087 70.6 84.7587 70.4 86.2254 70.4C87.6921 70.4 88.9087 70.4333 89.8754 70.5V72.95C92.1087 71.3833 94.4921 70.6 97.0254 70.6C100.359 70.6 102.775 71.55 104.275 73.45C105.775 75.35 106.525 78.5167 106.525 82.95C106.525 85.3167 106.175 87.4 105.475 89.2C104.775 91 103.825 92.4 102.625 93.4C100.325 95.4 97.5921 96.4 94.4254 96.4C93.0587 96.4 91.7587 96.2667 90.5254 96V100.3C92.4921 100.833 93.7587 101.45 94.3254 102.15L93.8254 106H81.2754L80.7754 102.15C81.2087 101.55 82.1254 100.983 83.5254 100.45V76.55C82.3587 76.15 81.4421 75.5833 80.7754 74.85L81.2754 71ZM93.9254 91.3C95.5921 91.3 96.9087 90.5667 97.8754 89.1C98.8421 87.6 99.3254 85.55 99.3254 82.95C99.3254 80.3167 99.0587 78.5167 98.5254 77.55C97.9921 76.5833 97.0254 76.1 95.6254 76.1C93.4921 76.1 91.7921 76.6 90.5254 77.6V90.9C91.5587 91.1667 92.6921 91.3 93.9254 91.3ZM110.689 96.24C109.361 96.24 108.697 95.64 108.697 94.44C108.697 93.224 109.361 92.616 110.689 92.616C112.033 92.616 112.705 93.224 112.705 94.44C112.705 95.64 112.033 96.24 110.689 96.24ZM119.838 86.256C118.366 86.256 117.63 87.52 117.63 90.048C117.63 91.328 117.83 92.224 118.23 92.736C118.646 93.232 119.238 93.48 120.006 93.48C121.222 93.48 122.294 93.368 123.222 93.144L123.942 94.992C123.43 95.328 122.742 95.616 121.878 95.856C121.014 96.08 120.174 96.192 119.358 96.192C115.902 96.192 114.174 94.192 114.174 90.192C114.174 87.856 114.774 86.176 115.974 85.152C117.046 84.256 118.35 83.808 119.886 83.808C121.422 83.808 122.702 84.096 123.726 84.672C123.742 84.832 123.75 84.984 123.75 85.128C123.75 86.04 123.542 86.904 123.126 87.72H121.014C120.79 87.32 120.654 86.84 120.606 86.28C120.414 86.264 120.158 86.256 119.838 86.256ZM130.453 96.192C128.565 96.192 127.165 95.688 126.253 94.68C125.341 93.672 124.885 92.152 124.885 90.12C124.885 88.072 125.389 86.512 126.397 85.44C127.421 84.352 128.885 83.808 130.789 83.808C132.693 83.808 134.101 84.288 135.013 85.248C135.941 86.208 136.405 87.712 136.405 89.76C136.405 91.792 135.885 93.376 134.845 94.512C133.821 95.632 132.357 96.192 130.453 96.192ZM128.341 89.904C128.341 92.464 129.109 93.744 130.645 93.744C131.429 93.744 132.005 93.456 132.373 92.88C132.757 92.288 132.949 91.328 132.949 90C132.949 87.504 132.165 86.256 130.597 86.256C129.829 86.256 129.261 86.536 128.893 87.096C128.525 87.64 128.341 88.576 128.341 89.904ZM137.876 84C138.756 83.808 139.548 83.712 140.252 83.712C140.956 83.712 141.54 83.728 142.004 83.76V84.96C142.404 84.624 142.932 84.352 143.588 84.144C144.26 83.92 144.9 83.808 145.508 83.808C147.076 83.808 148.172 84.176 148.796 84.912C149.436 85.648 149.756 86.92 149.756 88.728V93.336C150.38 93.576 150.82 93.848 151.076 94.152L150.836 96H145.316L145.076 94.152C145.3 93.848 145.74 93.576 146.396 93.336V88.584C146.396 87.72 146.252 87.144 145.964 86.856C145.692 86.552 145.196 86.4 144.476 86.4C143.756 86.4 143.036 86.656 142.316 87.168V93.336C142.94 93.576 143.38 93.848 143.636 94.152L143.396 96H137.876L137.636 94.152C137.86 93.848 138.3 93.576 138.956 93.336V86.664C138.396 86.472 137.956 86.2 137.636 85.848L137.876 84ZM156.709 85.968C155.653 85.968 155.125 86.28 155.125 86.904C155.125 87.496 155.677 87.936 156.781 88.224L158.677 88.728C160.629 89.24 161.605 90.368 161.605 92.112C161.605 93.312 161.181 94.296 160.333 95.064C159.501 95.816 158.165 96.192 156.325 96.192C154.501 96.192 153.077 95.936 152.053 95.424C152.037 95.248 152.029 95.072 152.029 94.896C152.029 94.016 152.205 93.224 152.557 92.52H154.549C154.757 92.904 154.893 93.304 154.957 93.72C155.277 93.816 155.733 93.864 156.325 93.864C157.733 93.864 158.437 93.464 158.437 92.664C158.437 92.408 158.341 92.2 158.149 92.04C157.957 91.864 157.581 91.696 157.021 91.536L155.125 90.984C154.149 90.712 153.389 90.312 152.845 89.784C152.301 89.24 152.029 88.448 152.029 87.408C152.029 86.352 152.453 85.488 153.301 84.816C154.149 84.144 155.357 83.808 156.925 83.808C158.509 83.808 159.845 84.04 160.933 84.504C160.949 84.664 160.957 84.824 160.957 84.984C160.957 85.816 160.781 86.584 160.429 87.288H158.461C158.253 86.92 158.117 86.536 158.053 86.136C157.605 86.024 157.157 85.968 156.709 85.968ZM171.593 94.992C170.489 95.792 169.185 96.192 167.681 96.192C166.193 96.192 165.153 95.88 164.561 95.256C163.969 94.632 163.673 93.616 163.673 92.208V86.664C163.113 86.472 162.673 86.2 162.353 85.848L162.593 84C163.489 83.792 164.321 83.688 165.089 83.688C165.857 83.688 166.505 83.712 167.033 83.76V91.416C167.033 92.28 167.161 92.856 167.417 93.144C167.689 93.416 168.217 93.552 169.001 93.552C169.785 93.552 170.513 93.296 171.185 92.784V86.664C170.625 86.472 170.185 86.2 169.865 85.848L170.105 84C171.001 83.792 171.833 83.688 172.601 83.688C173.369 83.688 174.017 83.712 174.545 83.76V93.12C175.105 93.232 175.545 93.368 175.865 93.528V95.424C174.905 95.936 173.697 96.192 172.241 96.192C171.841 95.904 171.625 95.504 171.593 94.992ZM176.799 78.96C177.695 78.752 178.527 78.648 179.295 78.648C180.063 78.648 180.711 78.672 181.239 78.72V93.336C181.863 93.576 182.303 93.848 182.559 94.152L182.319 96H176.799L176.559 94.152C176.783 93.848 177.223 93.576 177.879 93.336V81.624C177.319 81.432 176.879 81.16 176.559 80.808L176.799 78.96ZM187.918 80.976V84H191.35V86.016H187.918V92.088C187.918 92.6 187.99 92.976 188.134 93.216C188.278 93.44 188.622 93.552 189.166 93.552C189.71 93.552 190.294 93.432 190.918 93.192L191.638 95.064C190.406 95.688 189.142 96 187.846 96C186.566 96 185.694 95.728 185.23 95.184C184.782 94.624 184.558 93.816 184.558 92.76V86.016H183.478L183.214 84.552C183.47 84.248 183.998 83.944 184.798 83.64C184.99 82.328 185.446 81.44 186.166 80.976H187.918ZM192.767 84C193.663 83.792 194.495 83.688 195.263 83.688C196.031 83.688 196.679 83.712 197.207 83.76V93.336C197.831 93.576 198.271 93.848 198.527 94.152L198.287 96H192.767L192.527 94.152C192.751 93.848 193.191 93.576 193.847 93.336V86.664C193.287 86.472 192.847 86.2 192.527 85.848L192.767 84ZM195.479 82.344C194.151 82.344 193.487 81.744 193.487 80.544C193.487 79.328 194.151 78.72 195.479 78.72C196.823 78.72 197.495 79.328 197.495 80.544C197.495 81.744 196.823 82.344 195.479 82.344ZM199.727 84C200.607 83.808 201.399 83.712 202.103 83.712C202.807 83.712 203.391 83.728 203.855 83.76V84.96C204.255 84.624 204.783 84.352 205.439 84.144C206.111 83.92 206.751 83.808 207.359 83.808C208.927 83.808 210.023 84.176 210.647 84.912C211.287 85.648 211.607 86.92 211.607 88.728V93.336C212.231 93.576 212.671 93.848 212.927 94.152L212.687 96H207.167L206.927 94.152C207.151 93.848 207.591 93.576 208.247 93.336V88.584C208.247 87.72 208.103 87.144 207.815 86.856C207.543 86.552 207.047 86.4 206.327 86.4C205.607 86.4 204.887 86.656 204.167 87.168V93.336C204.791 93.576 205.231 93.848 205.487 94.152L205.247 96H199.727L199.487 94.152C199.711 93.848 200.151 93.576 200.807 93.336V86.664C200.247 86.472 199.807 86.2 199.487 85.848L199.727 84ZM219.281 98.544C220.705 98.544 221.417 97.688 221.417 95.976V94.92C220.633 95.4 219.649 95.64 218.465 95.64C216.961 95.64 215.801 95.2 214.985 94.32C214.185 93.44 213.785 91.976 213.785 89.928C213.785 85.848 215.657 83.808 219.401 83.808C220.361 83.808 221.257 84.016 222.089 84.432C222.249 84.144 222.489 84 222.809 84H224.777V95.808C224.777 97.568 224.337 98.872 223.457 99.72C222.593 100.568 221.249 100.992 219.425 100.992C218.465 100.992 217.473 100.88 216.449 100.656C215.425 100.432 214.649 100.152 214.121 99.816C214.105 99.672 214.097 99.528 214.097 99.384C214.097 98.504 214.305 97.656 214.721 96.84H216.833C217.009 97.176 217.137 97.624 217.217 98.184C217.825 98.424 218.513 98.544 219.281 98.544ZM217.097 89.784C217.097 90.984 217.257 91.824 217.577 92.304C217.913 92.784 218.473 93.024 219.257 93.024C220.057 93.024 220.777 92.8 221.417 92.352V86.664C220.777 86.392 220.081 86.256 219.329 86.256C217.841 86.256 217.097 87.432 217.097 89.784Z" fill="white"/>
++</svg>
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 402 58"><g fill="#231F20"><path d="M24.6 23c.4 0 .7-.1 1-.2l10-5.4c1-.5 1.3-1.8.8-2.8-.5-1-1.8-1.3-2.8-.8l-9.9 5.4c-1 .3-1.5 1.3-1.3 2.3.3 1 1.3 1.7 2.3 1.5h-.1zM39.8 30.9c.3 0 .7-.1 1-.3L56.7 22c.6-.3 1-1 1-1.7 0-.8-.3-1.5-.9-1.8-.7-.4-1.4-.4-2.1-.1L38.8 27c-.9.4-1.5 1.4-1.2 2.4.2 1 1.2 1.6 2.2 1.5z"/><path d="M81 19.6c-.4-1.2-1.3-2.2-2.4-2.7L61.4 7.7c-2.8-1.4-6.1-1.4-9 0l-1.4.7L39.1 2C36.3.6 33 .6 30.1 2L2.5 16.9c-1.4.6-2.3 1.9-2.5 3.4v15.2c0 .8.4 1.5 1.1 1.8l35 19c2.8 1.4 6.2 1.4 9 0L80 37.1c.7-.3 1.1-1 1.1-1.8v-15c0-.2-.1-.5-.1-.7zm-76.5.9L32 5.6c1.6-.7 3.5-.7 5.2 0L51 13l3.3-1.8c1.7-.7 3.6-.7 5.2 0l17.1 9.2.2.1-.2.1-33.4 18c-1.7.8-3.6.8-5.2 0l-33.5-18-.2-.1h.2zm38.6 32.2c-1.6.7-3.5.7-5.1 0L4.1 34.3v-9.2L36 42.3c2.8 1.4 6.2 1.4 9 0l32-17.2v9L43.1 52.7zM115.7 10.2h18.2c8.7 0 13.1 3.1 13.1 9.1 0 1.9-.5 3.7-1.6 5.2s-2.6 2.6-4.3 3.2c2.2.4 4.2 1.5 5.7 3.1s2.2 3.6 2.2 5.7c0 3.8-1.4 6.7-4.1 8.7-2.7 2-6.6 3-11.8 3h-17.5v-5.4l1.8-.2c.4 0 .8-.2 1.1-.5.2-.4.3-.9.3-1.3V16.1l-3.1-.3v-5.6zm13.1 6.4v9h2.7c3.5 0 5.3-1.6 5.3-4.8 0-2.8-1.7-4.2-5.1-4.2h-2.9zm0 15.1v9.9h3.7c3.8 0 5.8-1.8 5.8-5.2 0-3.1-1.9-4.7-5.7-4.7h-3.8zM180.7 19v22c0 .5 0 .9.3 1.3.2.3.6.4 1 .5l1.5.1v5.2h-11.7v-3.6h-.2c-1.7 3-4.5 4.4-8.5 4.4-3.1 0-5.3-.8-6.8-2.3-1.4-1.6-2.1-4-2.1-7.3V26.2c0-.4-.1-.8-.4-1.1-.2-.3-.6-.5-1-.5l-1.6-.2V19H164v18.4c-.1 1.1.1 2.2.6 3.1.6.8 1.6 1.1 2.5 1 1.1.1 2.2-.4 2.9-1.2.7-1 1.1-2.2 1-3.4V26.3c0-.5-.1-.9-.3-1.3-.3-.3-.7-.4-1.1-.4l-1.3-.2V19h12.4zM198.9 12.3V19h8.1c2.5-1.1 4.3-3.4 5.5-6.7h5.3V19h6.9l-.5 6.3h-6.4v12.3c-.1 1.1.2 2.2.7 3.2.4.5 1.3.8 2.7.8 1.2 0 2.5-.3 3.6-.8l1.4 6.3c-2.5 1.3-5.2 1.9-7.9 1.8-1.3 0-2.5-.1-3.8-.3-.9-.2-1.8-.4-2.7-.8-.7-.3-1.3-.8-1.8-1.4-.4-.5-.8-1-1.1-1.6-.3-.6-.5-1.3-.6-2-.1-.6-.2-1.3-.3-2V25.3h-9v12.3c-.1 1 .1 2.1.6 3.1.5.7 1.4 1.1 2.3 1 1.1 0 2.2-.3 3.2-.8l1.7 6.2c-2.3 1.2-4.9 1.9-7.5 1.8-3.7 0-6.4-.9-7.9-2.6-1.5-1.7-2.3-4.2-2.3-7.6V25.3h-3.9l.8-5.5c3.6-.8 6.2-3.3 7.6-7.4l5.3-.1zM242.7 18.2c2.7-.1 5.3.6 7.5 2.2 2 1.6 3 4.1 2.8 6.6 0 6.9-5.3 10.2-16 10 .1 1.3.7 2.6 1.7 3.5 1.2 1 2.7 1.4 4.2 1.4 2.6-.1 5.2-.9 7.4-2.3l2.6 6.3c-.5.4-1 .7-1.6.9-1.3.6-2.6 1-4 1.4-1.9.5-3.8.7-5.7.7-4.9 0-8.5-1.3-10.8-4-2.3-2.6-3.5-6.2-3.5-10.7-.1-4.1 1.3-8.2 4-11.4 2.7-3 6.5-4.6 11.4-4.6zm2 9.3c0-.7-.2-1.4-.7-1.9-.5-.5-1.2-.7-1.9-.6-1.4 0-2.8.6-3.6 1.8-1 1.3-1.6 2.9-1.6 4.6 5.2.2 7.7-1.2 7.7-3.9h.1zM272.5 25.5c-1.1 0-2.1.5-2.7 1.3-.7.9-1.1 2.1-1 3.3v12.5l5.1.3v5.3h-18.1V43l1.9-.2c.4.1.8-.1 1.1-.4.2-.4.3-.9.3-1.4V26.2c0-.4-.1-.8-.3-1.2-.3-.3-.6-.4-1-.4l-2-.2V19H268v4.4h.1c.7-1.4 1.7-2.7 3-3.6 1.6-1.1 3.5-1.7 5.4-1.6 1.9-.1 3.7.2 5.4.9v11.3l-7.6.4v-3.9c0-.7-.2-1.1-.5-1.2-.4-.1-.9-.2-1.3-.2zM308.7 17.5c-1.2-.3-2.3-.4-3.4-.4-6.1 0-9.2 3.9-9.2 11.8 0 3.8.8 6.8 2.3 9 1.5 2.2 3.9 3.3 7.1 3.4 1.1 0 2.1-.1 3.2-.4.6-.2 1-.8 1-1.5v-3.7l7.3.4v10.5c-3.8 1.7-7.9 2.5-12.1 2.3-6.1 0-10.8-1.6-14.1-4.9-3.3-3.3-5-8.1-5-14.5 0-3.2.5-6.4 1.6-9.4.9-2.5 2.4-4.6 4.4-6.3 1.8-1.4 3.8-2.5 6-3.3 2.2-.7 4.6-1 6.9-1 4.2-.1 8.3.7 12.2 2.4v10l-7.4.4V19c0-.9-.3-1.4-.8-1.5zM323.6 10.2h14.6l7.5 24.8h.2l7.7-24.7h14.6v5.4l-1.8.2c-.5 0-.9.2-1.2.5-.3.4-.4.9-.3 1.3l1.9 24.8 2.9.1v5.6h-15.3v-5.5l1.8-.2c.4.1.8-.1 1-.4.2-.4.3-.9.2-1.3l-.9-16.1h-.1l-7.2 23.5h-7.1l-7-23.1h-.2l-1 17.3 2.8.2v5.6h-15.3v-5.5l1.8-.2c.5 0 .9-.2 1.2-.5.2-.4.4-.9.4-1.4l2-24.6-3.2-.2v-5.6zM385.5 41.6c3.5 0 5.3-1.4 5.3-4.2 0-1.1-.5-2.2-1.4-2.8-1.4-.8-2.9-1.4-4.5-1.8-1.3-.3-2.7-.8-4-1.3-1.2-.5-2.3-1.2-3.4-1.9-1.2-.9-2.2-2-2.8-3.3-.6-1.5-1-3.2-1-4.8-.1-3.4 1.4-6.7 4-8.8 2.7-2.1 6.2-3.1 10.6-3.1 4-.2 8 .6 11.7 2.2v9.3l-7.4.5v-2.9c0-.8-.3-1.3-.8-1.4-1.1-.3-2.2-.4-3.3-.4-1.1 0-2.2.3-3.1.8-.8.6-1.3 1.6-1.2 2.6-.1 1.1.5 2.2 1.4 2.8 1.5.9 3.1 1.6 4.8 2 1.4.4 2.5.8 3.3 1.1.9.4 1.9.8 2.8 1.3 1 .5 1.9 1.2 2.6 2 .7.9 1.2 1.8 1.6 2.9.5 1.3.7 2.6.7 4 .2 3.6-1.3 7-4.1 9.3-2.7 2.2-6.4 3.3-11.2 3.3-4.3.1-8.6-.7-12.6-2.3v-9.8l7.5-.5v3.2c0 .9.3 1.4.9 1.6 1.1.2 2.3.4 3.6.4z"/></g></svg>
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 402 58"><g fill="#fff"><path d="M24.6 23c.4 0 .7-.1 1-.2l10-5.4c1-.5 1.3-1.8.8-2.8-.5-1-1.8-1.3-2.8-.8l-9.9 5.4c-1 .3-1.5 1.3-1.3 2.3.3 1 1.3 1.7 2.3 1.5h-.1zM39.8 30.9c.3 0 .7-.1 1-.3L56.7 22c.6-.3 1-1 1-1.7 0-.8-.3-1.5-.9-1.8-.7-.4-1.4-.4-2.1-.1L38.8 27c-.9.4-1.5 1.4-1.2 2.4.2 1 1.2 1.6 2.2 1.5z"/><path d="M81 19.6c-.4-1.2-1.3-2.2-2.4-2.7L61.4 7.7c-2.8-1.4-6.1-1.4-9 0l-1.4.7L39.1 2C36.3.6 33 .6 30.1 2L2.5 16.9c-1.4.6-2.3 1.9-2.5 3.4v15.2c0 .8.4 1.5 1.1 1.8l35 19c2.8 1.4 6.2 1.4 9 0L80 37.1c.7-.3 1.1-1 1.1-1.8v-15c0-.2-.1-.5-.1-.7zm-76.5.9L32 5.6c1.6-.7 3.5-.7 5.2 0L51 13l3.3-1.8c1.7-.7 3.6-.7 5.2 0l17.1 9.2.2.1-.2.1-33.4 18c-1.7.8-3.6.8-5.2 0l-33.5-18-.2-.1h.2zm38.6 32.2c-1.6.7-3.5.7-5.1 0L4.1 34.3v-9.2L36 42.3c2.8 1.4 6.2 1.4 9 0l32-17.2v9L43.1 52.7zM115.7 10.2h18.2c8.7 0 13.1 3.1 13.1 9.1 0 1.9-.5 3.7-1.6 5.2s-2.6 2.6-4.3 3.2c2.2.4 4.2 1.5 5.7 3.1s2.2 3.6 2.2 5.7c0 3.8-1.4 6.7-4.1 8.7-2.7 2-6.6 3-11.8 3h-17.5v-5.4l1.8-.2c.4 0 .8-.2 1.1-.5.2-.4.3-.9.3-1.3V16.1l-3.1-.3v-5.6zm13.1 6.4v9h2.7c3.5 0 5.3-1.6 5.3-4.8 0-2.8-1.7-4.2-5.1-4.2h-2.9zm0 15.1v9.9h3.7c3.8 0 5.8-1.8 5.8-5.2 0-3.1-1.9-4.7-5.7-4.7h-3.8zM180.7 19v22c0 .5 0 .9.3 1.3.2.3.6.4 1 .5l1.5.1v5.2h-11.7v-3.6h-.2c-1.7 3-4.5 4.4-8.5 4.4-3.1 0-5.3-.8-6.8-2.3-1.4-1.6-2.1-4-2.1-7.3V26.2c0-.4-.1-.8-.4-1.1-.2-.3-.6-.5-1-.5l-1.6-.2V19H164v18.4c-.1 1.1.1 2.2.6 3.1.6.8 1.6 1.1 2.5 1 1.1.1 2.2-.4 2.9-1.2.7-1 1.1-2.2 1-3.4V26.3c0-.5-.1-.9-.3-1.3-.3-.3-.7-.4-1.1-.4l-1.3-.2V19h12.4zM198.9 12.3V19h8.1c2.5-1.1 4.3-3.4 5.5-6.7h5.3V19h6.9l-.5 6.3h-6.4v12.3c-.1 1.1.2 2.2.7 3.2.4.5 1.3.8 2.7.8 1.2 0 2.5-.3 3.6-.8l1.4 6.3c-2.5 1.3-5.2 1.9-7.9 1.8-1.3 0-2.5-.1-3.8-.3-.9-.2-1.8-.4-2.7-.8-.7-.3-1.3-.8-1.8-1.4-.4-.5-.8-1-1.1-1.6-.3-.6-.5-1.3-.6-2-.1-.6-.2-1.3-.3-2V25.3h-9v12.3c-.1 1 .1 2.1.6 3.1.5.7 1.4 1.1 2.3 1 1.1 0 2.2-.3 3.2-.8l1.7 6.2c-2.3 1.2-4.9 1.9-7.5 1.8-3.7 0-6.4-.9-7.9-2.6-1.5-1.7-2.3-4.2-2.3-7.6V25.3h-3.9l.8-5.5c3.6-.8 6.2-3.3 7.6-7.4l5.3-.1zM242.7 18.2c2.7-.1 5.3.6 7.5 2.2 2 1.6 3 4.1 2.8 6.6 0 6.9-5.3 10.2-16 10 .1 1.3.7 2.6 1.7 3.5 1.2 1 2.7 1.4 4.2 1.4 2.6-.1 5.2-.9 7.4-2.3l2.6 6.3c-.5.4-1 .7-1.6.9-1.3.6-2.6 1-4 1.4-1.9.5-3.8.7-5.7.7-4.9 0-8.5-1.3-10.8-4-2.3-2.6-3.5-6.2-3.5-10.7-.1-4.1 1.3-8.2 4-11.4 2.7-3 6.5-4.6 11.4-4.6zm2 9.3c0-.7-.2-1.4-.7-1.9-.5-.5-1.2-.7-1.9-.6-1.4 0-2.8.6-3.6 1.8-1 1.3-1.6 2.9-1.6 4.6 5.2.2 7.7-1.2 7.7-3.9h.1zM272.5 25.5c-1.1 0-2.1.5-2.7 1.3-.7.9-1.1 2.1-1 3.3v12.5l5.1.3v5.3h-18.1V43l1.9-.2c.4.1.8-.1 1.1-.4.2-.4.3-.9.3-1.4V26.2c0-.4-.1-.8-.3-1.2-.3-.3-.6-.4-1-.4l-2-.2V19H268v4.4h.1c.7-1.4 1.7-2.7 3-3.6 1.6-1.1 3.5-1.7 5.4-1.6 1.9-.1 3.7.2 5.4.9v11.3l-7.6.4v-3.9c0-.7-.2-1.1-.5-1.2-.4-.1-.9-.2-1.3-.2zM308.7 17.5c-1.2-.3-2.3-.4-3.4-.4-6.1 0-9.2 3.9-9.2 11.8 0 3.8.8 6.8 2.3 9 1.5 2.2 3.9 3.3 7.1 3.4 1.1 0 2.1-.1 3.2-.4.6-.2 1-.8 1-1.5v-3.7l7.3.4v10.5c-3.8 1.7-7.9 2.5-12.1 2.3-6.1 0-10.8-1.6-14.1-4.9-3.3-3.3-5-8.1-5-14.5 0-3.2.5-6.4 1.6-9.4.9-2.5 2.4-4.6 4.4-6.3 1.8-1.4 3.8-2.5 6-3.3 2.2-.7 4.6-1 6.9-1 4.2-.1 8.3.7 12.2 2.4v10l-7.4.4V19c0-.9-.3-1.4-.8-1.5zM323.6 10.2h14.6l7.5 24.8h.2l7.7-24.7h14.6v5.4l-1.8.2c-.5 0-.9.2-1.2.5-.3.4-.4.9-.3 1.3l1.9 24.8 2.9.1v5.6h-15.3v-5.5l1.8-.2c.4.1.8-.1 1-.4.2-.4.3-.9.2-1.3l-.9-16.1h-.1l-7.2 23.5h-7.1l-7-23.1h-.2l-1 17.3 2.8.2v5.6h-15.3v-5.5l1.8-.2c.5 0 .9-.2 1.2-.5.2-.4.4-.9.4-1.4l2-24.6-3.2-.2v-5.6zM385.5 41.6c3.5 0 5.3-1.4 5.3-4.2 0-1.1-.5-2.2-1.4-2.8-1.4-.8-2.9-1.4-4.5-1.8-1.3-.3-2.7-.8-4-1.3-1.2-.5-2.3-1.2-3.4-1.9-1.2-.9-2.2-2-2.8-3.3-.6-1.5-1-3.2-1-4.8-.1-3.4 1.4-6.7 4-8.8 2.7-2.1 6.2-3.1 10.6-3.1 4-.2 8 .6 11.7 2.2v9.3l-7.4.5v-2.9c0-.8-.3-1.3-.8-1.4-1.1-.3-2.2-.4-3.3-.4-1.1 0-2.2.3-3.1.8-.8.6-1.3 1.6-1.2 2.6-.1 1.1.5 2.2 1.4 2.8 1.5.9 3.1 1.6 4.8 2 1.4.4 2.5.8 3.3 1.1.9.4 1.9.8 2.8 1.3 1 .5 1.9 1.2 2.6 2 .7.9 1.2 1.8 1.6 2.9.5 1.3.7 2.6.7 4 .2 3.6-1.3 7-4.1 9.3-2.7 2.2-6.4 3.3-11.2 3.3-4.3.1-8.6-.7-12.6-2.3v-9.8l7.5-.5v3.2c0 .9.3 1.4.9 1.6 1.1.2 2.3.4 3.6.4z"/></g></svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 363 80" fill="none" xmlns="http://www.w3.org/2000/svg">
++<path fill-rule="evenodd" clip-rule="evenodd" d="M29.0705 42.8838C29.425 43.0864 29.8049 43.289 30.1847 43.4663C33.0209 44.783 34.3376 45.644 34.3376 47.4672C34.3376 49.4171 32.7423 51.0124 30.7925 51.0124C29.2731 51.0124 28.007 50.0502 27.5005 48.7081C25.6519 50.5819 23.1197 51.7468 20.2835 51.7468C14.6872 51.7468 10.1544 47.214 10.1544 41.6177C10.1544 41.0859 10.2304 40.5541 10.3064 40.0224C5.1152 38.503 1.1142 34.1728 0.202582 28.7537C0.0759682 27.9687 0 27.1837 0 26.3734C0 25.5631 0.0759682 24.7781 0.202582 23.9931C1.13952 18.5993 5.1152 14.2438 10.3064 12.7244C10.3032 12.7022 10.3 12.6801 10.2968 12.658C10.2242 12.1503 10.1544 11.6629 10.1544 11.1291C10.1544 5.53277 14.6872 1 20.2835 1C23.0943 1 25.6519 2.16485 27.5005 4.03873C28.007 2.69662 29.2731 1.73436 30.7925 1.73436C32.7423 1.73436 34.3376 3.32969 34.3376 5.27954C34.3376 7.25472 33.0209 8.11569 30.1847 9.43248C29.9037 9.5636 29.6366 9.70858 29.3628 9.85717C29.2665 9.90945 29.1694 9.96218 29.0705 10.0149H29.0704C28.8426 10.1415 28.6147 10.2681 28.4121 10.3947C28.2349 10.496 28.0829 10.5973 27.931 10.6986C27.8803 10.7239 27.836 10.7556 27.7917 10.7872C27.7474 10.8189 27.7031 10.8505 27.6524 10.8759C26.7915 11.433 26.0065 12.0914 25.2468 12.7751C25.2215 12.7877 25.2025 12.8067 25.1835 12.8257C25.1645 12.8447 25.1455 12.8637 25.1202 12.8764C24.8163 13.1802 24.5124 13.4841 24.2339 13.788C24.1959 13.826 24.1579 13.8703 24.1199 13.9146C24.0819 13.9589 24.0439 14.0032 24.006 14.0412C23.8864 14.1907 23.7629 14.3363 23.6401 14.481C23.4508 14.704 23.2633 14.9251 23.0943 15.1554C20.7393 18.2954 19.2959 22.2205 19.2959 26.4494C19.2959 30.6783 20.714 34.6033 23.0943 37.7433C23.3729 38.1231 23.6768 38.503 24.006 38.8575C24.0439 38.8955 24.0819 38.9398 24.1199 38.9841C24.1579 39.0284 24.1959 39.0728 24.2339 39.1107C24.4424 39.3572 24.6652 39.5753 24.8915 39.7969C24.9674 39.8712 25.0438 39.946 25.1202 40.0224C25.1455 40.035 25.1645 40.054 25.1835 40.073C25.2025 40.092 25.2215 40.111 25.2468 40.1236C26.0065 40.8074 26.7915 41.4658 27.6524 42.0229C27.7031 42.0482 27.7474 42.0798 27.7917 42.1115C27.836 42.1431 27.8803 42.1748 27.931 42.2001C28.007 42.2508 28.0893 42.3014 28.1716 42.3521C28.2539 42.4027 28.3362 42.4533 28.4121 42.504C28.5261 42.5673 28.6337 42.6306 28.7414 42.6939C28.849 42.7572 28.9566 42.8205 29.0705 42.8838ZM64.2693 12.826C69.4604 14.3453 73.4614 18.6755 74.3731 24.0946C74.4997 24.8543 74.5756 25.6646 74.5756 26.6269C74.5756 27.4372 74.4997 28.2222 74.3731 29.0072C73.4361 34.4009 69.4604 38.7565 64.2693 40.2758L64.2788 40.3423C64.3515 40.85 64.4212 41.3373 64.4212 41.8712C64.4212 47.4675 59.8884 52.0003 54.2921 52.0003C51.4813 52.0003 48.9237 50.8354 47.0751 48.9615C46.5687 50.3036 45.3025 51.2659 43.7832 51.2659C41.8333 51.2659 40.238 49.6706 40.238 47.7207C40.238 45.7455 41.5548 44.8846 44.3909 43.5678C44.6719 43.4367 44.939 43.2917 45.2128 43.1431C45.3091 43.0908 45.4063 43.0381 45.5051 42.9854C45.733 42.8587 45.9609 42.7321 46.1635 42.6055C46.3407 42.5042 46.4926 42.403 46.6445 42.3017L46.6446 42.3016C46.6953 42.2763 46.7396 42.2447 46.7839 42.213C46.8282 42.1814 46.8725 42.1497 46.9232 42.1244C47.7842 41.5673 48.5692 40.9089 49.3289 40.2252C49.3542 40.2125 49.3732 40.1935 49.3922 40.1745C49.4112 40.1555 49.4301 40.1365 49.4555 40.1239C49.7593 39.82 50.0632 39.5161 50.3418 39.2123C50.3797 39.1743 50.4177 39.13 50.4557 39.0856C50.4937 39.0413 50.5317 38.997 50.5697 38.959C50.6893 38.8096 50.8128 38.664 50.9356 38.5193C51.1248 38.2962 51.3124 38.0752 51.4813 37.8448C53.8363 34.7048 55.2797 30.7798 55.2797 26.5509C55.2797 22.322 53.8616 18.397 51.4813 15.257C51.2027 14.8771 50.8989 14.4973 50.5697 14.1428C50.5317 14.1048 50.4937 14.0605 50.4557 14.0161C50.4177 13.9718 50.3797 13.9275 50.3418 13.8895C50.0632 13.5603 49.7593 13.2565 49.4555 12.9779C49.4301 12.9652 49.4112 12.9463 49.3922 12.9273C49.3732 12.9083 49.3542 12.8893 49.3289 12.8766C48.5692 12.1929 47.7842 11.5598 46.9232 10.9774C46.8726 10.9521 46.8282 10.9204 46.7839 10.8888C46.7396 10.8571 46.6953 10.8255 46.6446 10.8001C46.5687 10.7495 46.4864 10.6988 46.4041 10.6482C46.3218 10.5976 46.2395 10.5469 46.1635 10.4963C46.0496 10.433 45.9419 10.3697 45.8343 10.3064C45.7267 10.243 45.6191 10.1797 45.5051 10.1164C45.1506 9.91385 44.7708 9.71127 44.3909 9.53401C41.5801 8.19191 40.238 7.33093 40.238 5.38108C40.238 3.43123 41.8333 1.8359 43.7832 1.8359C45.3025 1.8359 46.5687 2.79816 47.0751 4.14027C48.9237 2.26638 51.456 1.10154 54.2921 1.10154C59.8884 1.10154 64.4212 5.63431 64.4212 11.2306C64.4212 11.7624 64.3452 12.2942 64.2693 12.826Z" fill="#034AD8"/>
++<path d="M48.3405 26.475C48.3405 20.3723 43.4025 15.4343 37.2998 15.4343C31.197 15.4343 26.259 20.3723 26.259 26.475C26.259 32.5778 31.197 37.5158 37.2998 37.5158C43.4025 37.5158 48.3405 32.5778 48.3405 26.475Z" fill="#034AD8"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M119.934 36.2635V0.832581H113.425V36.2635H119.934ZM98.4922 36.9973C101.494 36.9973 103.973 36.198 105.931 34.5994C107.888 33.0007 109.161 31.0922 109.748 28.8736L104.022 26.9651C103.696 28.0743 103.076 29.0286 102.162 29.8279C101.249 30.6272 100.026 31.0269 98.4922 31.0269C96.763 31.0269 95.303 30.4152 94.1122 29.1917C92.9214 27.9683 92.326 26.3126 92.326 24.2246C92.326 22.1366 92.9133 20.489 94.0878 19.2819C95.2623 18.0747 96.7141 17.4712 98.4432 17.4712C101.216 17.4712 102.994 18.8251 103.777 21.533L109.601 19.5755C109.046 17.3243 107.79 15.4076 105.833 13.8253C103.875 12.243 101.363 11.4518 98.2964 11.4518C94.7729 11.4518 91.8122 12.6589 89.4142 15.0732C87.0163 17.4875 85.8173 20.5379 85.8173 24.2246C85.8173 27.8786 87.0326 30.9209 89.4631 33.3514C91.8937 35.782 94.9034 36.9973 98.4922 36.9973ZM145.097 33.3759C142.699 35.7902 139.689 36.9973 136.068 36.9973C132.446 36.9973 129.437 35.7902 127.039 33.3759C124.641 30.9617 123.442 27.9112 123.442 24.2246C123.442 20.5379 124.633 17.4875 127.014 15.0732C129.429 12.6589 132.446 11.4518 136.068 11.4518C139.689 11.4518 142.699 12.6589 145.097 15.0732C147.495 17.4875 148.694 20.5379 148.694 24.2246C148.694 27.9112 147.495 30.9617 145.097 33.3759ZM136.069 31.0758C134.373 31.0758 132.921 30.4722 131.714 29.2651C130.539 28.058 129.952 26.3778 129.952 24.2245C129.952 22.0713 130.547 20.3911 131.738 19.1839C132.929 17.9768 134.373 17.3732 136.069 17.3732C137.766 17.3732 139.209 17.9768 140.4 19.1839C141.591 20.3911 142.186 22.0713 142.186 24.2245C142.186 26.3778 141.591 28.058 140.4 29.2651C139.209 30.4722 137.766 31.0758 136.069 31.0758ZM164.901 36.0919C163.677 36.6302 162.381 36.8994 161.01 36.8994C158.172 36.8994 155.937 35.9941 154.306 34.1834C152.675 32.3727 151.859 30.1134 151.859 27.4055V12.1859H158.368V26.0842C158.368 27.5197 158.743 28.686 159.493 29.5832C160.244 30.4804 161.337 30.929 162.772 30.929C164.175 30.929 165.284 30.4967 166.1 29.6321C166.915 28.7676 167.323 27.6175 167.323 26.182V12.1859H173.832V31.9078C173.832 33.4411 173.914 34.893 174.077 36.2632H167.862C167.731 35.6107 167.666 34.7461 167.666 33.6695C167.046 34.7461 166.124 35.5536 164.901 36.0919ZM189.5 36.8507C191.066 36.8507 192.444 36.5408 193.635 35.9209C194.826 35.301 195.698 34.4854 196.253 33.474C196.253 34.518 196.335 35.4479 196.498 36.2635H202.713C202.582 34.9585 202.517 33.5067 202.517 31.908V0.832581H196.106V14.5841C195.03 12.5939 192.762 11.5989 189.304 11.5989C185.943 11.5989 183.178 12.806 181.009 15.2203C178.839 17.6345 177.755 20.6197 177.755 24.1759C177.755 27.8299 178.856 30.8559 181.058 33.2538C183.26 35.6518 186.074 36.8507 189.5 36.8507ZM185.977 29.1919C187.086 30.4154 188.522 31.0271 190.283 31.0271C192.013 31.0271 193.432 30.4072 194.541 29.1674C195.65 27.9277 196.205 26.2475 196.205 24.1269C196.205 22.0388 195.65 20.3994 194.541 19.2086C193.432 18.0178 192.013 17.4224 190.283 17.4224C188.554 17.4224 187.127 18.026 186.001 19.2331C184.876 20.4402 184.313 22.0878 184.313 24.1758C184.313 26.2964 184.868 27.9685 185.977 29.1919ZM218.798 36.9973C221.8 36.9973 224.279 36.198 226.237 34.5994C228.194 33.0007 229.466 31.0922 230.054 28.8736L224.328 26.9651C224.002 28.0743 223.382 29.0286 222.468 29.8279C221.555 30.6272 220.331 31.0269 218.798 31.0269C217.069 31.0269 215.609 30.4152 214.418 29.1917C213.227 27.9683 212.632 26.3126 212.632 24.2246C212.632 22.1366 213.219 20.489 214.394 19.2819C215.568 18.0747 217.02 17.4712 218.749 17.4712C221.522 17.4712 223.3 18.8251 224.083 21.533L229.907 19.5755C229.352 17.3243 228.096 15.4076 226.139 13.8253C224.181 12.243 221.669 11.4518 218.602 11.4518C215.079 11.4518 212.118 12.6589 209.72 15.0732C207.322 17.4875 206.123 20.5379 206.123 24.2246C206.123 27.8786 207.338 30.9209 209.769 33.3514C212.2 35.782 215.209 36.9973 218.798 36.9973ZM248.562 33.3759C247.028 35.7575 244.663 36.9483 241.466 36.9483C238.986 36.9483 236.988 36.2306 235.471 34.7951C233.954 33.3595 233.195 31.663 233.195 29.7055C233.195 27.6501 233.864 26.0026 235.202 24.7628C236.539 23.5231 238.268 22.7401 240.389 22.4138L246.311 21.5329C247.518 21.3698 248.121 20.7989 248.121 19.8201C248.121 18.9066 247.77 18.1562 247.069 17.569C246.368 16.9817 245.364 16.6881 244.059 16.6881C242.689 16.6881 241.604 17.0633 240.805 17.8137C240.006 18.564 239.557 19.4939 239.459 20.6031L233.685 19.3797C233.913 17.2917 234.941 15.4483 236.768 13.8497C238.595 12.2511 241.009 11.4518 244.01 11.4518C247.599 11.4518 250.242 12.3082 251.938 14.021C253.635 15.7338 254.483 17.9279 254.483 20.6031V32.446C254.483 33.8815 254.581 35.1539 254.777 36.2632H248.806C248.643 35.5454 248.562 34.583 248.562 33.3759ZM242.836 32.1037C241.857 32.1037 241.09 31.8346 240.536 31.2963C239.981 30.7579 239.704 30.0973 239.704 29.3143C239.704 27.5851 240.699 26.5738 242.689 26.2801L248.121 25.4482V26.5248C248.121 28.515 247.624 29.9423 246.629 30.8069C245.633 31.6714 244.369 32.1037 242.836 32.1037ZM265.918 22.4142V36.2636H259.41V12.1863H265.723V15.1715C266.408 13.9969 267.386 13.0998 268.659 12.4799C269.931 11.86 271.269 11.5501 272.672 11.5501C275.51 11.5501 277.672 12.4391 279.156 14.2172C280.64 15.9952 281.383 18.2872 281.383 21.0929V36.2636H274.874V22.2185C274.874 20.783 274.507 19.6248 273.773 18.7439C273.039 17.863 271.921 17.4226 270.421 17.4226C269.05 17.4226 267.957 17.8957 267.142 18.8418C266.326 19.7879 265.918 20.9787 265.918 22.4142ZM292.866 36.2636V22.4142C292.866 20.9787 293.274 19.7879 294.09 18.8418C294.905 17.8957 295.998 17.4226 297.368 17.4226C298.869 17.4226 299.987 17.863 300.721 18.7439C301.455 19.6248 301.822 20.783 301.822 22.2185V36.2636H308.33V21.0929C308.33 18.2872 307.588 15.9952 306.104 14.2172C304.619 12.4391 302.458 11.5501 299.619 11.5501C298.217 11.5501 296.879 11.86 295.607 12.4799C294.334 13.0998 293.355 13.9969 292.67 15.1715V12.1863H286.357V36.2636H292.866ZM333.149 33.3759C330.751 35.7901 327.742 36.9972 324.12 36.9972C320.499 36.9972 317.489 35.7901 315.091 33.3759C312.693 30.9616 311.494 27.9111 311.494 24.2245C311.494 20.5379 312.685 17.4874 315.067 15.0731C317.481 12.6589 320.499 11.4518 324.12 11.4518C327.742 11.4518 330.751 12.6589 333.149 15.0731C335.547 17.4874 336.746 20.5379 336.746 24.2245C336.746 27.9111 335.547 30.9616 333.149 33.3759ZM324.121 31.0757C322.425 31.0757 320.973 30.4722 319.766 29.265C318.591 28.0579 318.004 26.3777 318.004 24.2245C318.004 22.0712 318.6 20.391 319.79 19.1839C320.981 17.9767 322.425 17.3732 324.121 17.3732C325.818 17.3732 327.262 17.9767 328.452 19.1839C329.643 20.391 330.239 22.0712 330.239 24.2245C330.239 26.3777 329.643 28.0579 328.452 29.265C327.262 30.4722 325.818 31.0757 324.121 31.0757ZM346.762 22.4142V36.2636H340.254V12.1863H346.567V15.1715C347.252 13.9969 348.23 13.0998 349.503 12.4799C350.775 11.86 352.113 11.5501 353.516 11.5501C356.354 11.5501 358.515 12.4391 360 14.2172C361.484 15.9952 362.227 18.2872 362.227 21.0929V36.2636H355.718V22.2185C355.718 20.783 355.351 19.6248 354.617 18.7439C353.883 17.863 352.765 17.4226 351.265 17.4226C349.894 17.4226 348.801 17.8957 347.986 18.8418C347.17 19.7879 346.762 20.9787 346.762 22.4142Z" fill="#034AD8"/>
++<path d="M313.211 64.2638C318.224 64.2638 320.862 60.5706 320.862 60.5706L319.015 58.724C319.015 58.724 317.037 61.6258 313.211 61.6258C309.386 61.6258 306.353 58.5921 306.353 54.767C306.353 50.9419 309.386 47.9082 313.211 47.9082C317.037 47.9082 318.883 50.6781 318.883 50.6781L320.73 48.8315C320.73 48.8315 318.224 45.2702 313.211 45.2702C307.672 45.2702 303.451 49.491 303.451 54.767C303.451 60.043 307.672 64.2638 313.211 64.2638ZM324.294 64H327.196V50.4143L333.923 58.9878L340.65 50.4143V64H343.552V45.534H340.914L333.923 54.5032L326.932 45.534H324.294V64ZM353.568 64.2638C357.657 64.2638 360.163 61.7577 360.163 58.8559C360.163 51.9971 350.402 54.5032 350.402 50.4143C350.402 49.0953 351.589 47.9082 353.832 47.9082C356.338 47.9082 357.657 49.6229 357.657 49.6229L359.635 47.6444C359.635 47.6444 357.657 45.2702 353.832 45.2702C349.875 45.2702 347.5 47.6444 347.5 50.4143C347.5 57.2731 357.261 54.767 357.261 58.8559C357.261 60.3068 355.942 61.6258 353.568 61.6258C350.402 61.6258 348.951 59.5154 348.951 59.5154L346.973 61.4939C346.973 61.4939 349.083 64.2638 353.568 64.2638Z" fill="#034AD8"/>
++</svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 363 80" fill="none" xmlns="http://www.w3.org/2000/svg">
++<path fill-rule="evenodd" clip-rule="evenodd" d="M29.0705 42.8838C29.425 43.0864 29.8049 43.289 30.1847 43.4663C33.0209 44.783 34.3376 45.644 34.3376 47.4672C34.3376 49.4171 32.7423 51.0124 30.7925 51.0124C29.2731 51.0124 28.007 50.0502 27.5005 48.7081C25.6519 50.5819 23.1197 51.7468 20.2835 51.7468C14.6872 51.7468 10.1544 47.214 10.1544 41.6177C10.1544 41.0859 10.2304 40.5541 10.3064 40.0224C5.1152 38.503 1.1142 34.1728 0.202582 28.7537C0.0759682 27.9687 0 27.1837 0 26.3734C0 25.5631 0.0759682 24.7781 0.202582 23.9931C1.13952 18.5993 5.1152 14.2438 10.3064 12.7244C10.3032 12.7022 10.3 12.6801 10.2968 12.658C10.2242 12.1503 10.1544 11.6629 10.1544 11.1291C10.1544 5.53277 14.6872 1 20.2835 1C23.0943 1 25.6519 2.16485 27.5005 4.03873C28.007 2.69662 29.2731 1.73436 30.7925 1.73436C32.7423 1.73436 34.3376 3.32969 34.3376 5.27954C34.3376 7.25472 33.0209 8.11569 30.1847 9.43248C29.9037 9.5636 29.6366 9.70858 29.3628 9.85717C29.2665 9.90945 29.1694 9.96218 29.0705 10.0149H29.0704C28.8426 10.1415 28.6147 10.2681 28.4121 10.3947C28.2349 10.496 28.0829 10.5973 27.931 10.6986C27.8803 10.7239 27.836 10.7556 27.7917 10.7872C27.7474 10.8189 27.7031 10.8505 27.6524 10.8759C26.7915 11.433 26.0065 12.0914 25.2468 12.7751C25.2215 12.7877 25.2025 12.8067 25.1835 12.8257C25.1645 12.8447 25.1455 12.8637 25.1202 12.8764C24.8163 13.1802 24.5124 13.4841 24.2339 13.788C24.1959 13.826 24.1579 13.8703 24.1199 13.9146C24.0819 13.9589 24.0439 14.0032 24.006 14.0412C23.8864 14.1907 23.7629 14.3363 23.6401 14.481C23.4508 14.704 23.2633 14.9251 23.0943 15.1554C20.7393 18.2954 19.2959 22.2205 19.2959 26.4494C19.2959 30.6783 20.714 34.6033 23.0943 37.7433C23.3729 38.1231 23.6768 38.503 24.006 38.8575C24.0439 38.8955 24.0819 38.9398 24.1199 38.9841C24.1579 39.0284 24.1959 39.0728 24.2339 39.1107C24.4424 39.3572 24.6652 39.5753 24.8915 39.7969C24.9674 39.8712 25.0438 39.946 25.1202 40.0224C25.1455 40.035 25.1645 40.054 25.1835 40.073C25.2025 40.092 25.2215 40.111 25.2468 40.1236C26.0065 40.8074 26.7915 41.4658 27.6524 42.0229C27.7031 42.0482 27.7474 42.0798 27.7917 42.1115C27.836 42.1431 27.8803 42.1748 27.931 42.2001C28.007 42.2508 28.0893 42.3014 28.1716 42.3521C28.2539 42.4027 28.3362 42.4533 28.4121 42.504C28.5261 42.5673 28.6337 42.6306 28.7414 42.6939C28.849 42.7572 28.9566 42.8205 29.0705 42.8838ZM64.2693 12.826C69.4604 14.3453 73.4614 18.6755 74.3731 24.0946C74.4997 24.8543 74.5756 25.6646 74.5756 26.6269C74.5756 27.4372 74.4997 28.2222 74.3731 29.0072C73.4361 34.4009 69.4604 38.7565 64.2693 40.2758L64.2788 40.3423C64.3515 40.85 64.4212 41.3373 64.4212 41.8712C64.4212 47.4675 59.8884 52.0003 54.2921 52.0003C51.4813 52.0003 48.9237 50.8354 47.0751 48.9615C46.5687 50.3036 45.3025 51.2659 43.7832 51.2659C41.8333 51.2659 40.238 49.6706 40.238 47.7207C40.238 45.7455 41.5548 44.8846 44.3909 43.5678C44.6719 43.4367 44.939 43.2917 45.2128 43.1431C45.3091 43.0908 45.4063 43.0381 45.5051 42.9854C45.733 42.8587 45.9609 42.7321 46.1635 42.6055C46.3407 42.5042 46.4926 42.403 46.6445 42.3017L46.6446 42.3016C46.6953 42.2763 46.7396 42.2447 46.7839 42.213C46.8282 42.1814 46.8725 42.1497 46.9232 42.1244C47.7842 41.5673 48.5692 40.9089 49.3289 40.2252C49.3542 40.2125 49.3732 40.1935 49.3922 40.1745C49.4112 40.1555 49.4301 40.1365 49.4555 40.1239C49.7593 39.82 50.0632 39.5161 50.3418 39.2123C50.3797 39.1743 50.4177 39.13 50.4557 39.0856C50.4937 39.0413 50.5317 38.997 50.5697 38.959C50.6893 38.8096 50.8128 38.664 50.9356 38.5193C51.1248 38.2962 51.3124 38.0752 51.4813 37.8448C53.8363 34.7048 55.2797 30.7798 55.2797 26.5509C55.2797 22.322 53.8616 18.397 51.4813 15.257C51.2027 14.8771 50.8989 14.4973 50.5697 14.1428C50.5317 14.1048 50.4937 14.0605 50.4557 14.0161C50.4177 13.9718 50.3797 13.9275 50.3418 13.8895C50.0632 13.5603 49.7593 13.2565 49.4555 12.9779C49.4301 12.9652 49.4112 12.9463 49.3922 12.9273C49.3732 12.9083 49.3542 12.8893 49.3289 12.8766C48.5692 12.1929 47.7842 11.5598 46.9232 10.9774C46.8726 10.9521 46.8282 10.9204 46.7839 10.8888C46.7396 10.8571 46.6953 10.8255 46.6446 10.8001C46.5687 10.7495 46.4864 10.6988 46.4041 10.6482C46.3218 10.5976 46.2395 10.5469 46.1635 10.4963C46.0496 10.433 45.9419 10.3697 45.8343 10.3064C45.7267 10.243 45.6191 10.1797 45.5051 10.1164C45.1506 9.91385 44.7708 9.71127 44.3909 9.53401C41.5801 8.19191 40.238 7.33093 40.238 5.38108C40.238 3.43123 41.8333 1.8359 43.7832 1.8359C45.3025 1.8359 46.5687 2.79816 47.0751 4.14027C48.9237 2.26638 51.456 1.10154 54.2921 1.10154C59.8884 1.10154 64.4212 5.63431 64.4212 11.2306C64.4212 11.7624 64.3452 12.2942 64.2693 12.826Z" fill="white"/>
++<path d="M48.3405 26.475C48.3405 20.3723 43.4025 15.4343 37.2998 15.4343C31.197 15.4343 26.259 20.3723 26.259 26.475C26.259 32.5778 31.197 37.5158 37.2998 37.5158C43.4025 37.5158 48.3405 32.5778 48.3405 26.475Z" fill="white"/>
++<path fill-rule="evenodd" clip-rule="evenodd" d="M119.934 36.2635V0.832581H113.425V36.2635H119.934ZM98.4922 36.9973C101.494 36.9973 103.973 36.198 105.931 34.5994C107.888 33.0007 109.161 31.0922 109.748 28.8736L104.022 26.9651C103.696 28.0743 103.076 29.0286 102.162 29.8279C101.249 30.6272 100.026 31.0269 98.4922 31.0269C96.763 31.0269 95.303 30.4152 94.1122 29.1917C92.9214 27.9683 92.326 26.3126 92.326 24.2246C92.326 22.1366 92.9133 20.489 94.0878 19.2819C95.2623 18.0747 96.7141 17.4712 98.4432 17.4712C101.216 17.4712 102.994 18.8251 103.777 21.533L109.601 19.5755C109.046 17.3243 107.79 15.4076 105.833 13.8253C103.875 12.243 101.363 11.4518 98.2964 11.4518C94.7729 11.4518 91.8122 12.6589 89.4142 15.0732C87.0163 17.4875 85.8173 20.5379 85.8173 24.2246C85.8173 27.8786 87.0326 30.9209 89.4631 33.3514C91.8937 35.782 94.9034 36.9973 98.4922 36.9973ZM145.097 33.3759C142.699 35.7902 139.689 36.9973 136.068 36.9973C132.446 36.9973 129.437 35.7902 127.039 33.3759C124.641 30.9617 123.442 27.9112 123.442 24.2246C123.442 20.5379 124.633 17.4875 127.014 15.0732C129.429 12.6589 132.446 11.4518 136.068 11.4518C139.689 11.4518 142.699 12.6589 145.097 15.0732C147.495 17.4875 148.694 20.5379 148.694 24.2246C148.694 27.9112 147.495 30.9617 145.097 33.3759ZM136.069 31.0758C134.373 31.0758 132.921 30.4722 131.714 29.2651C130.539 28.058 129.952 26.3778 129.952 24.2245C129.952 22.0713 130.547 20.3911 131.738 19.1839C132.929 17.9768 134.373 17.3732 136.069 17.3732C137.766 17.3732 139.209 17.9768 140.4 19.1839C141.591 20.3911 142.186 22.0713 142.186 24.2245C142.186 26.3778 141.591 28.058 140.4 29.2651C139.209 30.4722 137.766 31.0758 136.069 31.0758ZM164.901 36.0919C163.677 36.6302 162.381 36.8994 161.01 36.8994C158.172 36.8994 155.937 35.9941 154.306 34.1834C152.675 32.3727 151.859 30.1134 151.859 27.4055V12.1859H158.368V26.0842C158.368 27.5197 158.743 28.686 159.493 29.5832C160.244 30.4804 161.337 30.929 162.772 30.929C164.175 30.929 165.284 30.4967 166.1 29.6321C166.915 28.7676 167.323 27.6175 167.323 26.182V12.1859H173.832V31.9078C173.832 33.4411 173.914 34.893 174.077 36.2632H167.862C167.731 35.6107 167.666 34.7461 167.666 33.6695C167.046 34.7461 166.124 35.5536 164.901 36.0919ZM189.5 36.8507C191.066 36.8507 192.444 36.5408 193.635 35.9209C194.826 35.301 195.698 34.4854 196.253 33.474C196.253 34.518 196.335 35.4479 196.498 36.2635H202.713C202.582 34.9585 202.517 33.5067 202.517 31.908V0.832581H196.106V14.5841C195.03 12.5939 192.762 11.5989 189.304 11.5989C185.943 11.5989 183.178 12.806 181.009 15.2203C178.839 17.6345 177.755 20.6197 177.755 24.1759C177.755 27.8299 178.856 30.8559 181.058 33.2538C183.26 35.6518 186.074 36.8507 189.5 36.8507ZM185.977 29.1919C187.086 30.4154 188.522 31.0271 190.283 31.0271C192.013 31.0271 193.432 30.4072 194.541 29.1674C195.65 27.9277 196.205 26.2475 196.205 24.1269C196.205 22.0388 195.65 20.3994 194.541 19.2086C193.432 18.0178 192.013 17.4224 190.283 17.4224C188.554 17.4224 187.127 18.026 186.001 19.2331C184.876 20.4402 184.313 22.0878 184.313 24.1758C184.313 26.2964 184.868 27.9685 185.977 29.1919ZM218.798 36.9973C221.8 36.9973 224.279 36.198 226.237 34.5994C228.194 33.0007 229.466 31.0922 230.054 28.8736L224.328 26.9651C224.002 28.0743 223.382 29.0286 222.468 29.8279C221.555 30.6272 220.331 31.0269 218.798 31.0269C217.069 31.0269 215.609 30.4152 214.418 29.1917C213.227 27.9683 212.632 26.3126 212.632 24.2246C212.632 22.1366 213.219 20.489 214.394 19.2819C215.568 18.0747 217.02 17.4712 218.749 17.4712C221.522 17.4712 223.3 18.8251 224.083 21.533L229.907 19.5755C229.352 17.3243 228.096 15.4076 226.139 13.8253C224.181 12.243 221.669 11.4518 218.602 11.4518C215.079 11.4518 212.118 12.6589 209.72 15.0732C207.322 17.4875 206.123 20.5379 206.123 24.2246C206.123 27.8786 207.338 30.9209 209.769 33.3514C212.2 35.782 215.209 36.9973 218.798 36.9973ZM248.562 33.3759C247.028 35.7575 244.663 36.9483 241.466 36.9483C238.986 36.9483 236.988 36.2306 235.471 34.7951C233.954 33.3595 233.195 31.663 233.195 29.7055C233.195 27.6501 233.864 26.0026 235.202 24.7628C236.539 23.5231 238.268 22.7401 240.389 22.4138L246.311 21.5329C247.518 21.3698 248.121 20.7989 248.121 19.8201C248.121 18.9066 247.77 18.1562 247.069 17.569C246.368 16.9817 245.364 16.6881 244.059 16.6881C242.689 16.6881 241.604 17.0633 240.805 17.8137C240.006 18.564 239.557 19.4939 239.459 20.6031L233.685 19.3797C233.913 17.2917 234.941 15.4483 236.768 13.8497C238.595 12.2511 241.009 11.4518 244.01 11.4518C247.599 11.4518 250.242 12.3082 251.938 14.021C253.635 15.7338 254.483 17.9279 254.483 20.6031V32.446C254.483 33.8815 254.581 35.1539 254.777 36.2632H248.806C248.643 35.5454 248.562 34.583 248.562 33.3759ZM242.836 32.1037C241.857 32.1037 241.09 31.8346 240.536 31.2963C239.981 30.7579 239.704 30.0973 239.704 29.3143C239.704 27.5851 240.699 26.5738 242.689 26.2801L248.121 25.4482V26.5248C248.121 28.515 247.624 29.9423 246.629 30.8069C245.633 31.6714 244.369 32.1037 242.836 32.1037ZM265.918 22.4142V36.2636H259.41V12.1863H265.723V15.1715C266.408 13.9969 267.386 13.0998 268.659 12.4799C269.931 11.86 271.269 11.5501 272.672 11.5501C275.51 11.5501 277.672 12.4391 279.156 14.2172C280.64 15.9952 281.383 18.2872 281.383 21.0929V36.2636H274.874V22.2185C274.874 20.783 274.507 19.6248 273.773 18.7439C273.039 17.863 271.921 17.4226 270.421 17.4226C269.05 17.4226 267.957 17.8957 267.142 18.8418C266.326 19.7879 265.918 20.9787 265.918 22.4142ZM292.866 36.2636V22.4142C292.866 20.9787 293.274 19.7879 294.09 18.8418C294.905 17.8957 295.998 17.4226 297.368 17.4226C298.869 17.4226 299.987 17.863 300.721 18.7439C301.455 19.6248 301.822 20.783 301.822 22.2185V36.2636H308.33V21.0929C308.33 18.2872 307.588 15.9952 306.104 14.2172C304.619 12.4391 302.458 11.5501 299.619 11.5501C298.217 11.5501 296.879 11.86 295.607 12.4799C294.334 13.0998 293.355 13.9969 292.67 15.1715V12.1863H286.357V36.2636H292.866ZM333.149 33.3759C330.751 35.7901 327.742 36.9972 324.12 36.9972C320.499 36.9972 317.489 35.7901 315.091 33.3759C312.693 30.9616 311.494 27.9111 311.494 24.2245C311.494 20.5379 312.685 17.4874 315.067 15.0731C317.481 12.6589 320.499 11.4518 324.12 11.4518C327.742 11.4518 330.751 12.6589 333.149 15.0731C335.547 17.4874 336.746 20.5379 336.746 24.2245C336.746 27.9111 335.547 30.9616 333.149 33.3759ZM324.121 31.0757C322.425 31.0757 320.973 30.4722 319.766 29.265C318.591 28.0579 318.004 26.3777 318.004 24.2245C318.004 22.0712 318.6 20.391 319.79 19.1839C320.981 17.9767 322.425 17.3732 324.121 17.3732C325.818 17.3732 327.262 17.9767 328.452 19.1839C329.643 20.391 330.239 22.0712 330.239 24.2245C330.239 26.3777 329.643 28.0579 328.452 29.265C327.262 30.4722 325.818 31.0757 324.121 31.0757ZM346.762 22.4142V36.2636H340.254V12.1863H346.567V15.1715C347.252 13.9969 348.23 13.0998 349.503 12.4799C350.775 11.86 352.113 11.5501 353.516 11.5501C356.354 11.5501 358.515 12.4391 360 14.2172C361.484 15.9952 362.227 18.2872 362.227 21.0929V36.2636H355.718V22.2185C355.718 20.783 355.351 19.6248 354.617 18.7439C353.883 17.863 352.765 17.4226 351.265 17.4226C349.894 17.4226 348.801 17.8957 347.986 18.8418C347.17 19.7879 346.762 20.9787 346.762 22.4142Z" fill="white"/>
++<path d="M313.211 64.2638C318.224 64.2638 320.862 60.5706 320.862 60.5706L319.015 58.724C319.015 58.724 317.037 61.6258 313.211 61.6258C309.386 61.6258 306.353 58.5921 306.353 54.767C306.353 50.9419 309.386 47.9082 313.211 47.9082C317.037 47.9082 318.883 50.6781 318.883 50.6781L320.73 48.8315C320.73 48.8315 318.224 45.2702 313.211 45.2702C307.672 45.2702 303.451 49.491 303.451 54.767C303.451 60.043 307.672 64.2638 313.211 64.2638ZM324.294 64H327.196V50.4143L333.923 58.9878L340.65 50.4143V64H343.552V45.534H340.914L333.923 54.5032L326.932 45.534H324.294V64ZM353.568 64.2638C357.657 64.2638 360.163 61.7577 360.163 58.8559C360.163 51.9971 350.402 54.5032 350.402 50.4143C350.402 49.0953 351.589 47.9082 353.832 47.9082C356.338 47.9082 357.657 49.6229 357.657 49.6229L359.635 47.6444C359.635 47.6444 357.657 45.2702 353.832 45.2702C349.875 45.2702 347.5 47.6444 347.5 50.4143C347.5 57.2731 357.261 54.767 357.261 58.8559C357.261 60.3068 355.942 61.6258 353.568 61.6258C350.402 61.6258 348.951 59.5154 348.951 59.5154L346.973 61.4939C346.973 61.4939 349.083 64.2638 353.568 64.2638Z" fill="#FDFDFD"/>
++</svg>
--- /dev/null
--- /dev/null
++<?xml version="1.0" encoding="utf-8"?>\r
++<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
++<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
++ viewBox="325 451.6 374.2 120.8" enable-background="new 325 451.6 374.2 120.8" xml:space="preserve">\r
++<path fill="#FFFFFF" d="M491.4,451.6c-33.6,0-59.6,22.4-63.6,53.4c5.4,1.7,9.7,3.9,12.9,6.6c2.1-25.9,23-44.5,50.7-44.5\r
++ c11.5,0,21.7,3.2,30.1,8.8c0.3-0.6,0.8-1.4,2.2-1.8c5.4-1.6,10.6-1.4,15.3,0.4c0.3-0.9,0.5-1.8,0.9-2.7\r
++ C528.2,459.4,511.2,451.6,491.4,451.6z"/>\r
++<path fill="#FBAA19" d="M491.4,455.5c-31.9,0-56.4,21.5-59.9,50.8c2.1,0.8,3.9,1.7,5.6,2.7c3.4-26.5,25.5-45.8,54.3-45.8\r
++ c10.7,0,20.7,2.7,29,7.5c0.3-0.1,0.6-0.3,0.9-0.4c3.5-1,6.9-1.3,10.2-1C521.1,460.7,507.2,455.5,491.4,455.5z"/>\r
++<g>\r
++ <path fill="#14499E" d="M564.5,538.1v-62.1h-7.8c-0.1,4-1.6,7.8-4,10.3c-1.3,1.3-2.7,2.3-4.1,2.8c1,2.6,2.1,5.3,2.7,8.1\r
++ c1.2,4.8,1.6,6.5,1.9,10.9c0.3,2.2,0.3,4.4,0.3,6.5c0,12.7-3.5,25.2-9.8,35.7v5h45.4v-17.6h-24.6V538.1z"/>\r
++ <path fill="#14499E" d="M613.5,555.7h-20.7v-79.5h20.7V555.7z"/>\r
++ <path fill="#14499E" d="M666.2,526.1h-17.2l8.7-25.3L666.2,526.1z M671.9,541.9l5.2,13.8h22.1l-29.9-79.5h-22.5l-30.5,79.5h21.9\r
++ l5.4-13.8H671.9z"/>\r
++ <path fill="#14499E" d="M426.1,507.2c-7-2.2-7.9-2.3-8.9-2.8c-3.6-1.7-5.4-3.7-5.4-6.2c0-3.9,3.9-6.9,8.8-6.9\r
++ c3.4,0,6.5,0.9,9.7,2.7c1.8-5.6,4.4-10.9,7.6-15.5c-6.7-2.8-13.8-4.4-20.7-4.4c-16,0-27,10.9-27,26.8c0,6.9,2.1,12,5.9,15.5\r
++ c3,2.5,6.5,4,15.5,6.7c9.7,2.8,12.4,4.9,12.4,9.2c0,4.7-4.3,7.9-10.3,8.3c-5.7,0.4-10.9,0.3-17.2-5.2l-9.6,13.3\r
++ c8.4,5.8,18,8.9,27.7,8.9c19.5,0,31-10.5,31-28.3C445.7,517.8,440,511.2,426.1,507.2z"/>\r
++</g>\r
++<g>\r
++ <path fill="#14499E" d="M596.7,479.9c0,6.7,0,65.2,0,71.8c3.9,0,8.9,0,12.9,0c0-6.7,0-65.2,0-71.8\r
++ C605.7,479.9,600.7,479.9,596.7,479.9z"/>\r
++ <path fill="#14499E" d="M649.3,479.9c-1.7,4.4-24.2,62.8-27.5,71.8c5.2,0,10.6,0,13.6,0c1.3-3.4,5.4-13.8,5.4-13.8h33.9\r
++ c0,0,3.9,10.5,5.2,13.8c3,0,8.5,0,13.7,0c-3.4-8.8-25.3-67.4-27-71.8C662.9,479.9,652.8,479.9,649.3,479.9z M645.4,524.8l12.4-36.2\r
++ l13.8,41.4h-27.9L645.4,524.8z"/>\r
++ <path fill="#14499E" d="M560.6,542c0,0,0-55.2,0-62.1c-0.5,0-1.2,0-1.7,0c-0.8,3.5-2.3,6.6-4.5,9.1c-0.6,0.8-1.4,1.4-2.2,1.9\r
++ c0.6,1.9,1.3,3.7,1.8,5.6c1.2,4.9,1.6,6.9,1.9,11.4c0.3,2.3,0.4,4.7,0.4,6.9c0,12.2-3.1,24-8.5,34.4c0,1.2,0,2.1,0,2.6\r
++ c5.9,0,31.8,0,37.6,0c0-3.4,0-6.5,0-9.8C579.9,542,560.6,542,560.6,542z"/>\r
++ <path fill="#14499E" d="M394.2,501c0,5.7,1.6,9.8,4.7,12.5c2.2,1.8,4.9,3.2,14,5.8c8.7,2.6,15.3,5.2,15.3,12.9\r
++ c0,6.7-5.6,11.6-14,12.2c-5.2,0.4-10.6,0.3-16.7-3.6c-1.8,2.5-3,4.1-4.8,6.6c6.9,4,14.4,6.2,22.1,6.2c17.5,0,27.2-8.7,27.2-24.4\r
++ c0-8-2.8-14.2-16.8-18.4l-1.8-0.5c-5.7-1.7-6.3-1.9-7.6-2.5c-5.2-2.3-7.6-5.7-7.6-9.7c0-5.9,5.6-10.7,12.7-10.7\r
++ c2.6,0,5,0.5,7.5,1.3c1.2-2.8,2.5-5.6,4-8.3c-4.9-1.6-10.1-2.5-14.9-2.5C403.5,478,394.2,487.2,394.2,501z"/>\r
++</g>\r
++<path fill="#FBAA19" d="M346.5,517.3c1.2-6.1,5.2-9.6,12-9.6c5.8,0,10.5,3.5,11.9,9.3L346.5,517.3z M389.8,529.1v-2.7\r
++ c-0.1-20.2-12.7-32.1-33-31.8c-19.5,0.1-31.9,12.8-31.8,31.9c0.1,18.9,13.7,31,34.4,30.8c15.5-0.1,25.7-7.2,29.5-21.9l-20,0.1\r
++ c-2.6,5.4-5.2,7-10,7c-8.5,0.1-12.8-4.1-12.9-13.1L389.8,529.1z"/>\r
++<path fill="#FBAA19" d="M506.1,485.1c0,0,1.9-3.9,6.5-6.6c-6.2-3.1-13.4-4.9-21.2-4.9c-25.2,0-44,18.2-44,42.3\r
++ c0,24.2,18.9,42.4,44,42.4c25.2,0,44-18.2,44-42.4c0-10.5-3.5-19.8-9.6-27C517,484.2,506.1,485.1,506.1,485.1z M491.3,538.5\r
++ c-12.4,0-22.4-10-22.4-22.4c0-12.3,10-22.2,22.4-22.2s22.4,10,22.4,22.2C513.8,528.4,503.7,538.5,491.3,538.5z"/>\r
++<path fill="#FBAA19" d="M356.8,498.3L356.8,498.3c-17.3,0.1-28.1,10.9-27.9,28.1c0.1,16.8,11.9,27.2,30.5,27\r
++ c12.2-0.1,20-4.8,24-14.1c-4.9,0-9.7,0.1-12.2,0.1c-2.8,4.9-6.5,7-12.3,7c-10.6,0.1-16.7-5.9-16.9-16.9c0,0,0,0,0-0.1\r
++ c0-1,0.4-1.9,1-2.7c0.8-0.8,1.7-1.2,2.7-1.2c0,0,33.2-0.3,39.7-0.4c-0.3-8.1-2.8-14.9-7.5-19.5C373.3,500.8,365.9,498.2,356.8,498.3\r
++ z M343.5,519.9c-0.8-0.9-1-2.1-0.9-3.2c1.4-8,7.2-12.7,15.8-12.8l0,0c7.6-0.1,13.8,4.8,15.6,12.3c0.3,1.2,0,2.3-0.6,3.4\r
++ c-0.8,0.9-1.8,1.6-3,1.6l-23.9,0.3C345.3,521.3,344.3,520.8,343.5,519.9z"/>\r
++<path fill="#FBAA19" d="M506.1,485.1c0,0,0.9-1.8,3-3.9c-5.3-2.3-11.2-3.6-17.7-3.6c-22.9,0-40.1,16.5-40.1,38.4\r
++ c0,22,17.2,38.5,40.1,38.5s40.1-16.5,40.1-38.5c0-12.5-5.6-23.3-14.7-30.1C511,484.7,506.1,485.1,506.1,485.1z M517.7,516\r
++ c0,14.5-11.8,26.2-26.2,26.2s-26.2-11.8-26.2-26.2c0-14.5,11.8-26.1,26.2-26.1C505.8,489.9,517.7,501.7,517.7,516z"/>\r
++<path fill="#14499E" d="M518.5,562.4c-7.9,4.1-16.9,6.3-26.9,6.3c-20.2,0-37.1-9.4-46.5-24.2c-0.6,1.4-1.4,2.7-2.3,3.9\r
++ c10.7,14.4,28.3,23.3,48.9,23.3c9.6,0,18.4-1.9,26.2-5.3c0.1-0.6,0.1-1.3,0.4-1.9C518.3,563.6,518.5,562.9,518.5,562.4z"/>\r
++<path fill="#14499E" d="M552.9,472.6c-0.6-5-0.1-8,0.8-9.7c0-0.1-11.9-0.1-14.2,15.3c-5.7-3.2-11.5-3-16.3-1.6\r
++ c-0.8,0.3-0.6,0.5,0.1,0.5c3.1-0.1,6.1,0.5,8.8,1.9c-5.4-1.3-15.1-1.4-20.4,3.2c-0.3,0.1-0.5,0.3-0.5,0.4c0.5,0.1,4.9-0.8,15,3.6\r
++ c4.1,1.8,11.4,3.7,14.1-0.5c2.5,5.6,4.1,10.7,5,15.5c-1.8-3.1-4.1-4.5-4.8-4.8c-2.7-1.6-6.5-1.6-6.5-1.6s0.5,2.3,1.8,3.5\r
++ c3,3,7.4,2.1,7.2,1.8c0-0.8-0.3-1.4-0.5-1.9c2.2,2.3,3.7,8.1,4,10.9c0.9,10-1,18.4-3.1,24.8c-3.9,10-8.5,16.9-17.3,25\r
++ c-2.6-3.7-7.2-4.3-7.8-2.8v0.1c2.5-0.3,8.4,2.3,7.9,8.4c-0.6,7.4-6.5,5-5.3,0.1c0.8-3.4-0.6-5-1.9-6.1c0.6,1.3,1.6,3.1,0.5,6.5\r
++ c-2.3,7.9,7,11,8.3,0.9c0-0.5,0-1,0-1.4c15.9-12.9,24.2-34.9,22.1-56c-0.4-4.1-0.6-5.8-1.8-10.5c-0.9-3.6-2.2-7.2-3.7-10.6\r
++ C548.2,487.8,554.1,482.3,552.9,472.6z"/>\r
++<g>\r
++ <path fill="#14499E" d="M541.7,478.5l-0.5,3.5l0,0c0.5,1.2,1.2,2.6,1.2,2.6c0.1,0.1,0.1,0.4,0.1,0.5c0.8,0,1.7,0.1,1.7,0.1\r
++ c0.9,0,2.5-0.4,3.7-1.9c1.8-1.9,2.7-4.7,2.7-7.9c0-0.8,0-1.6-0.1-2.3c-0.3-1.6-0.4-3.1-0.4-4.4c0-0.9,0.1-1.7,0.3-2.6\r
++ C547.3,467.1,543,470.1,541.7,478.5z"/>\r
++ <path fill="#14499E" d="M529.8,481.1c-3.4-0.8-6.1-0.8-10.3,0.1c2.3,0.6,4.8,1.4,7.4,2.6c4.1,1.8,9.4,3,11,0.4c0,0,1.2-1.9,1.8-3\r
++ c-0.9-0.5-1.7-1-1.7-1c-1.8-1-3.6-1.6-5.6-1.9C534,482,529.8,481.1,529.8,481.1z"/>\r
++</g>\r
++<path fill="#FBAA19" d="M491.3,489.9c13.6,0,24.8,10.3,26.1,23.5c0.1-0.9,0.1-1.7,0.1-2.6c0-14.5-11.8-26.1-26.2-26.1\r
++ c-14.5,0-26.2,11.8-26.2,26.1c0,0.9,0,1.8,0.1,2.6C466.5,500.2,477.7,489.9,491.3,489.9z"/>\r
++</svg>\r
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" fill="none" height="100%" width="100%" viewBox="0 0 238 79">
++ <defs>
++ <linearGradient id="a" x1="63.6351" x2="39.318" y1="54.0451" y2="1.59593" gradientUnits="userSpaceOnUse">
++ <stop offset=".24" stop-color="#00D886"/>
++ <stop offset=".51" stop-color="#007DFE"/>
++ </linearGradient>
++ <linearGradient id="b" x1="59.3792" x2=".674325" y1="4.38051" y2="63.0854" gradientUnits="userSpaceOnUse">
++ <stop offset=".27" stop-color="#007DFE"/>
++ <stop offset=".7" stop-color="#D249FC"/>
++ </linearGradient>
++ </defs>
++ <path fill="#000" fill-rule="evenodd" d="M107.38 35.54h-7.19v-4.29h12.41v2.31c0 2.63-.62 5-1.88 7.11-1.26 2.12-2.99 3.78-5.19 4.99-2.2 1.21-4.51 1.82-7.37 1.82-2.86 0-5.44-.67-7.74-2.02-2.31-1.34-4.12-3.2-5.44-5.56-1.32-2.36-1.98-5-1.98-7.91s.66-5.55 1.98-7.91c1.32-2.36 3.14-4.21 5.44-5.56 2.31-1.35 4.89-2.02 7.74-2.02 2.27 0 4.36.4 6.29 1.21 1.93.8 3.56 1.93 4.9 3.39 1.35 1.45 2.29 3.14 2.85 5.07h-5.71c-.49-1-1.14-1.86-1.95-2.59-.82-.73-1.76-1.28-2.84-1.67-1.08-.39-2.25-.58-3.5-.58-1.84 0-3.51.46-5 1.38-1.49.92-2.66 2.19-3.5 3.81-.84 1.62-1.26 3.44-1.26 5.47s.42 3.85 1.26 5.47c.84 1.62 2.01 2.89 3.5 3.81 1.49.92 3.16 1.38 5 1.38 1.71 0 3.25-.32 4.63-.96 1.38-.65 2.48-1.54 3.29-2.69.73-1.04 1.14-2.19 1.26-3.46Zm19.54-11c2.15 0 4.11.5 5.86 1.5s3.13 2.37 4.14 4.12c1.01 1.74 1.51 3.7 1.51 5.85 0 2.15-.5 4.1-1.51 5.85s-2.38 3.12-4.14 4.12c-1.76 1-3.74 1.5-5.89 1.5-2.15 0-4.11-.5-5.86-1.5s-3.13-2.37-4.14-4.12c-1.01-1.74-1.51-3.7-1.51-5.85 0-2.15.5-4.1 1.5-5.85s2.38-3.12 4.14-4.12c1.77-1 3.75-1.5 5.9-1.5Zm3.25 17.55c.95-.58 1.69-1.4 2.21-2.46s.78-2.25.78-3.62-.26-2.58-.79-3.63c-.52-1.05-1.26-1.87-2.21-2.46-.95-.59-2.04-.89-3.26-.89-1.22 0-2.31.3-3.26.88-.95.58-1.68 1.4-2.2 2.46-.52 1.06-.78 2.28-.78 3.64 0 1.36.26 2.56.78 3.62.52 1.05 1.25 1.88 2.2 2.46.94.59 2.04.88 3.26.88 1.22 0 2.32-.3 3.27-.88Zm17.73-25.08h.01l-.01-.01v.01Zm0 0h-5.3v29.96h19.75v-4.82H147.9V17.01Zm30.87 8.73c1.11.66 2.02 1.54 2.73 2.63v-3.31h4.96v21.92h-4.96v-3.31c-.71 1.09-1.62 1.98-2.73 2.63-1.36.8-2.95 1.2-4.76 1.2-1.94 0-3.68-.49-5.22-1.47-1.54-.98-2.75-2.34-3.62-4.09-.87-1.75-1.3-3.72-1.3-5.92 0-2.2.43-4.17 1.3-5.92.87-1.75 2.08-3.11 3.61-4.09 1.53-.98 3.28-1.47 5.23-1.47 1.81 0 3.4.4 4.76 1.2Zm-.29 16.36c.94-.59 1.67-1.41 2.2-2.46.53-1.05.79-2.26.79-3.63s-.26-2.58-.79-3.63c-.52-1.05-1.26-1.87-2.2-2.46-.94-.59-2.05-.89-3.25-.89-1.2 0-2.27.3-3.21.89-.94.59-1.67 1.41-2.19 2.46s-.78 2.26-.78 3.63.26 2.58.78 3.64 1.25 1.88 2.19 2.46c.94.59 1.99.88 3.21.88s2.31-.3 3.25-.89Zm24.72-17.56c1.57 0 2.95.34 4.13 1.03l.01.03c1.18.68 2.11 1.68 2.76 2.97.65 1.29.98 2.84.98 4.64v13.78h-5.03V33.98c0-1.06-.18-1.96-.54-2.7-.36-.74-.87-1.31-1.54-1.7-.67-.39-1.47-.59-2.4-.59-.99 0-1.88.22-2.65.67-.77.45-1.37 1.07-1.79 1.88-.42.81-.63 1.72-.63 2.75v12.69h-5.05V25.06h4.9v3.21c.63-1.06 1.44-1.92 2.45-2.55 1.25-.79 2.72-1.18 4.4-1.18Zm29.04 3.79v-11.3h5.05v29.96h-5.05v-3.28c-.71 1.07-1.61 1.94-2.71 2.59-1.36.8-2.95 1.2-4.76 1.2-1.94 0-3.68-.49-5.22-1.47-1.54-.98-2.75-2.34-3.62-4.09-.87-1.75-1.31-3.72-1.31-5.92 0-2.2.44-4.17 1.31-5.92.87-1.75 2.08-3.11 3.61-4.09 1.53-.98 3.27-1.47 5.23-1.47 1.81 0 3.4.4 4.76 1.2 1.1.64 2 1.52 2.71 2.59Zm-3.01 13.77c.95-.59 1.68-1.41 2.21-2.46s.79-2.26.79-3.63-.26-2.58-.79-3.63c-.53-1.05-1.27-1.87-2.21-2.46-.94-.59-2.05-.89-3.25-.89-1.2 0-2.27.3-3.21.89-.94.59-1.67 1.41-2.19 2.46s-.78 2.26-.78 3.63.26 2.58.78 3.64 1.25 1.88 2.19 2.46c.94.59 1.99.88 3.21.88s2.31-.3 3.25-.89ZM87.7037 74.19c.17-.31.25-.66.25-1.05h.01v-9.15h3.1v9.37c0 .88-.2 1.67-.61 2.38s-.97 1.26-1.68 1.66c-.71.4-1.52.6-2.41.6h-2.37v-2.85h1.95c.4 0 .75-.08 1.05-.25.31-.17.54-.4.71-.71Zm15.2603-1.9h-6.5003v3.02h7.3803v2.7H93.4437V63.99h10.2003v2.71h-7.1803v2.97h6.5003v2.62Zm6.16-5.52h-4.16v-2.78h11.39v2.78h-4.13V78h-3.1V66.77Zm17.2 3.9c.29.08.56.18.81.31h.01c.57.31 1.02.73 1.34 1.28.32.55.48 1.17.48 1.86 0 .75-.2 1.42-.61 2.01-.41.59-.98 1.05-1.72 1.38-.74.33-1.58.5-2.52.5h-6.35V63.99h6.23c.89 0 1.69.16 2.39.47.7.31 1.24.75 1.63 1.31.39.56.58 1.2.58 1.91 0 .62-.15 1.17-.44 1.65-.29.48-.7.86-1.21 1.12-.18.0945-.386.1532-.585.21l-.035.01Zm-2.8-4.33h-2.75v3.45h2.75c.38 0 .72-.08 1.01-.22.3-.14.52-.34.69-.61.17-.27.25-.59.25-.93 0-.34-.09-.64-.25-.89-.17-.26-.4-.45-.69-.59-.29-.14-.63-.21-1.01-.21Zm1.24 9.1c.32-.15.57-.35.75-.62v.02c.18-.27.27-.57.27-.93 0-.36-.09-.68-.27-.96-.18-.28-.44-.5-.76-.65-.33-.15-.7-.23-1.11-.23h-2.87v3.59h2.87c.42 0 .8-.07 1.12-.22Zm16.56-4.67c-.43.67-1.03 1.2-1.81 1.57h-.01c-.14.07-.3.13-.46.19l3.2 5.48h-3.54l-2.84-5.11h-2.02v5.11h-3.1V63.99h6.14c1.01 0 1.9.18 2.67.55.77.37 1.36.89 1.78 1.56.42.67.63 1.43.63 2.32 0 .89-.21 1.68-.64 2.35Zm-3.56-.61c.32-.16.57-.39.74-.68v.01c.17-.29.26-.63.26-1.03s-.09-.74-.26-1.03c-.17-.29-.42-.51-.74-.67-.32-.15-.7-.23-1.13-.23h-2.79v3.87h2.79c.43 0 .81-.08 1.13-.24Zm5.51 7.85 5.01-14.02h3.36l5.12 14.02h-3.09l-1.06-3.09h-5.2l-.99 3.09h-3.15Zm6.46-10.39-1.61 4.95h3.71l-1.72-4.95-.19-.9-.19.9Zm11.43 10.39h-3.2V63.99h3.2v14.02Zm5.44-14.02 6.02 9.48h.01v-9.48h2.83v14.02h-3.05l-6-9.48v9.48h-2.83V63.99h3.02Zm17.78 5.66c.71.13 1.33.4 1.88.79v-.02c.55.4.97.88 1.28 1.47.31.59.46 1.23.46 1.92 0 .85-.23 1.61-.68 2.28-.45.67-1.08 1.2-1.88 1.58-.81.38-1.74.57-2.77.57s-1.95-.19-2.75-.56c-.8-.37-1.43-.9-1.89-1.56-.46-.66-.7-1.44-.71-2.31h3.1c0 .36.1.68.29.96.19.28.46.49.81.64.35.15.75.23 1.18.23.43 0 .8-.07 1.12-.2.32-.13.56-.32.74-.57.18-.25.27-.53.27-.84 0-.39-.12-.71-.36-.97s-.57-.44-.98-.54l-2.52-.52c-.66-.14-1.24-.39-1.74-.75s-.89-.82-1.16-1.36c-.27-.55-.41-1.16-.41-1.83 0-.84.22-1.58.64-2.23.43-.65 1.02-1.16 1.78-1.53.76-.37 1.62-.55 2.6-.55s1.86.18 2.62.53c.76.35 1.36.84 1.79 1.47.43.62.66 1.35.68 2.16h-3.1c0-.3-.09-.57-.25-.81-.17-.24-.4-.42-.69-.55-.29-.14-.64-.2-1.02-.2s-.72.07-1.01.19c-.29.12-.52.3-.68.52-.16.23-.24.49-.24.79 0 .34.11.61.33.84.22.23.52.38.89.47l2.38.49Zm14.38 8.36h-3.2V63.99h3.2v14.02Zm7.88-14.02c1.33 0 2.53.31 3.59.91 1.06.61 1.9 1.44 2.5 2.51.61 1.06.91 2.27.91 3.59 0 1.32-.31 2.52-.91 3.59-.6 1.07-1.43 1.9-2.5 2.51-1.07.61-2.26.91-3.59.91h-5.47V63.99h5.47Zm2.01 10.86c.58-.35 1.03-.85 1.34-1.5v-.01c.31-.65.47-1.44.47-2.35 0-.91-.16-1.7-.47-2.35-.31-.65-.76-1.15-1.34-1.5-.58-.35-1.26-.52-2.05-.52h-2.32v8.75h2.32c.79 0 1.47-.17 2.05-.52Zm9.8-2.56v3.02h7.38v2.7h-10.4V63.99h10.2v2.71h-7.18v2.97h6.5v2.62h-6.5Z" clip-rule="evenodd"/>
++ <path fill="#00D886" d="m48.0521 58.1839 11.8755-.0017c2.2493 0 4.0722-1.8234 4.0722-4.0727V42.6029c0-1.1887-.5196-2.3186-1.422-3.0924L24.4164 6.80068c-.7384-.63244-1.6786-.98037-2.6508-.98037H9.89011c-2.24931 0-4.07273 1.82342-4.07273 4.07273V21.4014c0 1.1887.51957 2.3185 1.42197 3.0924L45.4002 57.203c.7383.633 1.6786.9804 2.6514.9804l.0005.0005Z"/>
++ <path fill="url(#a)" d="M49.4806 58.1818h10.4465c2.2493 0 4.0728-1.8234 4.0728-4.0727V41.0164c0-.1925-.014-.3851-.0408-.576L58.6815 3.49673C58.3952 1.49062 56.6765 0 54.65 0H38.977c-2.2499 0-4.0733 1.824-4.0727 4.07389l.0047 18.53851c0 .4375.0704.8721.2088 1.2869l10.4995 31.4979c.5545 1.6629 2.1109 2.7846 3.8639 2.7846h-.0006Z"/>
++ <path fill="url(#b)" d="M4.07273 64H38.041c1.6291 0 3.1017-.9711 3.7434-2.4681l16.0681-37.4906c.217-.5068.3293-1.0531.3293-1.6046V4.07273C58.1818 1.82342 56.3584 0 54.1091 0h-17.966c-.8046 0-1.5912.238545-2.2609.685382L1.81353 22.0881C.681309 22.8439.001745 24.1146.001745 25.4755L0 59.9273C0 62.1766 1.82342 64 4.07273 64Z"/>
++ <path fill="#000" d="M52 12H12v40h40V12Z"/>
++ <path fill="#fff" d="M19.764 31.6245c1.174.6765 2.4847 1.0155 3.9318 1.0155 1.3899 0 2.6427-.3095 3.7589-.9293 1.1231-.6197 2.005-1.4651 2.6461-2.5384.6481-1.0798.9721-2.2857.9721-3.6183v-1.1879h-6.405v2.3221h3.516c-.0722.5605-.2761 1.0718-.6106 1.5339-.3958.5468-.9322.9762-1.6092 1.2852-.6701.3096-1.4188.4646-2.2469.4646-.8928 0-1.6988-.2227-2.4193-.6695-.7204-.4467-1.2857-1.0583-1.6959-1.836-.4034-.784-.6047-1.667-.6047-2.6461 0-.979.2013-1.858.6047-2.6357.4108-.7846.9761-1.4003 1.6959-1.847.7199-.4467 1.5265-.6695 2.4193-.6695.6053 0 1.1706.0972 1.696.2916.526.1875.9831.4577 1.372.8101.3958.3455.7094.7563.9397 1.2314h3.1542c-.2737-.9866-.7529-1.8575-1.4368-2.6137-.677-.7563-1.5126-1.3436-2.5061-1.7608-.9866-.4172-2.0669-.6267-3.2404-.6267-1.4477 0-2.7583.3414-3.9318 1.0259-1.1741.6765-2.0959 1.6133-2.7653 2.8082-.6695 1.1879-1.0046 2.5165-1.0046 3.9856 0 1.4692.3351 2.8018 1.0046 3.9967.67 1.1879 1.5918 2.1236 2.7653 2.8081Z"/>
++ <path fill="#fff" fill-rule="evenodd" d="M36.1829 31.6245c1.181.6765 2.4951 1.0155 3.9422 1.0155 1.4541 0 2.7688-.339 3.9423-1.0155 1.181-.6845 2.1062-1.6202 2.7757-2.8081.6695-1.1949 1.0045-2.5275 1.0045-3.9967 0-1.4691-.335-2.7977-1.0045-3.9856-.6695-1.1949-1.5947-2.1317-2.7757-2.8082C42.8939 17.3414 41.5723 17 40.1251 17c-1.4471 0-2.7612.3414-3.9422 1.0259-1.1735.6765-2.0988 1.6133-2.7758 2.8082-.6695 1.1879-1.0045 2.5165-1.0045 3.9856 0 1.4692.335 2.8018 1.0045 3.9967.6765 1.1879 1.6023 2.1236 2.7758 2.8081Zm6.3621-2.2463c-.7129.4468-1.516.6695-2.4089.6695-.8928 0-1.6994-.2227-2.4193-.6695-.7128-.4536-1.2747-1.0756-1.685-1.8684-.4033-.7991-.6046-1.696-.6046-2.6895 0-.9935.2013-1.8858.6046-2.6785.4103-.7991.9722-1.4217 1.685-1.8684.7199-.4537 1.5265-.6805 2.4193-.6805.8929 0 1.696.2268 2.4089.6805.7129.4467 1.2707 1.0693 1.674 1.8684.4033.7921.6047 1.685.6047 2.6785s-.2014 1.8904-.6047 2.6895c-.4033.7922-.9611 1.4148-1.674 1.8684Z" clip-rule="evenodd"/>
++ <path fill="#fff" d="M16.9941 44h16v3h-16v-3Z"/>
++</svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 1280 492" overflow="visible" xmlns="http://www.w3.org/2000/svg"><path d="m106.3 334.1c1.9 5.2 3.8 10.7 5.3 16.1-10.5 27.1-42.9 29.2-57.7 14.2-2.5-4.6-4.6-9.4-6.5-14.4 13.8 2.5 46.3-5 58.9-15.9zm80.4-207.2c1.8-6.5 1.8-13.4.2-20-2-7.6-6.1-14.4-12-19.7 0 0-12.8-23.7-36.2-23.7-14 .2-27.4 5.2-38 14.3-9 17.1-12.1 35.8-7.5 53.9 4.4 17.1 15 31.3 29.7 41.9 0 0 30.1 2.1 47.1-10.5 16.4-12.2 16.7-36.2 16.7-36.2zm33.2 125.1-50.1 42c-2.9-3.4-25.7-29.4-36-60l57.1-33.2c12.1 27.1 21.7 40.1 29 51.2zm-50.8 40.6c.5.6.5.6 0 0zm170.7 35.1c-8.5 9.9-34.8 26.2-48.7 26.2 1.7 4.8 3 9.8 3.8 14.8 9.6 15.9 50.3.4 46.2-25.7-.1-5.1-.5-10.2-1.3-15.3zm-141 88.1c-.1 4.6-.4 9.4-.6 14.4 6.4 20.7 47.2 23 58.7-.5 2.7-3.6 6.7-10.3 9.4-20.8-19.6 14.2-54.3 13.7-67.5 6.9zm101.3-282.8c1.2-4.2 2.3-8.5 3.2-12.8-17.3-2.7-34.7-4.4-52.1-4.9-1.3 4.2-3 8.2-5.1 12 8.1 20.1 40.9 21.9 54 5.7zm979.9 15v128c0 4.4-3.6 8-8 8h-296c-4.4 0-8-3.6-8-8v-128c0-4.4 3.6-8 8-8h296c4.4 0 8 3.6 8 8zm-162.4 107.2-53.8-46.6 52.2-39.6v-5h-22.7l-60.6 46v-46h-20.4v96h20.4v-41h14.1l47.2 41h23.7zm32.6-67h-19.9v71.8h19.9zm.4-27.5h-20.7l.9 17.3h18.9zm90.1 98.5-2.3-14.6c-5.7 1.1-11.4 1.6-17.2 1.6-16.1 0-22.4-6.4-22.4-18v-25.6h41.4v-14.5h-41.5v-19.1h-10.4l-9.6 19.2h-17.3v14.5h17.6v25.8c0 20.3 10.7 33.1 40.3 33.1 7.1 0 14.3-.8 21.4-2.4z" fill="#d99b21"/><path d="m339.8 327.7c-7.1-43.3-43.6-72.7-80.8-72.7-6.2 0-12.4.7-18.5 2-7.2-8-13.7-16.8-19.2-26 33.1-13.7 65.8-53.9 78.8-98-2.6 2.1-8.2 5-19.1 5-22.9 0-32.2-7.6-35-10.7-9.7 17.3-28.1 31.7-47 31.7-4.7 0-9.4-.5-14.1-1.4 7.7-14.4 9-26.8 4.3-32.2-.7-.8-2-.9-2.8-.2-.3.3-.5.6-.6 1-7.2 28.9-40.8 46.7-71 46.7-30.4.1-55.8-17.2-55.8-43.7 0-29.5 34.1-56.2 72.2-56.2 17.2 0 32.6 5.5 42.9 15.1.8.7 2 .7 2.8-.1.3-.3.5-.7.5-1.1 2.5-17-29.9-39.7-69.1-39.7-4.5 0-9.1.3-13.6.9l-2.4-9c-.7-2.5-.3-3.8 1.4-5.7 7.4-8.2 6.8-20.8-1.4-28.3-8.2-7.4-20.8-6.8-28.3 1.4-7.4 8.2-6.8 20.8 1.4 28.3 2.1 1.9 4.7 3.4 7.4 4.2 2.4.8 3.3 1.8 4 4.2l2.2 8.2c-37.5 11.6-65 44.3-65 80.2 0 46.9 40.2 68.2 64.3 73.3-8.9 5-16.6 11.8-22.7 20l-4.1-7.1c-.7-1-.8-2.4-.2-3.5 1.9-4.6-.3-9.9-5-11.7-4.6-1.9-9.9.3-11.7 5-1.9 4.6.3 9.9 5 11.7.7.3 1.4.5 2.2.6 1.3.1 2.4.8 2.9 1.9l6.1 10.5c-3 5-5.5 10.3-7.4 15.8l-20.5-35.1c-.8-1.1-.9-2.6-.1-3.7 2.9-6 .4-13.1-5.6-16-1.8-.9-3.7-1.3-5.7-1.2-6.6.2-11.8 5.8-11.6 12.4.2 6.1 5.1 11.1 11.2 11.5 1.3 0 2.6.8 3.1 2l25.2 43.6c-1.7 8-2.5 16.2-2.5 24.4 0 28.1 4.8 49.1 10.4 64 1.9 1.8 6.4 4 16.6 4 22.4 0 41.1-9.5 42.2-20 19.6 29.9 40.3 38.2 74.7 47 10.9 2.8 17.8 10.9 17.8 31 0 1.2 0 2.5-.1 3.8 2.9 3.3 10.4 8.2 29.2 8.2 23.9 0 34.4-10.1 38.2-15.1 1.9-7.8 2.8-15.8 2.8-23.9 0-24.7-18.1-47.9-42.8-61.2 5.5-1.2 11.2-1.8 16.8-1.8 21.4 0 39.5 8.6 48 31.9 1.6 1 4.4 2.1 9 2.1 15.2 0 35-15.6 40.1-28.3zm-126.6-74.9c-25.6 25.1-54.5 41.9-62.2 46.1-1.2.6-2.6.4-3.6-.5-16.9-17.3-26.7-40.7-29.6-48.1-.5-1.3.1-2.8 1.3-3.4 23.5-12 46.2-25.5 67.8-40.5.9-.6 2.1-.4 2.8.5.1.1.1.2.2.3 6.7 14.5 14.6 28.5 23.6 41.8.9 1.2.8 2.8-.3 3.8zm164.8 111.2c0 22.1-24 41-50 41-17.4 0-29.6-12-33-35-.1-.4-.1-.9-.2-1.3 1.3 1.2 3.5 2.3 7.2 2.3 16.2 0 39-17.3 39-28 0 0 2.2-1 8-1 15 0 29 7.7 29 22zm-121.1 65.7c9.1 12.4 14.1 25.4 14.1 33.3 0 15-9.3 29-26 29-24.4 0-47-24.5-47-54 0-2.6.1-5.2.2-7.8 2.2 3.6 8.7 8.8 27.8 8.8 16.3 0 25.8-5.1 30.9-9.3zm-145.3-79.5c2.6 9.2 4.4 18.3 4.4 25.9 0 12.7-3.4 20.4-11.2 23-2.3 14-8.1 22-19.8 22-16.5 0-32-17.2-32-48 0-2.9.3-5.8.9-8.7 3.1 2 8 3.7 16.1 3.7 25.6-.1 37.7-12.8 41.6-17.9zm122.4-259.2c0-5.1 4.3-8 10-8 2.7 0 5.4.5 7.9 1.5-.6-3.5-.9-7-.9-10.5 0-17.9 6.3-32 22-32 17.7 0 33 21.9 33 52 0 8.8-.9 17.6-2.7 26.2-2.6 1.5-8.6 3.8-20.3 3.8-25.3 0-31.9-8.7-31.9-8.7-7.5-6.3-17.1-15.9-17.1-24.3zm168.1 116.6h51.6v48.8c-14.8 3.5-30 5.3-45.2 5.3-42.2 0-64.6-19.6-64.6-49.8 0-30.7 24.2-49.5 66.8-49.5 13.7 0 27.3 1.4 40.7 4.2l-3.4 15.4c-12.1-2.3-24.3-3.4-36.6-3.4-32.4 0-46.9 13.1-46.9 33.7 0 20.7 13.9 33.3 44.6 33.3 8.6.1 17.3-.5 25.8-1.8v-21.1l-32.9-5.4zm449 37 2.3 14.6c-7.1 1.6-14.3 2.4-21.5 2.4-29.6 0-40.3-12.8-40.3-33.1v-25.8h-17.6v-14.5h17.3l9.7-19.2h10.4v19.2h41.5v14.5h-41.4v25.6c0 11.6 6.4 18 22.4 18 5.8-.1 11.6-.6 17.2-1.7zm-108.4-83.9h20.7l-.8 17.3h-18.9zm208.8 27.5v4.9l-49.5 90.9h-25.1v-4.8l28.8-22.6v-.8h-11.5l-34.3-62.7v-4.9h19.3l27 54.2 26.4-54.2zm-430.5 0h10v18.9l-38.1 9.5v43.4h-19.9v-71.8h13.4l5.3 16.1zm222.1 0h19.9v71.8h-19.9zm-32 0h19.2v4.9l-38.3 66.9h-16.6l-38.5-66.9v-4.9h19.5l27.4 50.2zm-132-1.5c-11 .1-22.1 1.3-32.9 3.6l2.3 13.8c9.4-2 19-3 28.7-3.1 19.2 0 26 6.1 26.9 16.4l-34.9.9c-19.3.5-28.5 8.7-28.5 21.4 0 12.6 10.3 21.9 30 21.9 13.2 0 25.1-4.6 34.6-10.3l4.7 8.7h14.1v-38.3c0-21.3-10.2-35-45-35zm25.2 55.3c-8.4 3.9-17.6 6.6-27.3 6.6-12.2 0-17.3-4.2-17.4-10.3 0-5.9 4.3-9.2 12.3-9.5l32.4-1.1z" fill="#001a4d"/></svg>
++
++
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" enable-background="new 0 0 575.8 178.3" viewBox="0 0 575.8 178.3"><path d="m148.6 78.9-24.7-13.6-20.8 12.7-.3 13-10.1-6.7-13.8 8.4c-.2-3.9-.4-8.6-.6-14.2l-14.2-9.5c3.9-2 8.4-4.3 13.5-7-.1 0 .1 1.4-2-46.5l-32-15.4-43.6 13.6 9.7 46.9 14.6 11.4-11.1 5.3 7.3 35.3 10.2 9.6-7.3 4.5 5.7 27.3 22.9 24.3c.1-.1 2.4-1.9 29.5-23.5l-.8-18.6 11.7 9.9c.2-.2 2.4-1.9 23.7-18.8l.8-13.7 8.8 6.1c.1-.2 2.1-1.7 19.3-15.3z"></path><path d="m128.1 93.5 20.5-14.6-24.7-13.6-20.8 12.7z" fill="#141414"></path><path d="m125.8 119.5 2.3-26-25-15.5-.5 25.4z" fill="#004b16"></path><path d="m92.6 146-.3-27-25.1-19.1 1.9 26.4z" fill="#004b16"></path><path d="m92.3 119 25.5-18.2-25.1-16.5-25.5 15.6z" fill="#141414"></path><path d="m52.1 178.2-4.1-27.6-24.6-24.1 5.7 27.4z" fill="#004b16"></path><path d="m48 150.6 32.4-23.1-25.1-20.4-31.9 19.4z" fill="#141414"></path><path d="m45.9 136.3-5.3-36.4-27.4-22.8 7.3 35.4z" fill="#004b16"></path><path d="m40.6 99.9 37.7-21.4-28.2-18.9-36.9 17.5z" fill="#141414"></path><path d="m38 82.5-7.3-49.9-30.7-19 9.7 46.9z" fill="#004b16"></path><path d="m30.7 32.6 44.9-17.2-32-15.4-43.6 13.6z" fill="#141414"></path><g fill="#1cb35c"><path d="m145.2 104.2c-19 15.1-19.4 15.4-19.3 15.4 2.4-27.2 2.2-26 2.3-26 21.8-15.5 20.4-14.6 20.5-14.6z"></path><path d="m116.2 127.2c-23.5 18.7-23.8 18.8-23.7 18.8-.2-28.2-.3-27-.2-27 27.1-19.4 25.4-18.2 25.5-18.2z"></path><path d="m81.6 154.7c-29.4 23.3-29.6 23.5-29.5 23.5-4.2-28.4-4.1-27.5-4-27.5 34.5-24.6 32.3-23.1 32.4-23.1z"></path><path d="m75.6 15.4c2.1 47.9 1.9 46.5 2 46.5-38.8 20.2-39.7 20.6-39.6 20.6-7.5-51-7.4-49.9-7.3-49.9z"></path><path d="m78.3 78.5c1.6 36.3 1.4 35.1 1.5 35.1-33.6 22.6-34 22.8-33.9 22.8-5.5-37.4-5.4-36.4-5.3-36.4z"></path></g><path d="m191.4 33.6 16.8-4c0 81.8-3.1 93.5 8 97.1-2.6 4.9-7.1 7.4-13.3 7.4-15.3 0-11.5-11.3-11.5-100.5z"></path><path d="m233.7 132.7v-58.4h-9.2v-13.8h26.3v72.2zm8.7-100.1c12.9 0 12.9 19.5 0 19.5s-12.9-19.5 0-19.5z"></path><path d="m316.8 132.7c0-43.6 1.1-49.6-3.5-55.2-5.8-6.9-20-5-26.1 3v52.2h-16.8v-72.2h12.1l3.1 6.7c9.1-10.8 30.4-10.9 40.6-.4 9.7 10 7.4 20.5 7.4 65.8z"></path><path d="m347.2 96.4c0-49.2 69.4-51.1 69.4 0-.1 50.7-69.4 50.8-69.4 0zm17.5 0c0 28.8 22.2 27.7 29.7 17.7 7-9.4 8.8-41.2-12.5-41.2-12.3 0-17.2 11.3-17.2 23.5z"></path><path d="m476.4 132.7c0-7.4 1.8-3.4-7.1-.4-10.2 3.5-25.1 2-34.1-7.9-11.1-12.3-12.6-39.5 1.3-54.6 11.4-12.3 28.5-13.1 39.9-7.4v-28.9l16.9-4v103.1zm0-54.9c-8.9-7.1-20.9-4.8-26.8 1.9-8.1 9.1-11.2 40.2 16.2 40.2 2.9 0 9-2.2 10.6-4.4z"></path><path d="m574.6 101.8h-51.6c1.2 22.3 29 21.4 38.1 12.2l6.5 12.9c-14 11.3-62.3 15-62.3-29.5.1-54.1 81.3-49 69.3 4.4zm-51-12.7h35.5c-1.2-10.6-7-15.8-17.5-15.8-9.7 0-15.6 5.2-18 15.8z"></path></svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 298 144" xmlns="http://www.w3.org/2000/svg">
++<path d="M92.056 39.544H86.68L68.536 66.616V80.056H78.712V91H46.072V80.056H55.672V66.52L36.952 39.544H31.384V28.6H57.208V39.544H52.024L62.488 55.288H63.064L73.432 39.544H67.48V28.6H92.056V39.544ZM134.601 69.4C134.601 76.248 132.361 81.72 127.881 85.816C123.401 89.912 117.705 91.96 110.793 91.96C104.137 91.96 98.6965 90.04 94.4725 86.2C90.3125 82.296 88.2325 76.856 88.2325 69.88C88.2325 63.544 90.1525 58.104 93.9925 53.56C97.8325 49.016 103.657 46.744 111.465 46.744C119.273 46.744 125.065 49.016 128.841 53.56C132.681 58.04 134.601 63.32 134.601 69.4ZM121.833 69.016C121.833 64.6 120.809 61.368 118.761 59.32C116.713 57.272 114.217 56.248 111.273 56.248C108.073 56.248 105.545 57.4 103.689 59.704C101.897 61.944 101.001 65.112 101.001 69.208C101.001 72.92 101.833 76.056 103.497 78.616C105.225 81.176 107.785 82.456 111.177 82.456C114.377 82.456 116.937 81.272 118.857 78.904C120.841 76.472 121.833 73.176 121.833 69.016ZM191.379 91H172.755V84.376C169.875 89.368 165.235 91.864 158.835 91.864C154.739 91.864 151.187 90.648 148.179 88.216C145.171 85.784 143.667 82.008 143.667 76.888V57.016H137.907V47.704H156.051V72.088C156.051 75.864 156.659 78.552 157.875 80.152C159.155 81.688 161.011 82.456 163.443 82.456C166.387 82.456 168.659 81.496 170.259 79.576C171.923 77.656 172.755 75.192 172.755 72.184V57.016H165.747V47.704H185.139V81.688H191.379V91ZM222.863 47.128C224.079 47.128 225.423 47.32 226.895 47.704C228.431 48.024 229.935 48.632 231.407 49.528L233.327 64.696L223.919 65.752L222.287 58.36C221.007 57.592 219.887 57.208 218.927 57.208C217.519 57.208 216.271 57.752 215.183 58.84C214.159 59.928 213.647 61.528 213.647 63.64V81.688H221.327V91H195.503V81.688H201.263V57.112H195.023V47.704H212.687V55.96C213.391 53.464 214.511 51.384 216.047 49.72C217.647 47.992 219.919 47.128 222.863 47.128Z" fill="#004887"/>
++<path d="M37.568 124.032C36.0747 125.44 33.9413 126.571 31.168 127.424C28.4373 128.235 25.6 128.64 22.656 128.64C16.64 128.64 11.6693 126.699 7.744 122.816C3.86133 118.891 1.92 113.856 1.92 107.712C1.92 104.256 2.64533 100.843 4.096 97.472C5.54667 94.1013 7.808 91.3067 10.88 89.088C13.952 86.8693 17.8773 85.76 22.656 85.76C26.1547 85.76 29.1413 86.2507 31.616 87.232C34.0907 88.2133 36.0533 89.3653 37.504 90.688L38.592 99.712L32.768 100.288L31.744 94.528C29.184 92.864 26.112 92.032 22.528 92.032C18.6027 92.032 15.4453 93.3973 13.056 96.128C10.7093 98.8587 9.536 102.592 9.536 107.328C9.536 112.277 10.7947 116.032 13.312 118.592C15.8293 121.109 19.136 122.368 23.232 122.368C26.6453 122.368 29.44 121.771 31.616 120.576L32.64 114.368L38.464 114.944L37.568 124.032ZM72.802 113.664C72.802 118.144 71.3727 121.771 68.514 124.544C65.698 127.275 62.0287 128.64 57.506 128.64C53.1113 128.64 49.57 127.317 46.882 124.672C44.2367 122.027 42.914 118.443 42.914 113.92C42.914 109.739 44.1727 106.155 46.69 103.168C49.2073 100.139 52.9407 98.624 57.89 98.624C62.882 98.624 66.6153 100.117 69.09 103.104C71.5647 106.091 72.802 109.611 72.802 113.664ZM65.698 113.472C65.698 110.4 64.9513 108.053 63.458 106.432C62.0073 104.811 60.1087 104 57.762 104C55.33 104 53.4313 104.875 52.066 106.624C50.7007 108.331 50.018 110.635 50.018 113.536C50.018 116.267 50.658 118.571 51.938 120.448C53.2607 122.325 55.202 123.264 57.762 123.264C60.2367 123.264 62.178 122.368 63.586 120.576C64.994 118.741 65.698 116.373 65.698 113.472ZM129.478 128H116.806V122.752H118.406V111.488C118.406 108.757 117.915 106.837 116.934 105.728C115.995 104.576 114.651 104 112.902 104C110.64 104 108.976 104.768 107.91 106.304C106.886 107.84 106.352 109.589 106.31 111.552V122.752H110.597V128H97.9255V122.752H99.4615V111.488C99.4615 108.757 98.9708 106.837 97.9895 105.728C97.0508 104.576 95.7282 104 94.0215 104C91.8028 104 90.1602 104.768 89.0935 106.304C88.0268 107.797 87.4722 109.525 87.4295 111.488V122.752H92.8055V128H76.2935V122.752H80.5815V104.576H76.3575V99.264H87.4295V104C88.3255 102.421 89.5202 101.141 91.0135 100.16C92.5068 99.1787 94.3202 98.688 96.4535 98.688C98.5868 98.688 100.507 99.2213 102.214 100.288C103.92 101.312 105.115 102.933 105.798 105.152C106.651 103.189 107.888 101.632 109.51 100.48C111.131 99.2853 113.115 98.688 115.462 98.688C118.064 98.688 120.347 99.52 122.31 101.184C124.272 102.848 125.254 105.451 125.254 108.992V122.752H129.478V128ZM164.428 112.896C164.428 116.992 163.34 120.64 161.164 123.84C159.03 127.04 155.724 128.64 151.244 128.64C147.105 128.64 144.097 127.147 142.22 124.16V136.256H147.916V141.632H131.084V136.256H135.372V104.512H130.892V99.264H142.22V104.96C143.03 103.253 144.204 101.781 145.74 100.544C147.318 99.3067 149.43 98.688 152.076 98.688C155.745 98.688 158.71 99.9467 160.972 102.464C163.276 104.939 164.428 108.416 164.428 112.896ZM157.324 113.6C157.324 110.528 156.62 108.203 155.212 106.624C153.804 105.003 152.012 104.192 149.836 104.192C147.532 104.192 145.718 105.067 144.396 106.816C143.073 108.565 142.369 110.613 142.284 112.96L142.22 115.2C142.22 117.589 142.902 119.509 144.268 120.96C145.676 122.411 147.468 123.136 149.644 123.136C152.076 123.136 153.953 122.283 155.276 120.576C156.641 118.869 157.324 116.544 157.324 113.6ZM170.922 101.376C173.055 100.352 174.954 99.648 176.618 99.264C178.282 98.88 180.202 98.688 182.378 98.688C185.578 98.688 188.202 99.4987 190.25 101.12C192.341 102.741 193.386 105.173 193.386 108.416V121.344C193.386 123.051 194.09 123.904 195.498 123.904C195.882 123.904 196.373 123.819 196.97 123.648L197.034 127.424C195.626 128.235 194.09 128.64 192.426 128.64C188.799 128.64 186.837 126.741 186.538 122.944V122.816C185.685 124.309 184.469 125.653 182.89 126.848C181.354 128.043 179.434 128.64 177.13 128.64C175.125 128.64 173.141 128.043 171.178 126.848C169.258 125.611 168.298 123.477 168.298 120.448C168.298 116.907 169.706 114.581 172.522 113.472C175.338 112.32 178.389 111.744 181.674 111.744C182.485 111.744 183.317 111.765 184.17 111.808C185.023 111.851 185.813 111.915 186.538 112V110.4C186.538 108.693 186.239 107.157 185.642 105.792C185.045 104.427 183.551 103.744 181.162 103.744C180.266 103.744 179.413 103.808 178.602 103.936C177.834 104.064 177.087 104.32 176.362 104.704L175.21 109.12L169.706 108.544L170.922 101.376ZM186.538 116.608V115.584C185.813 115.499 185.066 115.413 184.298 115.328C183.53 115.243 182.741 115.2 181.93 115.2C180.223 115.2 178.687 115.499 177.322 116.096C175.999 116.693 175.338 117.888 175.338 119.68C175.338 122.283 176.725 123.584 179.498 123.584C181.119 123.584 182.655 123.008 184.106 121.856C185.557 120.661 186.367 118.912 186.538 116.608ZM234.863 128H219.503V122.752H223.727V111.488C223.727 108.757 223.236 106.837 222.255 105.728C221.273 104.576 219.908 104 218.159 104C215.983 104 214.255 104.704 212.975 106.112C211.737 107.52 211.097 109.248 211.055 111.296V122.752H215.343V128H199.919V122.752H204.207V104.576H199.727V99.264H211.055V103.936C213.06 100.437 216.239 98.688 220.591 98.688C223.321 98.688 225.668 99.52 227.631 101.184C229.593 102.848 230.575 105.451 230.575 108.992V122.752H234.863V128ZM267.085 104.512H264.077L254.477 128L251.277 136.256H255.501V141.632H240.141V136.256H245.005L247.821 128.256L237.645 104.512H234.509V99.264H248.653V104.512H245.005L251.661 120.064H252.045L257.421 104.512H254.157V99.264H267.085V104.512ZM275.625 98.688L270.121 98.176L271.145 89.152C273.15 88.0427 275.22 87.2107 277.353 86.656C279.486 86.1013 281.449 85.824 283.241 85.824C286.825 85.824 289.812 86.6347 292.201 88.256C294.633 89.8347 295.849 92.032 295.849 94.848C295.849 97.024 295.209 98.7947 293.929 100.16C292.649 101.483 291.177 102.592 289.513 103.488C287.892 104.384 286.441 105.237 285.161 106.048C283.881 106.859 283.241 107.84 283.241 108.992C283.241 110.4 284.201 111.104 286.121 111.104V115.456C279.252 116.139 275.817 114.24 275.817 109.76C275.817 107.755 276.436 106.197 277.673 105.088C278.91 103.936 280.34 102.976 281.961 102.208C283.582 101.44 285.012 100.608 286.249 99.712C287.486 98.7733 288.105 97.536 288.105 96C288.105 93.3547 286.206 92.032 282.409 92.032C281.428 92.032 280.382 92.16 279.273 92.416C278.206 92.672 277.289 93.056 276.521 93.568L275.625 98.688ZM277.673 128V119.872H285.865V128H277.673Z" fill="#004887"/>
++</svg>
--- /dev/null
--- /dev/null
++<svg viewBox="0 0 298 144" fill="none" xmlns="http://www.w3.org/2000/svg">
++<path d="M92.056 39.544H86.68L68.536 66.616V80.056H78.712V91H46.072V80.056H55.672V66.52L36.952 39.544H31.384V28.6H57.208V39.544H52.024L62.488 55.288H63.064L73.432 39.544H67.48V28.6H92.056V39.544ZM134.601 69.4C134.601 76.248 132.361 81.72 127.881 85.816C123.401 89.912 117.705 91.96 110.793 91.96C104.137 91.96 98.6965 90.04 94.4725 86.2C90.3125 82.296 88.2325 76.856 88.2325 69.88C88.2325 63.544 90.1525 58.104 93.9925 53.56C97.8325 49.016 103.657 46.744 111.465 46.744C119.273 46.744 125.065 49.016 128.841 53.56C132.681 58.04 134.601 63.32 134.601 69.4ZM121.833 69.016C121.833 64.6 120.809 61.368 118.761 59.32C116.713 57.272 114.217 56.248 111.273 56.248C108.073 56.248 105.545 57.4 103.689 59.704C101.897 61.944 101.001 65.112 101.001 69.208C101.001 72.92 101.833 76.056 103.497 78.616C105.225 81.176 107.785 82.456 111.177 82.456C114.377 82.456 116.937 81.272 118.857 78.904C120.841 76.472 121.833 73.176 121.833 69.016ZM191.379 91H172.755V84.376C169.875 89.368 165.235 91.864 158.835 91.864C154.739 91.864 151.187 90.648 148.179 88.216C145.171 85.784 143.667 82.008 143.667 76.888V57.016H137.907V47.704H156.051V72.088C156.051 75.864 156.659 78.552 157.875 80.152C159.155 81.688 161.011 82.456 163.443 82.456C166.387 82.456 168.659 81.496 170.259 79.576C171.923 77.656 172.755 75.192 172.755 72.184V57.016H165.747V47.704H185.139V81.688H191.379V91ZM222.863 47.128C224.079 47.128 225.423 47.32 226.895 47.704C228.431 48.024 229.935 48.632 231.407 49.528L233.327 64.696L223.919 65.752L222.287 58.36C221.007 57.592 219.887 57.208 218.927 57.208C217.519 57.208 216.271 57.752 215.183 58.84C214.159 59.928 213.647 61.528 213.647 63.64V81.688H221.327V91H195.503V81.688H201.263V57.112H195.023V47.704H212.687V55.96C213.391 53.464 214.511 51.384 216.047 49.72C217.647 47.992 219.919 47.128 222.863 47.128Z" fill="white"/>
++<path d="M37.568 124.032C36.0747 125.44 33.9413 126.571 31.168 127.424C28.4373 128.235 25.6 128.64 22.656 128.64C16.64 128.64 11.6693 126.699 7.744 122.816C3.86133 118.891 1.92 113.856 1.92 107.712C1.92 104.256 2.64533 100.843 4.096 97.472C5.54667 94.1013 7.808 91.3067 10.88 89.088C13.952 86.8693 17.8773 85.76 22.656 85.76C26.1547 85.76 29.1413 86.2507 31.616 87.232C34.0907 88.2133 36.0533 89.3653 37.504 90.688L38.592 99.712L32.768 100.288L31.744 94.528C29.184 92.864 26.112 92.032 22.528 92.032C18.6027 92.032 15.4453 93.3973 13.056 96.128C10.7093 98.8587 9.536 102.592 9.536 107.328C9.536 112.277 10.7947 116.032 13.312 118.592C15.8293 121.109 19.136 122.368 23.232 122.368C26.6453 122.368 29.44 121.771 31.616 120.576L32.64 114.368L38.464 114.944L37.568 124.032ZM72.802 113.664C72.802 118.144 71.3727 121.771 68.514 124.544C65.698 127.275 62.0287 128.64 57.506 128.64C53.1113 128.64 49.57 127.317 46.882 124.672C44.2367 122.027 42.914 118.443 42.914 113.92C42.914 109.739 44.1727 106.155 46.69 103.168C49.2073 100.139 52.9407 98.624 57.89 98.624C62.882 98.624 66.6153 100.117 69.09 103.104C71.5647 106.091 72.802 109.611 72.802 113.664ZM65.698 113.472C65.698 110.4 64.9513 108.053 63.458 106.432C62.0073 104.811 60.1087 104 57.762 104C55.33 104 53.4313 104.875 52.066 106.624C50.7007 108.331 50.018 110.635 50.018 113.536C50.018 116.267 50.658 118.571 51.938 120.448C53.2607 122.325 55.202 123.264 57.762 123.264C60.2367 123.264 62.178 122.368 63.586 120.576C64.994 118.741 65.698 116.373 65.698 113.472ZM129.478 128H116.806V122.752H118.406V111.488C118.406 108.757 117.915 106.837 116.934 105.728C115.995 104.576 114.651 104 112.902 104C110.64 104 108.976 104.768 107.91 106.304C106.886 107.84 106.352 109.589 106.31 111.552V122.752H110.597V128H97.9255V122.752H99.4615V111.488C99.4615 108.757 98.9708 106.837 97.9895 105.728C97.0508 104.576 95.7282 104 94.0215 104C91.8028 104 90.1602 104.768 89.0935 106.304C88.0268 107.797 87.4722 109.525 87.4295 111.488V122.752H92.8055V128H76.2935V122.752H80.5815V104.576H76.3575V99.264H87.4295V104C88.3255 102.421 89.5202 101.141 91.0135 100.16C92.5068 99.1787 94.3202 98.688 96.4535 98.688C98.5868 98.688 100.507 99.2213 102.214 100.288C103.92 101.312 105.115 102.933 105.798 105.152C106.651 103.189 107.888 101.632 109.51 100.48C111.131 99.2853 113.115 98.688 115.462 98.688C118.064 98.688 120.347 99.52 122.31 101.184C124.272 102.848 125.254 105.451 125.254 108.992V122.752H129.478V128ZM164.428 112.896C164.428 116.992 163.34 120.64 161.164 123.84C159.03 127.04 155.724 128.64 151.244 128.64C147.105 128.64 144.097 127.147 142.22 124.16V136.256H147.916V141.632H131.084V136.256H135.372V104.512H130.892V99.264H142.22V104.96C143.03 103.253 144.204 101.781 145.74 100.544C147.318 99.3067 149.43 98.688 152.076 98.688C155.745 98.688 158.71 99.9467 160.972 102.464C163.276 104.939 164.428 108.416 164.428 112.896ZM157.324 113.6C157.324 110.528 156.62 108.203 155.212 106.624C153.804 105.003 152.012 104.192 149.836 104.192C147.532 104.192 145.718 105.067 144.396 106.816C143.073 108.565 142.369 110.613 142.284 112.96L142.22 115.2C142.22 117.589 142.902 119.509 144.268 120.96C145.676 122.411 147.468 123.136 149.644 123.136C152.076 123.136 153.953 122.283 155.276 120.576C156.641 118.869 157.324 116.544 157.324 113.6ZM170.922 101.376C173.055 100.352 174.954 99.648 176.618 99.264C178.282 98.88 180.202 98.688 182.378 98.688C185.578 98.688 188.202 99.4987 190.25 101.12C192.341 102.741 193.386 105.173 193.386 108.416V121.344C193.386 123.051 194.09 123.904 195.498 123.904C195.882 123.904 196.373 123.819 196.97 123.648L197.034 127.424C195.626 128.235 194.09 128.64 192.426 128.64C188.799 128.64 186.837 126.741 186.538 122.944V122.816C185.685 124.309 184.469 125.653 182.89 126.848C181.354 128.043 179.434 128.64 177.13 128.64C175.125 128.64 173.141 128.043 171.178 126.848C169.258 125.611 168.298 123.477 168.298 120.448C168.298 116.907 169.706 114.581 172.522 113.472C175.338 112.32 178.389 111.744 181.674 111.744C182.485 111.744 183.317 111.765 184.17 111.808C185.023 111.851 185.813 111.915 186.538 112V110.4C186.538 108.693 186.239 107.157 185.642 105.792C185.045 104.427 183.551 103.744 181.162 103.744C180.266 103.744 179.413 103.808 178.602 103.936C177.834 104.064 177.087 104.32 176.362 104.704L175.21 109.12L169.706 108.544L170.922 101.376ZM186.538 116.608V115.584C185.813 115.499 185.066 115.413 184.298 115.328C183.53 115.243 182.741 115.2 181.93 115.2C180.223 115.2 178.687 115.499 177.322 116.096C175.999 116.693 175.338 117.888 175.338 119.68C175.338 122.283 176.725 123.584 179.498 123.584C181.119 123.584 182.655 123.008 184.106 121.856C185.557 120.661 186.367 118.912 186.538 116.608ZM234.863 128H219.503V122.752H223.727V111.488C223.727 108.757 223.236 106.837 222.255 105.728C221.273 104.576 219.908 104 218.159 104C215.983 104 214.255 104.704 212.975 106.112C211.737 107.52 211.097 109.248 211.055 111.296V122.752H215.343V128H199.919V122.752H204.207V104.576H199.727V99.264H211.055V103.936C213.06 100.437 216.239 98.688 220.591 98.688C223.321 98.688 225.668 99.52 227.631 101.184C229.593 102.848 230.575 105.451 230.575 108.992V122.752H234.863V128ZM267.085 104.512H264.077L254.477 128L251.277 136.256H255.501V141.632H240.141V136.256H245.005L247.821 128.256L237.645 104.512H234.509V99.264H248.653V104.512H245.005L251.661 120.064H252.045L257.421 104.512H254.157V99.264H267.085V104.512ZM275.625 98.688L270.121 98.176L271.145 89.152C273.15 88.0427 275.22 87.2107 277.353 86.656C279.486 86.1013 281.449 85.824 283.241 85.824C286.825 85.824 289.812 86.6347 292.201 88.256C294.633 89.8347 295.849 92.032 295.849 94.848C295.849 97.024 295.209 98.7947 293.929 100.16C292.649 101.483 291.177 102.592 289.513 103.488C287.892 104.384 286.441 105.237 285.161 106.048C283.881 106.859 283.241 107.84 283.241 108.992C283.241 110.4 284.201 111.104 286.121 111.104V115.456C279.252 116.139 275.817 114.24 275.817 109.76C275.817 107.755 276.436 106.197 277.673 105.088C278.91 103.936 280.34 102.976 281.961 102.208C283.582 101.44 285.012 100.608 286.249 99.712C287.486 98.7733 288.105 97.536 288.105 96C288.105 93.3547 286.206 92.032 282.409 92.032C281.428 92.032 280.382 92.16 279.273 92.416C278.206 92.672 277.289 93.056 276.521 93.568L275.625 98.688ZM277.673 128V119.872H285.865V128H277.673Z" fill="white"/>
++</svg>
--- /dev/null
--- /dev/null
++var debug = 0 ? console.log.bind(console, '[explorer]') : function () {};
++
++// This is cureently not used, but kept in case I change my mind.
++export const explorer = (Alpine) => ({
++ uiState: {
++ containerScrollTop: -1,
++ lastActiveRef: '',
++ },
++ treeState: {
++ // The href of the current page.
++ currentNode: '',
++ // The state of each node in the tree.
++ nodes: {},
++
++ // We currently only list the sections, not regular pages, in the side bar.
++ // This strikes me as the right balance. The pages gets listed on the section pages.
++ // This array is sorted by length, so we can find the longest prefix of the current page
++ // without having to iterate over all the keys.
++ nodeRefsByLength: [],
++ },
++ async init() {
++ let keys = Reflect.ownKeys(this.$refs);
++ for (let key of keys) {
++ let n = {
++ open: false,
++ active: false,
++ };
++ this.treeState.nodes[key] = n;
++ this.treeState.nodeRefsByLength.push(key);
++ }
++
++ this.treeState.nodeRefsByLength.sort((a, b) => b.length - a.length);
++
++ this.setCurrentActive();
++ },
++
++ longestPrefix(ref) {
++ let longestPrefix = '';
++ for (let key of this.treeState.nodeRefsByLength) {
++ if (ref.startsWith(key)) {
++ longestPrefix = key;
++ break;
++ }
++ }
++ return longestPrefix;
++ },
++
++ setCurrentActive() {
++ let ref = this.longestPrefix(window.location.pathname);
++ let activeChanged = this.uiState.lastActiveRef !== ref;
++ debug('setCurrentActive', this.uiState.lastActiveRef, window.location.pathname, '=>', ref, activeChanged);
++ this.uiState.lastActiveRef = ref;
++ if (this.uiState.containerScrollTop === -1 && activeChanged) {
++ // Navigation outside of the explorer menu.
++ let el = document.querySelector(`[x-ref="${ref}"]`);
++ if (el) {
++ this.$nextTick(() => {
++ debug('scrolling to', ref);
++ el.scrollIntoView({ behavior: 'smooth', block: 'center' });
++ });
++ }
++ }
++ this.treeState.currentNode = ref;
++ for (let key in this.treeState.nodes) {
++ let n = this.treeState.nodes[key];
++ n.active = false;
++ n.open = ref == key || ref.startsWith(key);
++ if (n.open) {
++ debug('open', key);
++ }
++ }
++
++ let n = this.treeState.nodes[this.longestPrefix(ref)];
++ if (n) {
++ n.active = true;
++ }
++ },
++
++ getScrollingContainer() {
++ return document.getElementById('leftsidebar');
++ },
++
++ onLoad() {
++ debug('onLoad', this.uiState.containerScrollTop);
++ if (this.uiState.containerScrollTop >= 0) {
++ debug('onLoad: scrolling to', this.uiState.containerScrollTop);
++ this.getScrollingContainer().scrollTo(0, this.uiState.containerScrollTop);
++ }
++ this.uiState.containerScrollTop = -1;
++ },
++
++ onBeforeRender() {
++ debug('onBeforeRender', this.uiState.containerScrollTop);
++ this.setCurrentActive();
++ },
++
++ toggleNode(ref) {
++ this.uiState.containerScrollTop = this.getScrollingContainer().scrollTop;
++ this.uiState.lastActiveRef = '';
++ debug('toggleNode', ref, this.uiState.containerScrollTop);
++
++ let node = this.treeState.nodes[ref];
++ if (!node) {
++ debug('node not found', ref);
++ return;
++ }
++ let wasOpen = node.open;
++ },
++
++ isCurrent(ref) {
++ let n = this.treeState.nodes[ref];
++ return n && n.active;
++ },
++
++ isOpen(ref) {
++ let node = this.treeState.nodes[ref];
++ if (!node) return false;
++ if (node.open) {
++ debug('isOpen', ref);
++ }
++ return node.open;
++ },
++});
--- /dev/null
--- /dev/null
++export * from './navbar';
++export * from './search';
++export * from './toc';
--- /dev/null
--- /dev/null
++export const navbar = (Alpine) => ({
++ init: function () {
++ Alpine.bind(this.$root, this.root);
++ },
++ root: {
++ ['@scroll.window.debounce.10ms'](event) {
++ this.$store.nav.scroll.atTop = window.scrollY < 40 ? true : false;
++ },
++ },
++});
--- /dev/null
--- /dev/null
++const designMode = false;
++
++const groupByLvl0 = (array) => {
++ if (!array) return [];
++ return array.reduce((result, currentValue) => {
++ (result[currentValue.hierarchy.lvl0] = result[currentValue.hierarchy.lvl0] || []).push(currentValue);
++ return result;
++ }, {});
++};
++
++const applyHelperFuncs = (array) => {
++ if (!array) return [];
++ return array.map((item) => {
++ item.getHeadingHTML = function () {
++ let lvl2 = this._highlightResult.hierarchy.lvl2;
++ let lvl3 = this._highlightResult.hierarchy.lvl3;
++
++ if (!lvl3) {
++ if (lvl2) {
++ return lvl2.value;
++ }
++ return '';
++ }
++
++ if (!lvl2) {
++ return lvl3.value;
++ }
++
++ return `${lvl2.value} <span class="text-gray-500"> > </span> ${lvl3.value}`;
++ };
++ return item;
++ });
++};
++
++export const search = (Alpine, cfg) => ({
++ query: designMode ? 'shortcodes' : '',
++ open: designMode,
++ result: {},
++
++ init() {
++ Alpine.bind(this.$root, this.root);
++
++ this.checkOpen();
++ return this.$nextTick(() => {
++ this.$watch('query', () => {
++ this.search();
++ });
++ });
++ },
++ toggleOpen: function () {
++ this.open = !this.open;
++ this.checkOpen();
++ },
++ checkOpen: function () {
++ if (!this.open) {
++ return;
++ }
++ this.search();
++ this.$nextTick(() => {
++ this.$refs.input.focus();
++ });
++ },
++
++ search: function () {
++ if (!this.query) {
++ this.result = {};
++ return;
++ }
++ var queries = {
++ requests: [
++ {
++ indexName: cfg.index,
++ params: `query=${encodeURIComponent(this.query)}`,
++ attributesToHighlight: ['hierarchy', 'content'],
++ attributesToRetrieve: ['hierarchy', 'url', 'content'],
++ },
++ ],
++ };
++
++ const host = `https://${cfg.app_id}-dsn.algolia.net`;
++ const url = `${host}/1/indexes/*/queries`;
++
++ fetch(url, {
++ method: 'POST',
++ headers: {
++ 'X-Algolia-Application-Id': cfg.app_id,
++ 'X-Algolia-API-Key': cfg.api_key,
++ },
++ body: JSON.stringify(queries),
++ })
++ .then((response) => response.json())
++ .then((data) => {
++ this.result = groupByLvl0(applyHelperFuncs(data.results[0].hits));
++ });
++ },
++ root: {
++ ['@click']() {
++ if (!this.open) {
++ this.toggleOpen();
++ }
++ },
++ ['@search-toggle.window']() {
++ this.toggleOpen();
++ },
++ ['@keydown.meta.k.window.prevent']() {
++ this.toggleOpen();
++ },
++ },
++});
--- /dev/null
--- /dev/null
++var debug = 0 ? console.log.bind(console, '[toc]') : function () {};
++
++export const toc = (Alpine) => ({
++ contentScrollSpy: null,
++ activeHeading: '',
++ justClicked: false,
++
++ setActive(id) {
++ debug('setActive', id);
++ this.activeHeading = id;
++ // Prevent the intersection observer from changing the active heading right away.
++ this.justClicked = true;
++ setTimeout(() => {
++ this.justClicked = false;
++ }, 200);
++ },
++
++ init() {
++ this.$watch('$store.nav.scroll.atTop', (value) => {
++ if (!value) return;
++ this.activeHeading = '';
++ this.$root.scrollTop = 0;
++ });
++
++ return this.$nextTick(() => {
++ let contentEl = document.getElementById('content');
++ if (contentEl) {
++ const handleIntersect = (entries) => {
++ if (this.justClicked) {
++ return;
++ }
++ for (let entry of entries) {
++ if (entry.isIntersecting) {
++ let id = entry.target.id;
++ this.activeHeading = id;
++ let liEl = this.$refs[id];
++ if (liEl) {
++ // If liEl is not in the viewport, scroll it into view.
++ let bounding = liEl.getBoundingClientRect();
++ if (bounding.top < 0 || bounding.bottom > window.innerHeight) {
++ this.$root.scrollTop = liEl.offsetTop - 100;
++ }
++ }
++ debug('intersecting', id);
++ break;
++ }
++ }
++ };
++
++ let opts = {
++ rootMargin: '0px 0px -75%',
++ threshold: 0.75,
++ };
++
++ this.contentScrollSpy = new IntersectionObserver(handleIntersect, opts);
++ // Observe all headings.
++ let headings = contentEl.querySelectorAll('h2, h3, h4, h5, h6');
++ for (let heading of headings) {
++ this.contentScrollSpy.observe(heading);
++ }
++ }
++ });
++ },
++
++ destroy() {
++ if (this.contentScrollSpy) {
++ debug('disconnecting');
++ this.contentScrollSpy.disconnect();
++ }
++ },
++});
--- /dev/null
--- /dev/null
++'use strict';
++
++export function registerMagics(Alpine) {
++ Alpine.magic('copy', (currentEl) => {
++ return function (el) {
++ if (!el) {
++ el = currentEl;
++ }
++
++ // Select the element to copy.
++ let range = document.createRange();
++ range.selectNode(el);
++ window.getSelection().removeAllRanges();
++ window.getSelection().addRange(range);
++
++ // Remove the selection after some time.
++ setTimeout(() => {
++ window.getSelection().removeAllRanges();
++ }, 500);
++
++ // Trim whitespace.
++ let text = el.textContent.trim();
++
++ navigator.clipboard.writeText(text);
++ };
++ });
++
++ Alpine.magic('isScrollX', (currentEl) => {
++ return function (el) {
++ if (!el) {
++ el = currentEl;
++ }
++ return el.clientWidth < el.scrollWidth;
++ };
++ });
++}
--- /dev/null
--- /dev/null
++export * from './helpers';
--- /dev/null
--- /dev/null
++export * from './nav.js';
--- /dev/null
--- /dev/null
++var debug = 1 ? console.log.bind(console, '[navStore]') : function () {};
++
++var ColorScheme = {
++ System: 1,
++ Light: 2,
++ Dark: 3,
++};
++
++const localStorageUserSettingsKey = 'hugoDocsUserSettings';
++
++export const navStore = (Alpine) => ({
++ init() {
++ // There is no $watch available in Alpine stores,
++ // but this has the same effect.
++ this.userSettings.onColorSchemeChanged = Alpine.effect(() => {
++ if (this.userSettings.settings.colorScheme) {
++ this.userSettings.isDark = isDark(this.userSettings.settings.colorScheme);
++ toggleDarkMode(this.userSettings.isDark);
++ }
++ });
++
++ // Also react to changes in system settings.
++ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
++ this.userSettings.setColorScheme(ColorScheme.System);
++ });
++ },
++
++ destroy() {},
++
++ scroll: {
++ atTop: true,
++ },
++
++ userSettings: {
++ // settings gets persisted between page navigations.
++ settings: Alpine.$persist({
++ // light, dark or system mode.
++ // If not set, we use the OS setting.
++ colorScheme: ColorScheme.System,
++ // Used to show the most relevant tab in config listings etc.
++ configFileType: 'toml',
++ }).as(localStorageUserSettingsKey),
++
++ isDark: false,
++
++ setColorScheme(colorScheme) {
++ this.settings.colorScheme = colorScheme;
++ this.isDark = isDark(colorScheme);
++ },
++
++ toggleColorScheme() {
++ let next = this.settings.colorScheme + 1;
++ if (next > ColorScheme.Dark) {
++ next = ColorScheme.System;
++ }
++ this.setColorScheme(next);
++ },
++ colorScheme() {
++ return this.settings.colorScheme ? this.settings.colorScheme : ColorScheme.System;
++ },
++ },
++});
++
++function isMediaDark() {
++ return window.matchMedia('(prefers-color-scheme: dark)').matches;
++}
++
++function isDark(colorScheme) {
++ if (!colorScheme || colorScheme == ColorScheme.System) {
++ return isMediaDark();
++ }
++
++ return colorScheme == ColorScheme.Dark;
++}
++
++export function initColorScheme() {
++ // The AlpineJS store has not have been initialized yet, so access the
++ // localStorage directly.
++ let settingsJSON = localStorage[localStorageUserSettingsKey];
++ if (settingsJSON) {
++ let settings = JSON.parse(settingsJSON);
++ toggleDarkMode(isDark(settings.colorScheme));
++ return;
++ }
++ toggleDarkMode(isDark(null));
++}
++
++const toggleDarkMode = function (dark) {
++ if (dark) {
++ document.body.classList.add('dark');
++ } else {
++ document.body.classList.remove('dark');
++ }
++};
--- /dev/null
--- /dev/null
++import { initColorScheme } from './alpinejs/stores/index';
++
++(function () {
++ // This allows us to initialize the color scheme before AlpineJS etc. is loaded.
++ initColorScheme();
++})();
--- /dev/null
--- /dev/null
++import { scrollToActive } from 'js/helpers/index';
++
++(function () {
++ // Now we know that the browser has JS enabled.
++ document.documentElement.classList.remove('no-js');
++
++ // Add os-macos class to body if user is using macOS.
++ if (navigator.userAgent.indexOf('Mac') > -1) {
++ document.documentElement.classList.add('os-macos');
++ }
++
++ // Wait for the DOM to be ready.
++ document.addEventListener('DOMContentLoaded', function () {
++ scrollToActive('DOMContentLoaded');
++ });
++})();
--- /dev/null
--- /dev/null
++export function bridgeTurboAndAlpine(Alpine) {
++ document.addEventListener('turbo:before-render', (event) => {
++ event.detail.newBody.querySelectorAll('[data-alpine-generated]').forEach((el) => {
++ if (el.hasAttribute('data-alpine-generated')) {
++ el.removeAttribute('data-alpine-generated');
++ el.remove();
++ }
++ });
++ });
++
++ document.addEventListener('turbo:render', () => {
++ if (document.documentElement.hasAttribute('data-turbo-preview')) {
++ return;
++ }
++
++ document.querySelectorAll('[data-alpine-ignored]').forEach((el) => {
++ el.removeAttribute('x-ignore');
++ el.removeAttribute('data-alpine-ignored');
++ });
++
++ document.body.querySelectorAll('[x-data]').forEach((el) => {
++ if (el.hasAttribute('data-turbo-permanent')) {
++ return;
++ }
++ Alpine.initTree(el);
++ });
++
++ Alpine.startObservingMutations();
++ });
++
++ // Cleanup Alpine state on navigation.
++ document.addEventListener('turbo:before-cache', () => {
++ // This will be restarted in turbo:render.
++ Alpine.stopObservingMutations();
++
++ document.body.querySelectorAll('[data-turbo-permanent]').forEach((el) => {
++ if (!el.hasAttribute('x-ignore')) {
++ el.setAttribute('x-ignore', true);
++ el.setAttribute('data-alpine-ignored', true);
++ }
++ });
++
++ document.body.querySelectorAll('[x-for],[x-if],[x-teleport]').forEach((el) => {
++ if (el.hasAttribute('x-for') && el._x_lookup) {
++ Object.values(el._x_lookup).forEach((el) => el.setAttribute('data-alpine-generated', true));
++ }
++
++ if (el.hasAttribute('x-if') && el._x_currentIfEl) {
++ el._x_currentIfEl.setAttribute('data-alpine-generated', true);
++ }
++
++ if (el.hasAttribute('x-teleport') && el._x_teleport) {
++ el._x_teleport.setAttribute('data-alpine-generated', true);
++ }
++ });
++
++ document.body.querySelectorAll('[x-data]').forEach((el) => {
++ if (!el.hasAttribute('data-turbo-permanent')) {
++ Alpine.destroyTree(el);
++ // Turbo leaks DOM elements via their data-turbo-permanent handling.
++ // That needs to be fixed upstream, but until then.
++ let clone = el.cloneNode(true);
++ el.replaceWith(clone);
++ }
++ });
++ });
++}
--- /dev/null
--- /dev/null
++export const scrollToActive = (when) => {
++ let els = document.querySelectorAll('.scroll-active');
++ if (!els.length) {
++ return;
++ }
++ els.forEach((el) => {
++ // Find scrolling container.
++ let container = el.closest('[data-turbo-preserve-scroll-container]');
++ if (container) {
++ // Avoid scrolling if el is already in view.
++ if (el.offsetTop >= container.scrollTop && el.offsetTop <= container.scrollTop + container.clientHeight) {
++ return;
++ }
++ container.scrollTop = el.offsetTop - container.offsetTop;
++ }
++ });
++};
--- /dev/null
--- /dev/null
++export * from './bridgeTurboAndAlpine';
++export * from './helpers';
--- /dev/null
--- /dev/null
++import Alpine from 'alpinejs';
++import { registerMagics } from './alpinejs/magics/index';
++import { navbar, search, toc } from './alpinejs/data/index';
++import { navStore, initColorScheme } from './alpinejs/stores/index';
++import { bridgeTurboAndAlpine } from './helpers/index';
++import persist from '@alpinejs/persist';
++import focus from '@alpinejs/focus';
++
++var debug = 0 ? console.log.bind(console, '[index]') : function () {};
++
++// Turbolinks init.
++(function () {
++ document.addEventListener('turbo:render', function (e) {
++ // This is also called right after the body start. This is added to prevent flicker on navigation.
++ initColorScheme();
++ });
++})();
++
++// Set up and start Alpine.
++(function () {
++ // Register AlpineJS plugins.
++ {
++ Alpine.plugin(focus);
++ Alpine.plugin(persist);
++ }
++ // Register AlpineJS magics and directives.
++ {
++ // Handles copy to clipboard etc.
++ registerMagics(Alpine);
++ }
++
++ // Register AlpineJS controllers.
++ {
++ // Register AlpineJS data controllers.
++ let searchConfig = {
++ index: 'hugodocs',
++ app_id: 'D1BPLZHGYQ',
++ api_key: '6df94e1e5d55d258c56f60d974d10314',
++ };
++
++ Alpine.data('navbar', () => navbar(Alpine));
++ Alpine.data('search', () => search(Alpine, searchConfig));
++ Alpine.data('toc', () => toc(Alpine));
++ }
++
++ // Register AlpineJS stores.
++ {
++ Alpine.store('nav', navStore(Alpine));
++ }
++
++ // Start AlpineJS.
++ Alpine.start();
++
++ // Start the Turbo-Alpine bridge.
++ bridgeTurboAndAlpine(Alpine);
++
++ {
++ let containerScrollTops = {};
++
++ // To preserve scroll position in scrolling elements on navigation add data-turbo-preserve-scroll-container="somename" to the scrolling container.
++ addEventListener('turbo:click', () => {
++ document.querySelectorAll('[data-turbo-preserve-scroll-container]').forEach((el2) => {
++ containerScrollTops[el2.dataset.turboPreserveScrollContainer] = el2.scrollTop;
++ });
++ });
++
++ addEventListener('turbo:render', () => {
++ document.querySelectorAll('[data-turbo-preserve-scroll-container]').forEach((ele) => {
++ const containerScrollTop = containerScrollTops[ele.dataset.turboPreserveScrollContainer];
++ if (containerScrollTop) {
++ ele.scrollTop = containerScrollTop;
++ } else {
++ let els = ele.querySelectorAll('.scroll-active');
++ if (els.length) {
++ els.forEach((el) => {
++ // Avoid scrolling if el is already in view.
++ if (el.offsetTop >= ele.scrollTop && el.offsetTop <= ele.scrollTop + ele.clientHeight) {
++ return;
++ }
++ ele.scrollTop = el.offsetTop - ele.offsetTop;
++ });
++ }
++ }
++ });
++
++ containerScrollTops = {};
++ });
++ }
++})();
--- /dev/null
--- /dev/null
++import * as Turbo from '@hotwired/turbo';
--- /dev/null
--- /dev/null
++{
++ "compilerOptions": {
++ "baseUrl": ".",
++ "paths": {
++ "*": [
++ "*"
++ ]
++ }
++ }
++}
--- /dev/null
--- /dev/null
++Apache License
++ Version 2.0, January 2004
++ http://www.apache.org/licenses/
++
++ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
++
++ 1. Definitions.
++
++ "License" shall mean the terms and conditions for use, reproduction,
++ and distribution as defined by Sections 1 through 9 of this document.
++
++ "Licensor" shall mean the copyright owner or entity authorized by
++ the copyright owner that is granting the License.
++
++ "Legal Entity" shall mean the union of the acting entity and all
++ other entities that control, are controlled by, or are under common
++ control with that entity. For the purposes of this definition,
++ "control" means (i) the power, direct or indirect, to cause the
++ direction or management of such entity, whether by contract or
++ otherwise, or (ii) ownership of fifty percent (50%) or more of the
++ outstanding shares, or (iii) beneficial ownership of such entity.
++
++ "You" (or "Your") shall mean an individual or Legal Entity
++ exercising permissions granted by this License.
++
++ "Source" form shall mean the preferred form for making modifications,
++ including but not limited to software source code, documentation
++ source, and configuration files.
++
++ "Object" form shall mean any form resulting from mechanical
++ transformation or translation of a Source form, including but
++ not limited to compiled object code, generated documentation,
++ and conversions to other media types.
++
++ "Work" shall mean the work of authorship, whether in Source or
++ Object form, made available under the License, as indicated by a
++ copyright notice that is included in or attached to the work
++ (an example is provided in the Appendix below).
++
++ "Derivative Works" shall mean any work, whether in Source or Object
++ form, that is based on (or derived from) the Work and for which the
++ editorial revisions, annotations, elaborations, or other modifications
++ represent, as a whole, an original work of authorship. For the purposes
++ of this License, Derivative Works shall not include works that remain
++ separable from, or merely link (or bind by name) to the interfaces of,
++ the Work and Derivative Works thereof.
++
++ "Contribution" shall mean any work of authorship, including
++ the original version of the Work and any modifications or additions
++ to that Work or Derivative Works thereof, that is intentionally
++ submitted to Licensor for inclusion in the Work by the copyright owner
++ or by an individual or Legal Entity authorized to submit on behalf of
++ the copyright owner. For the purposes of this definition, "submitted"
++ means any form of electronic, verbal, or written communication sent
++ to the Licensor or its representatives, including but not limited to
++ communication on electronic mailing lists, source code control systems,
++ and issue tracking systems that are managed by, or on behalf of, the
++ Licensor for the purpose of discussing and improving the Work, but
++ excluding communication that is conspicuously marked or otherwise
++ designated in writing by the copyright owner as "Not a Contribution."
++
++ "Contributor" shall mean Licensor and any individual or Legal Entity
++ on behalf of whom a Contribution has been received by Licensor and
++ subsequently incorporated within the Work.
++
++ 2. Grant of Copyright License. Subject to the terms and conditions of
++ this License, each Contributor hereby grants to You a perpetual,
++ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
++ copyright license to reproduce, prepare Derivative Works of,
++ publicly display, publicly perform, sublicense, and distribute the
++ Work and such Derivative Works in Source or Object form.
++
++ 3. Grant of Patent License. Subject to the terms and conditions of
++ this License, each Contributor hereby grants to You a perpetual,
++ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
++ (except as stated in this section) patent license to make, have made,
++ use, offer to sell, sell, import, and otherwise transfer the Work,
++ where such license applies only to those patent claims licensable
++ by such Contributor that are necessarily infringed by their
++ Contribution(s) alone or by combination of their Contribution(s)
++ with the Work to which such Contribution(s) was submitted. If You
++ institute patent litigation against any entity (including a
++ cross-claim or counterclaim in a lawsuit) alleging that the Work
++ or a Contribution incorporated within the Work constitutes direct
++ or contributory patent infringement, then any patent licenses
++ granted to You under this License for that Work shall terminate
++ as of the date such litigation is filed.
++
++ 4. Redistribution. You may reproduce and distribute copies of the
++ Work or Derivative Works thereof in any medium, with or without
++ modifications, and in Source or Object form, provided that You
++ meet the following conditions:
++
++ (a) You must give any other recipients of the Work or
++ Derivative Works a copy of this License; and
++
++ (b) You must cause any modified files to carry prominent notices
++ stating that You changed the files; and
++
++ (c) You must retain, in the Source form of any Derivative Works
++ that You distribute, all copyright, patent, trademark, and
++ attribution notices from the Source form of the Work,
++ excluding those notices that do not pertain to any part of
++ the Derivative Works; and
++
++ (d) If the Work includes a "NOTICE" text file as part of its
++ distribution, then any Derivative Works that You distribute must
++ include a readable copy of the attribution notices contained
++ within such NOTICE file, excluding those notices that do not
++ pertain to any part of the Derivative Works, in at least one
++ of the following places: within a NOTICE text file distributed
++ as part of the Derivative Works; within the Source form or
++ documentation, if provided along with the Derivative Works; or,
++ within a display generated by the Derivative Works, if and
++ wherever such third-party notices normally appear. The contents
++ of the NOTICE file are for informational purposes only and
++ do not modify the License. You may add Your own attribution
++ notices within Derivative Works that You distribute, alongside
++ or as an addendum to the NOTICE text from the Work, provided
++ that such additional attribution notices cannot be construed
++ as modifying the License.
++
++ You may add Your own copyright statement to Your modifications and
++ may provide additional or different license terms and conditions
++ for use, reproduction, or distribution of Your modifications, or
++ for any such Derivative Works as a whole, provided Your use,
++ reproduction, and distribution of the Work otherwise complies with
++ the conditions stated in this License.
++
++ 5. Submission of Contributions. Unless You explicitly state otherwise,
++ any Contribution intentionally submitted for inclusion in the Work
++ by You to the Licensor shall be under the terms and conditions of
++ this License, without any additional terms or conditions.
++ Notwithstanding the above, nothing herein shall supersede or modify
++ the terms of any separate license agreement you may have executed
++ with Licensor regarding such Contributions.
++
++ 6. Trademarks. This License does not grant permission to use the trade
++ names, trademarks, service marks, or product names of the Licensor,
++ except as required for reasonable and customary use in describing the
++ origin of the Work and reproducing the content of the NOTICE file.
++
++ 7. Disclaimer of Warranty. Unless required by applicable law or
++ agreed to in writing, Licensor provides the Work (and each
++ Contributor provides its Contributions) on an "AS IS" BASIS,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ implied, including, without limitation, any warranties or conditions
++ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
++ PARTICULAR PURPOSE. You are solely responsible for determining the
++ appropriateness of using or redistributing the Work and assume any
++ risks associated with Your exercise of permissions under this License.
++
++ 8. Limitation of Liability. In no event and under no legal theory,
++ whether in tort (including negligence), contract, or otherwise,
++ unless required by applicable law (such as deliberate and grossly
++ negligent acts) or agreed to in writing, shall any Contributor be
++ liable to You for damages, including any direct, indirect, special,
++ incidental, or consequential damages of any character arising as a
++ result of this License or out of the use or inability to use the
++ Work (including but not limited to damages for loss of goodwill,
++ work stoppage, computer failure or malfunction, or any and all
++ other commercial damages or losses), even if such Contributor
++ has been advised of the possibility of such damages.
++
++ 9. Accepting Warranty or Additional Liability. While redistributing
++ the Work or Derivative Works thereof, You may choose to offer,
++ and charge a fee for, acceptance of support, warranty, indemnity,
++ or other liability obligations and/or rights consistent with this
++ License. However, in accepting such obligations, You may act only
++ on Your own behalf and on Your sole responsibility, not on behalf
++ of any other Contributor, and only if You agree to indemnify,
++ defend, and hold each Contributor harmless for any liability
++ incurred by, or claims asserted against, such Contributor by reason
++ of your accepting any such warranty or additional liability.
++
++ END OF TERMS AND CONDITIONS
++
++ APPENDIX: How to apply the Apache License to your work.
++
++ To apply the Apache License to your work, attach the following
++ boilerplate notice, with the fields enclosed by brackets "[]"
++ replaced with your own identifying information. (Don't include
++ the brackets!) The text should be enclosed in the appropriate
++ comment syntax for the file format. We also recommend that a
++ file or class name and description of purpose be included on the
++ same "printed page" as the copyright notice for easier
++ identification within third-party archives.
++
++ Copyright [yyyy] [name of copyright owner]
++
++ Licensed under the Apache License, Version 2.0 (the "License");
++ you may not use this file except in compliance with the License.
++ You may obtain a copy of the License at
++
++ http://www.apache.org/licenses/LICENSE-2.0
++
++ Unless required by applicable law or agreed to in writing, software
++ distributed under the License is distributed on an "AS IS" BASIS,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ See the License for the specific language governing permissions and
++ limitations under the License.
--- /dev/null
--- /dev/null
++---
++cascade:
++ _build:
++ list: never
++ publishResources: false
++ render: never
++---
++
++<!--
++Files within this headless branch bundle are Markdown snippets. Each file must contain front matter delimiters, though front matter fields are not required.
++
++Include the rendered content using the "include" shortcode.
++-->
--- /dev/null
--- /dev/null
++---
++_comment: Do not remove front matter.
++---
++
++## Scope
++
++The method or function used to create a scratch pad determines its scope. For example, use the `Store` method on a `Page` object to create a scratch pad scoped to the page.
++
++Scope|Method or function
++:--|:--
++page|[`PAGE.Store`]
++site|[`SITE.Store`]
++global|[`hugo.Store`]
++local|[`collections.NewScratch`]
++shortcode|[`SHORTCODE.Store`]
++
++[`page.store`]: /methods/page/store
++[`site.store`]: /methods/site/store
++[`hugo.store`]: /functions/hugo/store
++[`collections.newscratch`]: functions/collections/newscratch
++[`shortcode.store`]: /methods/shortcode/store
--- /dev/null
--- /dev/null
++---
++# Do not remove front matter.
++---
++
++## Methods
++
++###### Set
++
++Sets the value of the given key.
++
++```go-html-template
++{{ .Store.Set "greeting" "Hello" }}
++```
++
++###### Get
++
++Gets the value of the given key.
++
++```go-html-template
++{{ .Store.Set "greeting" "Hello" }}
++{{ .Store.Get "greeting" }} → Hello
++```
++
++###### Add
++
++Adds the given value to the existing value(s) of the given key.
++
++For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
++
++```go-html-template
++{{ .Store.Set "greeting" "Hello" }}
++{{ .Store.Add "greeting" "Welcome" }}
++{{ .Store.Get "greeting" }} → HelloWelcome
++```
++
++```go-html-template
++{{ .Store.Set "total" 3 }}
++{{ .Store.Add "total" 7 }}
++{{ .Store.Get "total" }} → 10
++```
++
++```go-html-template
++{{ .Store.Set "greetings" (slice "Hello") }}
++{{ .Store.Add "greetings" (slice "Welcome" "Cheers") }}
++{{ .Store.Get "greetings" }} → [Hello Welcome Cheers]
++```
++
++###### SetInMap
++
++Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`.
++
++```go-html-template
++{{ .Store.SetInMap "greetings" "english" "Hello" }}
++{{ .Store.SetInMap "greetings" "french" "Bonjour" }}
++{{ .Store.Get "greetings" }} → map[english:Hello french:Bonjour]
++```
++
++###### DeleteInMap
++
++Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`.
++
++```go-html-template
++{{ .Store.SetInMap "greetings" "english" "Hello" }}
++{{ .Store.SetInMap "greetings" "french" "Bonjour" }}
++{{ .Store.DeleteInMap "greetings" "english" }}
++{{ .Store.Get "greetings" }} → map[french:Bonjour]
++```
++
++###### GetSortedMapValues
++
++Returns an array of values from `key` sorted by `mapKey`.
++
++```go-html-template
++{{ .Store.SetInMap "greetings" "english" "Hello" }}
++{{ .Store.SetInMap "greetings" "french" "Bonjour" }}
++{{ .Store.GetSortedMapValues "greetings" }} → [Hello Bonjour]
++```
++
++###### Delete
++
++Removes the given key.
++
++```go-html-template
++{{ .Store.Set "greeting" "Hello" }}
++{{ .Store.Delete "greeting" }}
++```
--- /dev/null
- linkTitle: In this section
- description: Learn about Hugo and its features, security model, and privacy protections.
+---
+title: About Hugo
++linktitle: About
++description: Learn about Hugo and its features, privacy protections, and security model.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: about-hugo-in-this-section
+ parent: about
+ weight: 10
+weight: 10
+aliases: [/about-hugo/,/docs/]
+---
+
+Learn about Hugo and its features, privacy protections, and security model.
--- /dev/null
- : Configure the behavior of Hugo's embedded templates and shortcodes to facilitate compliance with regional privacy regulations, including the [GDPR] and [CCPA].
+---
+title: Features
+description: Hugo's rich and powerful feature set provides the framework and tools to create static sites that build in seconds, often less.
+categories: [about]
+keywords: []
+menu:
+ docs:
+ parent: about
+ weight: 30
+weight: 30
+toc: true
+---
+
+## Framework
+
+[Multiplatform]
+: Install Hugo's single executable on Linux, macOS, Windows, and more.
+
+[Multilingual]
+: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations.
+
+[Output formats]
+: Render each page of your site to one or more output formats, with granular control by page kind, section, and path. While HTML is the default output format, you can add JSON, RSS, CSV, and more. For example, create a REST API to access content.
+
+[Templates]
+: Create templates using variables, functions, and methods to transform your content, resources, and data into a published page. While HTML templates are the most common, you can create templates for any output format.
+
+[Themes]
+: Reduce development time and cost by using one of the hundreds of themes contributed by the Hugo community. Themes are available for corporate sites, documentation projects, image portfolios, landing pages, personal and professional blogs, resumes, CVs, and more.
+
+[Modules]
+: Reduce development time and cost by creating or importing packaged combinations of archetypes, assets, content, data, templates, translation tables, static files, or configuration settings. A module may serve as the basis for a new site, or to augment an existing site.
+
+[Privacy]
- [CCPA]: https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act
- [Sass processing]: /functions/css/Sass/
- [Caching]: /functions/partials/includecached/
- [CommonMark]: https://spec.commonmark.org/current/
- [Content adapters]: /content-management/content-adapters/
++: Configure your site to help comply with regional privacy regulations.
+
+[Security]
+: Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection. Other protections prevent "shelling out" to arbitrary applications, limit access to specific environment variables, prevent connections to arbitrary remote data sources, and more.
+
+## Content authoring
+
+[Content formats]
+: Create your content using Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, or reStructuredText. Markdown is the default content format, conforming to the [CommonMark] and [GitHub Flavored Markdown] specifications.
+
+[Markdown attributes]
+: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables.
+
+[Markdown extensions]
+: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more.
+
+[Markdown render hooks]
+: Override the conversion of Markdown to HTML when rendering blockquotes, fenced code blocks, headings, images, links, and tables. For example, render every standalone image as an HTML `figure` element.
+
+[Diagrams]
+: Use fenced code blocks and Markdown render hooks to include diagrams in your content.
+
+[Mathematics]
+: Include mathematical equations and expressions in Markdown using LaTeX markup.
+
+[Syntax highlighting]
+: Syntactically highlight code examples using Hugo's embedded syntax highlighter, enabled by default for fenced code blocks in Markdown. The syntax highlighter supports hundreds of code languages and dozens of styles.
+
+[Shortcodes]
+: Use Hugo's embedded shortcodes, or create your own, to insert complex content. For example, use shortcodes to include `audio` and `video` elements, render tables from local or remote data sources, insert snippets from other pages, and more.
+
+## Content management
+
+[Content adapters]
+: Create content adapters to dynamically add content when building your site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
+
+[Taxonomies]
+: Classify content to establish simple or complex logical relationships between pages. For example, create an authors taxonomy, and assign one or more authors to each page. Among other uses, the taxonomy system provides an inverted, weighted index to render a list of related pages, ordered by relevance.
+
+[Data]
+: Augment your content using local or remote data sources including CSV, JSON, TOML, YAML, and XML. For example, create a shortcode to render an HTML table from a remote CSV file.
+
+[Menus]
+: Provide rapid access to content via Hugo's menu system, configured automatically, globally, or on a page-by-page basis. The menu system is a key component of Hugo's multilingual architecture.
+
+[URL management]
+: Serve any page from any path via global configuration or on a page-by-page basis.
+
+## Asset pipelines
+
+[Image processing]
+: Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data.
+
+[JavaScript bundling]
+: Transpile TypeScript and JSX to JavaScript, bundle, tree shake, minify, create source maps, and perform SRI hashing.
+
+[Sass processing]
+: Transpile Sass to CSS, bundle, tree shake, minify, create source maps, perform SRI hashing, and integrate with PostCSS.
+
+[Tailwind CSS processing]
+: Compile Tailwind CSS utility classes into standard CSS, bundle, tree shake, optimize, minify, perform SRI hashing, and integrate with PostCSS.
+
+## Performance
+
+[Caching]
+: Reduce build time and cost by rendering a partial template once then cache the result, either globally or within a given context. For example, cache the result of an asset pipeline to prevent reprocessing on every rendered page.
+
+[Segmentation]
+: Reduce build time and cost by partitioning your sites into segments. For example, render the home page and the "news section" every hour, and render the entire site once a week.
+
+[Minification]
+: Minify HTML, CSS, and JavaScript to reduce file size, bandwidth consumption, and loading times.
+
- [Data]: /content-management/data-sources/
- [Diagrams]: /content-management/diagrams/
- [GDPR]: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation
++[Multilingual]: /content-management/multilingual/
++[Multiplatform]: /installation/
++[Output formats]: /templates/output-formats/
++[Templates]: /templates/introduction/
++[Themes]: https://themes.gohugo.io/
++[Modules]: /hugo-modules/
++[Privacy]: /about/privacy/
++[Security]: /about/security/
++
+[Content formats]: /content-management/formats/
- [Image processing]: /content-management/image-processing/
- [JavaScript bundling]: /functions/js/build/
++[CommonMark]: https://spec.commonmark.org/current/
+[GitHub Flavored Markdown]: https://github.github.com/gfm/
- [Menus]: /content-management/menus/
- [Minification]: /getting-started/configuration/#configure-minify
- [Modules]: /hugo-modules/
- [Multilingual]: /content-management/multilingual/
- [Multiplatform]: /installation/
- [Output formats]: /templates/output-formats/
- [Privacy]: /about/privacy/
- [Security]: /about/security/
- [Segmentation]: /getting-started/configuration/#configure-segments
- [Shortcodes]: /content-management/shortcodes/
+[Markdown attributes]: /content-management/markdown-attributes/
+[Markdown extensions]: /getting-started/configuration-markup/#goldmark-extensions
+[Markdown render hooks]: /render-hooks/introduction/
++[Diagrams]: /content-management/diagrams/
+[Mathematics]: /content-management/mathematics/
- [Tailwind CSS processing]: /functions/css/tailwindcss/
+[Syntax highlighting]: /content-management/syntax-highlighting/
- [Templates]: /templates/introduction/
- [Themes]: https://themes.gohugo.io/
++[Shortcodes]: /content-management/shortcodes/
++
++[Content adapters]: /content-management/content-adapters/
+[Taxonomies]: /content-management/taxonomies/
++[Data]: /content-management/data-sources/
++[Menus]: /content-management/menus/
+[URL management]: /content-management/urls/
++
++[Image processing]: /content-management/image-processing/
++[JavaScript bundling]: /functions/js/build/
++[Sass processing]: /functions/css/Sass/
++[Tailwind CSS processing]: /functions/css/tailwindcss/
++
++[Caching]: /functions/partials/includecached/
++[Segmentation]: /getting-started/configuration/#configure-segments
++[Minification]: /getting-started/configuration/#configure-minify
--- /dev/null
- description: Configure your site to facilitate compliance with regional privacy regulations.
+---
+title: Privacy
+linkTitle: Privacy
- General Data Protection Regulation ([GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation)) is a regulation in EU law on data protection and privacy for all individuals within the European Union and the European Economic Area. It became enforceable on 25 May 2018.
-
- **Hugo is a static site generator. By using Hugo you are already standing on very solid ground. Static HTML files on disk are much easier to reason about compared to server and database driven websites.**
-
- But even static websites can integrate with external services, so from version `0.41`, Hugo provides a **privacy configuration** that covers the relevant built-in templates.
-
- Note that:
-
- * These settings have their defaults setting set to _off_, i.e. how it worked before Hugo `0.41`. You must do your own evaluation of your site and apply the appropriate settings.
- * These settings work with the [embedded templates](/templates/embedded/). Some theme may contain custom templates for embedding services like Google Analytics. In that case these options have no effect.
- * We will continue this work and improve this further in future Hugo versions.
-
- ## All privacy settings
-
- Below are all privacy settings and their default value. These settings need to be put in your site configuration (e.g. `hugo.toml`).
-
- {{< code-toggle file=hugo >}}
- [privacy]
- [privacy.disqus]
- disable = false
- [privacy.googleAnalytics]
- disable = false
- respectDoNotTrack = false
- [privacy.instagram]
- disable = false
- simple = false
- [privacy.vimeo]
- disable = false
- enableDNT = false
- simple = false
- [privacy.x]
- disable = false
- enableDNT = false
- simple = false
- [privacy.youtube]
- disable = false
- privacyEnhanced = false
- {{< /code-toggle >}}
-
- ## Disable all services
-
- An example privacy configuration that disables all the relevant services in Hugo. With this configuration, the other settings will not matter.
-
- {{< code-toggle file=hugo >}}
- [privacy]
- [privacy.disqus]
- disable = true
- [privacy.googleAnalytics]
- disable = true
- [privacy.instagram]
- disable = true
- [privacy.vimeo]
- disable = true
- [privacy.x]
- disable = true
- [privacy.youtube]
- disable = true
- {{< /code-toggle >}}
-
- ## The privacy settings explained
-
- ### GoogleAnalytics
-
- respectDoNotTrack
- : Enabling this will make the GA templates respect the "Do Not Track" HTTP header.
-
- ### Instagram
++description: Configure your site to help comply with regional privacy regulations.
+categories: [about]
+keywords: ["GDPR", "Privacy", "Data Protection"]
+menu:
+ docs:
+ parent: about
+ weight: 40
+weight: 40
+toc: true
+aliases: [/gdpr/,/about/hugo-and-gdpr/]
++toc: true
+---
+
- simple
- : If simple mode is enabled, a static and no-JS version of the Instagram image card will be built. Note that this only supports image cards and the image itself will be fetched from Instagram's servers.
++## Responsibility
+
- **Note:** If you use the _simple mode_ for Instagram and a site styled with Bootstrap 4, you may want to disable the inline styles provided by Hugo:
++Site authors are responsible for ensuring compliance with regional privacy regulations, including but not limited to:
+
- {{< code-toggle file=hugo >}}
- [services]
- [services.instagram]
- disableInlineCSS = true
- {{< /code-toggle >}}
++- GDPR (General Data Protection Regulation): Applies to individuals within the European Union and the European Economic Area.
++- CCPA (California Consumer Privacy Act): Applies to California residents.
++- CPRA (California Privacy Rights Act): Expands upon the CCPA with stronger consumer privacy protections.
++- Virginia Consumer Data Protection Act (CDPA): Applies to businesses that collect, process, or sell the personal data of Virginia residents.
+
- ### X
++Hugo's privacy settings can assist in compliance efforts.
+
- enableDNT
- : Enabling this for the x shortcode, the post and its embedded page on your site are not used for purposes that include personalized suggestions and personalized ads.
++## Embedded templates
+
- simple
- : If simple mode is enabled, a static and no-JS version of a post will be built.
++Hugo provides [embedded templates](g) to simplify site and content creation. Some of these templates interact with external services. For example, the `youtube` shortcode connects with YouTube's servers to embed videos on your site.
+
- **Note:** If you use the _simple mode_ for X, you may want to disable the inline styles provided by Hugo:
++Some of these templates include settings to enhance privacy.
+
- {{< code-toggle file=hugo >}}
- [services]
- [services.x]
- disableInlineCSS = true
- {{< /code-toggle >}}
+
- ### YouTube
++## Configuration
+
- privacyEnhanced
- : When you turn on privacy-enhanced mode, YouTube won’t store information about visitors on your website unless the user plays the embedded video.
++{{% note %}}
++These settings affect the behavior of some of Hugo's embedded templates. These settings may or may not affect the behavior of templates provided by third parties in their modules or themes.
++{{% /note %}}
+
- ### Vimeo
++These are the default privacy settings for Hugo's embedded templates:
+
- enableDNT
- : Enabling this for the vimeo shortcode, the Vimeo player will be blocked from tracking any session data, including all cookies and stats.
++{{< code-toggle config=privacy />}}
+
- simple
- : If simple mode is enabled, the video thumbnail is fetched from Vimeo's servers and it is overlaid with a play button. If the user clicks to play the video, it will open in a new tab directly on Vimeo's website.
++See each template's documentation for a description of its privacy settings:
+
++- [Disqus partial](/templates/embedded/#privacy-disqus)
++- [Google Analytics partial](/templates/embedded/#privacy-google-analytics)
++- [Instagram shortcode](/shortcodes/instagram/#privacy)
++- [Vimeo shortcode](/shortcodes/vimeo/#privacy)
++- [X shortcode](/shortcodes/x/#privacy)
++- [YouTube shortcode](/shortcodes/youtube/#privacy)
--- /dev/null
--- /dev/null
++---
++title: Command line interface
++linkTitle: CLI
++description: Use the command line interface (CLI) to manage your site.
++categories: []
++keywords: []
++menu:
++ docs:
++ parent: commands
++ weight: 10
++weight: 10
++---
--- /dev/null
- * [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
+---
+title: "hugo gen"
+slug: hugo_gen
+url: /commands/hugo_gen/
+---
+## hugo gen
+
+Generate documentation and syntax highlighting styles
+
+### Synopsis
+
+Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages.
+
+### Options
+
+```
+ -h, --help help for gen
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo](/commands/hugo/) - Build your site
+* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter
++* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI
+* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
+
--- /dev/null
- Generate Markdown documentation for the Hugo CLI.
+---
+title: "hugo gen doc"
+slug: hugo_gen_doc
+url: /commands/hugo_gen_doc/
+---
+## hugo gen doc
+
++Generate Markdown documentation for the Hugo CLI
+
+### Synopsis
+
+Generate Markdown documentation for the Hugo CLI.
+ This command is, mostly, used to create up-to-date documentation
+ of Hugo's command-line interface for https://gohugo.io/.
+
+ It creates one Markdown file per command with front matter suitable
+ for rendering in Hugo.
+
+```
+hugo gen doc [flags] [args]
+```
+
+### Options
+
+```
+ --dir string the directory to write the doc. (default "/tmp/hugodoc/")
+ -h, --help help for doc
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
+
--- /dev/null
- * [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project.
- * [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo Project.
- * [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph.
- * [hugo mod init](/commands/hugo_mod_init/) - Initialize this project as a Hugo Module.
- * [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers.
- * [hugo mod tidy](/commands/hugo_mod_tidy/) - Remove unused entries in go.mod and go.sum.
- * [hugo mod vendor](/commands/hugo_mod_vendor/) - Vendor all module dependencies into the _vendor directory.
- * [hugo mod verify](/commands/hugo_mod_verify/) - Verify dependencies.
+---
+title: "hugo mod"
+slug: hugo_mod
+url: /commands/hugo_mod/
+---
+## hugo mod
+
+Manage modules
+
+### Synopsis
+
+Various helpers to help manage the modules in your project's dependency graph.
+Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git).
+This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor".
+
+
+Note that Hugo will always start out by resolving the components defined in the site
+configuration, provided by a _vendor directory (if no --ignoreVendorPaths flag provided),
+Go Modules, or a folder inside the themes directory, in that order.
+
+See https://gohugo.io/hugo-modules/ for more information.
+
+
+
+### Options
+
+```
+ -h, --help help for mod
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo](/commands/hugo/) - Build your site
++* [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project
++* [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo project
++* [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph
++* [hugo mod init](/commands/hugo_mod_init/) - Initialize this project as a Hugo Module
++* [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers
++* [hugo mod tidy](/commands/hugo_mod_tidy/) - Remove unused entries in go.mod and go.sum
++* [hugo mod vendor](/commands/hugo_mod_vendor/) - Vendor all module dependencies into the _vendor directory
++* [hugo mod verify](/commands/hugo_mod_verify/) - Verify dependencies
+
--- /dev/null
- Delete the Hugo Module cache for the current project.
+---
+title: "hugo mod clean"
+slug: hugo_mod_clean
+url: /commands/hugo_mod_clean/
+---
+## hugo mod clean
+
++Delete the Hugo Module cache for the current project
+
+### Synopsis
+
+Delete the Hugo Module cache for the current project.
+
+```
+hugo mod clean [flags] [args]
+```
+
+### Options
+
+```
+ --all clean entire module cache
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for clean
+ --pattern string pattern matching module paths to clean (all if not set), e.g. "**hugo*"
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Resolves dependencies in your current Hugo Project.
+---
+title: "hugo mod get"
+slug: hugo_mod_get
+url: /commands/hugo_mod_get/
+---
+## hugo mod get
+
- Resolves dependencies in your current Hugo Project.
++Resolves dependencies in your current Hugo project
+
+### Synopsis
+
+
-
++Resolves dependencies in your current Hugo project.
+
+Some examples:
+
+Install the latest version possible for a given module:
+
+ hugo mod get github.com/gohugoio/testshortcodes
++
+Install a specific version:
+
+ hugo mod get github.com/gohugoio/testshortcodes@v0.3.0
+
+Install the latest versions of all direct module dependencies:
+
+ hugo mod get
+ hugo mod get ./... (recursive)
+
+Install the latest versions of all module dependencies (direct and indirect):
+
+ hugo mod get -u
+ hugo mod get -u ./... (recursive)
+
+Run "go help get" for more information. All flags available for "go get" is also relevant here.
+
+Note that Hugo will always start out by resolving the components defined in the site
+configuration, provided by a _vendor directory (if no --ignoreVendorPaths flag provided),
+Go Modules, or a folder inside the themes directory, in that order.
+
+See https://gohugo.io/hugo-modules/ for more information.
+
+
+
+```
+hugo mod get [flags] [args]
+```
+
+### Options
+
+```
+ -h, --help help for get
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Print a module dependency graph.
+---
+title: "hugo mod graph"
+slug: hugo_mod_graph
+url: /commands/hugo_mod_graph/
+---
+## hugo mod graph
+
++Print a module dependency graph
+
+### Synopsis
+
+Print a module dependency graph with information about module status (disabled, vendored).
+Note that for vendored modules, that is the version listed and not the one from go.mod.
+
+
+```
+hugo mod graph [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ --clean delete module cache for dependencies that fail verification
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for graph
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Initialize this project as a Hugo Module.
+---
+title: "hugo mod init"
+slug: hugo_mod_init
+url: /commands/hugo_mod_init/
+---
+## hugo mod init
+
-
++Initialize this project as a Hugo Module
+
+### Synopsis
+
+Initialize this project as a Hugo Module.
+ It will try to guess the module path, but you may help by passing it as an argument, e.g:
-
++
+ hugo mod init github.com/gohugoio/testshortcodes
++
+ Note that Hugo Modules supports multi-module projects, so you can initialize a Hugo Module
+ inside a subfolder on GitHub, as one example.
+
+
+```
+hugo mod init [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for init
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Various npm helpers.
+---
+title: "hugo mod npm"
+slug: hugo_mod_npm
+url: /commands/hugo_mod_npm/
+---
+## hugo mod npm
+
- * [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project.
++Various npm helpers
+
+### Synopsis
+
+Various npm (Node package manager) helpers.
+
+```
+hugo mod npm [command] [flags]
+```
+
+### Options
+
+```
+ -h, --help help for npm
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
++* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project
+
--- /dev/null
- Experimental: Prepares and writes a composite package.json file for your project.
+---
+title: "hugo mod npm pack"
+slug: hugo_mod_npm_pack
+url: /commands/hugo_mod_npm_pack/
+---
+## hugo mod npm pack
+
- with the base dependency set.
++Experimental: Prepares and writes a composite package.json file for your project
+
+### Synopsis
+
+Prepares and writes a composite package.json file for your project.
+
+On first run it creates a "package.hugo.json" in the project root if not already there. This file will be used as a template file
- * [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers.
++with the base dependency set.
+
+This set will be merged with all "package.hugo.json" files found in the dependency tree, picking the version closest to the project.
+
+This command is marked as 'Experimental'. We think it's a great idea, so it's not likely to be
+removed from Hugo, but we need to test this out in "real life" to get a feel of it,
+so this may/will change in future versions of Hugo.
+
+
+```
+hugo mod npm pack [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for pack
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
++* [hugo mod npm](/commands/hugo_mod_npm/) - Various npm helpers
+
--- /dev/null
- Remove unused entries in go.mod and go.sum.
+---
+title: "hugo mod tidy"
+slug: hugo_mod_tidy
+url: /commands/hugo_mod_tidy/
+---
+## hugo mod tidy
+
++Remove unused entries in go.mod and go.sum
+
+```
+hugo mod tidy [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for tidy
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Vendor all module dependencies into the _vendor directory.
+---
+title: "hugo mod vendor"
+slug: hugo_mod_vendor
+url: /commands/hugo_mod_vendor/
+---
+## hugo mod vendor
+
++Vendor all module dependencies into the _vendor directory
+
+### Synopsis
+
+Vendor all module dependencies into the _vendor directory.
+ If a module is vendored, that is where Hugo will look for it's dependencies.
+
+
+```
+hugo mod vendor [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for vendor
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- Verify dependencies.
+---
+title: "hugo mod verify"
+slug: hugo_mod_verify
+url: /commands/hugo_mod_verify/
+---
+## hugo mod verify
+
++Verify dependencies
+
+### Synopsis
+
+Verify checks that the dependencies of the current module, which are stored in a local downloaded source cache, have not been modified since being downloaded.
+
+```
+hugo mod verify [flags] [args]
+```
+
+### Options
+
+```
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --cacheDir string filesystem path to cache directory
+ --clean delete module cache for dependencies that fail verification
+ -c, --contentDir string filesystem path to content directory
+ -h, --help help for verify
+ --renderSegments strings named segments to render (configured in the segments config)
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo mod](/commands/hugo_mod/) - Manage modules
+
--- /dev/null
- * [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store.
+---
+title: "hugo server"
+slug: hugo_server
+url: /commands/hugo_server/
+---
+## hugo server
+
+Start the embedded web server
+
+### Synopsis
+
+Hugo provides its own webserver which builds and serves the site.
+While hugo server is high performance, it is a webserver with limited options.
+
+The `hugo server` command will by default write and serve files from disk, but
+you can render to memory by using the `--renderToMemory` flag. This can be
+faster in some cases, but it will consume more memory.
+
+By default hugo will also watch your files for any changes you make and
+automatically rebuild the site. It will then live reload any open browser pages
+and push the latest content to them. As most Hugo sites are built in a fraction
+of a second, you will be able to save and see your changes nearly instantly.
+
+```
+hugo server [command] [flags]
+```
+
+### Options
+
+```
+ --appendPort append port to baseURL (default true)
+ -b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
+ --bind string interface to which the server will bind (default "127.0.0.1")
+ -D, --buildDrafts include content marked as draft
+ -E, --buildExpired include expired content
+ -F, --buildFuture include content with publishdate in the future
+ --cacheDir string filesystem path to cache directory
+ --cleanDestinationDir remove files from destination not found in static directories
+ -c, --contentDir string filesystem path to content directory
+ --disableBrowserError do not show build errors in the browser
+ --disableFastRender enables full re-renders on changes
+ --disableKinds strings disable different kind of pages (home, RSS etc.)
+ --disableLiveReload watch without enabling live browser reload on rebuild
+ --enableGitInfo add Git revision, date, author, and CODEOWNERS info to the pages
+ --forceSyncStatic copy all files when static is changed.
+ --gc enable to run some cleanup tasks (remove unused cache files) after the build
+ -h, --help help for server
+ --ignoreCache ignores the cache directory
+ -l, --layoutDir string filesystem path to layout directory
+ --liveReloadPort int port for live reloading (i.e. 443 in HTTPS proxy situations) (default -1)
+ --minify minify any supported output format (HTML, XML etc.)
+ -N, --navigateToChanged navigate to changed content file on live browser reload
+ --noChmod don't sync permission mode of files
+ --noHTTPCache prevent HTTP caching
+ --noTimes don't sync modification time of files
+ -O, --openBrowser open the site in a browser after server startup
+ --panicOnWarning panic on first WARNING log
+ --poll string set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes
+ -p, --port int port on which the server will listen (default 1313)
+ --pprof enable the pprof server (port 8080)
+ --printI18nWarnings print missing translations
+ --printMemoryUsage print memory usage to screen at intervals
+ --printPathWarnings print warnings on duplicate target paths etc.
+ --printUnusedTemplates print warnings on unused templates.
+ --renderSegments strings named segments to render (configured in the segments config)
+ --renderStaticToDisk serve static files from disk and dynamic files from memory
+ --templateMetrics display metrics about template executions
+ --templateMetricsHints calculate some improvement hints when combined with --templateMetrics
+ -t, --theme strings themes to use (located in /themes/THEMENAME/)
+ --tlsAuto generate and use locally-trusted certificates.
+ --tlsCertFile string path to TLS certificate file
+ --tlsKeyFile string path to TLS key file
+ --trace file write trace to file (not useful in general)
+ -w, --watch watch filesystem for changes and recreate as needed (default true)
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo](/commands/hugo/) - Build your site
++* [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store
+
--- /dev/null
- Install the local CA in the system trust store.
+---
+title: "hugo server trust"
+slug: hugo_server_trust
+url: /commands/hugo_server_trust/
+---
+## hugo server trust
+
++Install the local CA in the system trust store
+
+```
+hugo server trust [flags] [args]
+```
+
+### Options
+
+```
+ -h, --help help for trust
+ --uninstall Uninstall the local CA (but do not delete it).
+```
+
+### Options inherited from parent commands
+
+```
+ --clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
+ --config string config file (default is hugo.yaml|json|toml)
+ --configDir string config dir (default "config")
+ -d, --destination string filesystem path to write files to
+ -e, --environment string build environment
+ --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
+ --logLevel string log level (debug|info|warn|error)
+ --noBuildLock don't create .hugo_build.lock file
+ --quiet build in quiet mode
+ -M, --renderToMemory render to memory (mostly useful when running the server)
+ -s, --source string filesystem path to read files relative from
+ --themesDir string filesystem path to themes directory
+```
+
+### SEE ALSO
+
+* [hugo server](/commands/hugo_server/) - Start the embedded web server
+
--- /dev/null
- linkTitle: In this section
+---
+title: Content management
++
+description: Hugo makes managing large static sites easy with support for archetypes, content types, menus, cross references, summaries, and more.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: content-management-in-this-section
+ parent: content-management
+ weight: 10
+weight: 10
+aliases: [/content/,/content/organization]
+---
+
+A static site generator needs to extend beyond front matter and a couple of templates to be both scalable and *manageable*. Hugo was designed with not only developers in mind, but also content managers and authors.
--- /dev/null
- : (`hugolib.fileInfo`) Returns file information for the current page. See [details](/methods/page/file).
+---
+title: Archetypes
+description: An archetype is a template for new content.
+categories: [content management]
+keywords: [archetypes,generators,metadata,front matter]
+menu:
+ docs:
+ parent: content-management
+ weight: 140
+ quicklinks:
+weight: 140
+toc: true
+aliases: [/content/archetypes/]
+---
+
+## Overview
+
+A content file consists of [front matter](g) and markup. The markup is typically Markdown, but Hugo also supports other [content formats](g). Front matter can be TOML, YAML, or JSON.
+
+The `hugo new content` command creates a new file in the `content` directory, using an archetype as a template. This is the default archetype:
+
+{{< code-toggle file=archetypes/default.md fm=true >}}
+title = '{{ replace .File.ContentBaseName `-` ` ` | title }}'
+date = '{{ .Date }}'
+draft = true
+{{< /code-toggle >}}
+
+When you create new content, Hugo evaluates the [template actions](g) within the archetype. For example:
+
+```sh
+hugo new content posts/my-first-post.md
+```
+
+With the default archetype shown above, Hugo creates this content file:
+
+{{< code-toggle file=content/posts/my-first-post.md fm=true >}}
+title = 'My First Post'
+date = '2023-08-24T11:49:46-07:00'
+draft = true
+{{< /code-toggle >}}
+
+You can create an archetype for one or more [content types](g). For example, use one archetype for posts, and use the default archetype for everything else:
+
+```text
+archetypes/
+├── default.md
+└── posts.md
+```
+
+## Lookup order
+
+Hugo looks for archetypes in the `archetypes` directory in the root of your project, falling back to the `archetypes` directory in themes or installed modules. An archetype for a specific content type takes precedence over the default archetype.
+
+For example, with this command:
+
+```sh
+hugo new content posts/my-first-post.md
+```
+
+The archetype lookup order is:
+
+1. `archetypes/posts.md`
+1. `archetypes/default.md`
+1. `themes/my-theme/archetypes/posts.md`
+1. `themes/my-theme/archetypes/default.md`
+
+If none of these exists, Hugo uses a built-in default archetype.
+
+## Functions and context
+
+You can use any template [function](g) within an archetype. As shown above, the default archetype uses the [`replace`](/functions/strings/replace) function to replace hyphens with spaces when populating the title in front matter.
+
+Archetypes receive the following [context](g):
+
+Date
+: (`string`) The current date and time, formatted in compliance with RFC3339.
+
+File
- : (`page.Site`) The current site object. See [details](/methods/site/).
++: (`hugolib.fileInfo`) Returns file information for the current page. See [details](/methods/page/file).
+
+Type
+: (`string`) The [content type](g) inferred from the top-level directory name, or as specified by the `--kind` flag passed to the `hugo new content` command.
+
+Site
++: (`page.Site`) The current site object. See [details](/methods/site/).
+
+## Date format
+
+To insert date and time with a different format, use the [`time.Now`] function:
+
+[`time.Now`]: /functions/time/now/
+
+{{< code-toggle file=archetypes/default.md fm=true >}}
+title = '{{ replace .File.ContentBaseName `-` ` ` | title }}'
+date = '{{ time.Now.Format "2006-01-02" }}'
+draft = true
+{{< /code-toggle >}}
+
+## Include content
+
+Although typically used as a front matter template, you can also use an archetype to populate content.
+
+For example, in a documentation site you might have a section (content type) for functions. Every page within this section should follow the same format: a brief description, the function signature, examples, and notes. We can pre-populate the page to remind content authors of the standard format.
+
+{{< code file=archetypes/functions.md >}}
+---
+date: '{{ .Date }}'
+draft: true
+title: '{{ replace .File.ContentBaseName `-` ` ` | title }}'
+---
+
+A brief description of what the function does, using simple present tense in the third person singular form. For example:
+
+`someFunction` returns the string `s` repeated `n` times.
+
+## Signature
+
+```text
+func someFunction(s string, n int) string
+```
+
+## Examples
+
+One or more practical examples, each within a fenced code block.
+
+## Notes
+
+Additional information to clarify as needed.
+{{< /code >}}
+
+Although you can include [template actions](g) within the content body, remember that Hugo evaluates these once---at the time of content creation. In most cases, place template actions in a [template](g) where Hugo evaluates the actions every time you [build](g) the site.
+
+## Leaf bundles
+
+You can also create archetypes for [leaf bundles](g).
+
+For example, in a photography site you might have a section (content type) for galleries. Each gallery is leaf bundle with content and images.
+
+Create an archetype for galleries:
+
+```text
+archetypes/
+├── galleries/
+│ ├── images/
+│ │ └── .gitkeep
+│ └── index.md <-- same format as default.md
+└── default.md
+```
+
+Subdirectories within an archetype must contain at least one file. Without a file, Hugo will not create the subdirectory when you create new content. The name and size of the file are irrelevant. The example above includes a `.gitkeep` file, an empty file commonly used to preserve otherwise empty directories in a Git repository.
+
+To create a new gallery:
+
+```sh
+hugo new galleries/bryce-canyon
+```
+
+This produces:
+
+```text
+content/
+├── galleries/
+│ └── bryce-canyon/
+│ ├── images/
+│ │ └── .gitkeep
+│ └── index.md
+└── _index.md
+```
+
+## Specify archetype
+
+Use the `--kind` command line flag to specify an archetype when creating content.
+
+For example, let's say your site has two sections: articles and tutorials. Create an archetype for each content type:
+
+```text
+archetypes/
+├── articles.md
+├── default.md
+└── tutorials.md
+```
+
+To create an article using the articles archetype:
+
+```sh
+hugo new content articles/something.md
+```
+
+To create an article using the tutorials archetype:
+
+```sh
+hugo new content --kind tutorials articles/something.md
+```
--- /dev/null
- {{< new-in 0.126.0 >}}
+---
+title: Content adapters
+description: Create content adapters to dynamically add content when building your site.
+categories: [content management]
+keywords: []
+menu:
+ docs:
+ parent: content-management
+ weight: 290
+weight: 290
+toc: true
+---
+
++{{< new-in 0.126.0 />}}
+
+## Overview
+
+A content adapter is a template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
+
+Unlike templates that reside in the `layouts` directory, content adapters reside in the `content` directory, no more than one per directory per language. When a content adapter creates a page, the page's [logical path](g) will be relative to the content adapter.
+
+```text
+content/
+├── articles/
+│ ├── _index.md
+│ ├── article-1.md
+│ └── article-2.md
+├── books/
+│ ├── _content.gotmpl <-- content adapter
+│ └── _index.md
+└── films/
+ ├── _content.gotmpl <-- content adapter
+ └── _index.md
+```
+
+Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the `layouts` directory. You can use any of the [template functions] within a content adapter, as well as the methods described below.
+
+## Methods
+
+Use these methods within a content adapter.
+
+###### AddPage
+
+Adds a page to the site.
+
+{{< code file=content/books/_content.gotmpl >}}
+{{ $content := dict
+ "mediaType" "text/markdown"
+ "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
+}}
+{{ $page := dict
+ "content" $content
+ "kind" "page"
+ "path" "the-hunchback-of-notre-dame"
+ "title" "The Hunchback of Notre Dame"
+}}
+{{ .AddPage $page }}
+{{< /code >}}
+
+###### AddResource
+
+Adds a page resource to the site.
+
+{{< code file=content/books/_content.gotmpl >}}
+{{ with resources.Get "images/a.jpg" }}
+ {{ $content := dict
+ "mediaType" .MediaType.Type
+ "value" .
+ }}
+ {{ $resource := dict
+ "content" $content
+ "path" "the-hunchback-of-notre-dame/cover.jpg"
+ }}
+ {{ $.AddResource $resource }}
+{{ end }}
+{{< /code >}}
+
+Then retrieve the new page resource with something like:
+
+{{< code file=layouts/_default/single.html >}}
+{{ with .Resources.Get "cover.jpg" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+{{< /code >}}
+
+###### Site
+
+Returns the `Site` to which the pages will be added.
+
+{{< code file=content/books/_content.gotmpl >}}
+{{ .Site.Title }}
+{{< /code >}}
+
+{{% note %}}
+Note that the `Site` returned isn't fully built when invoked from the content adapters; if you try to call methods that depends on pages, e.g. `.Site.Pages`, you will get an error saying "this method cannot be called before the site is fully initialized".
+{{% /note %}}
+
+###### Store
+
+Returns a persistent “scratch pad” to store and manipulate data. The main use case for this is to transfer values between executions when [EnableAllLanguages](#enablealllanguages) is set. See [examples](/methods/page/store/).
+
+{{< code file=content/books/_content.gotmpl >}}
+{{ .Store.Set "key" "value" }}
+{{ .Store.Get "key" }}
+{{< /code >}}
+
+###### EnableAllLanguages
+
+By default, Hugo executes the content adapter for the language defined by the _content.gotmpl file . Use this method to activate the content adapter for all languages.
+
+{{< code file=content/books/_content.gotmpl >}}
+{{ .EnableAllLanguages }}
+{{ $content := dict
+ "mediaType" "text/markdown"
+ "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
+}}
+{{ $page := dict
+ "content" $content
+ "kind" "page"
+ "path" "the-hunchback-of-notre-dame"
+ "title" "The Hunchback of Notre Dame"
+}}
+{{ .AddPage $page }}
+{{< /code >}}
+
+## Page map
+
+Set any [front matter field] in the map passed to the [`AddPage`](#addpage) method, excluding `markup`. Instead of setting the `markup` field, specify the `content.mediaType` as described below.
+
+This table describes the fields most commonly passed to the `AddPage` method.
+
+Key|Description|Required
+:--|:--|:-:
+`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|
+`content.value`|The content value as a string.|
+`dates.date`|The page creation date as a `time.Time` value.|
+`dates.expiryDate`|The page expiry date as a `time.Time` value.|
+`dates.lastmod`|The page last modification date as a `time.Time` value.|
+`dates.publishDate`|The page publication date as a `time.Time` value.|
+`params`|A map of page parameters.|
+`path`|The page's [logical path](g) relative to the content adapter. Do not include a leading slash or file extension.|:heavy_check_mark:
+`title`|The page title.|
+
+{{% note %}}
+While `path` is the only required field, we recommend setting `title` as well.
+
+When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C` produces a logical path of `/section/a-b-c`.
+{{% /note %}}
+
+## Resource map
+
+Construct the map passed to the [`AddResource`](#addresource) method using the fields below.
+
+Key|Description|Required
+:--|:--|:-:
+`content.mediaType`|The content [media type].|:heavy_check_mark:
+`content.value`|The content value as a string or resource.|:heavy_check_mark:
+`name`|The resource name.|
+`params`|A map of resource parameters.|
+`path`|The resources's [logical path](g) relative to the content adapter. Do not include a leading slash.|:heavy_check_mark:
+`title`|The resource title.|
+
+{{% note %}}
+If the `content.value` is a string Hugo creates a new resource. If the `content.value` is a resource, Hugo obtains the value from the existing resource.
+
+When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C/cover.jpg` produces a logical path of `/section/a-b-c/cover.jpg`.
+{{% /note %}}
+
+## Example
+
+Create pages from remote data, where each page represents a book review.
+
+Step 1
+: Create the content structure.
+
+```text
+content/
+└── books/
+ ├── _content.gotmpl <-- content adapter
+ └── _index.md
+```
+
+Step 2
+: Inspect the remote data to determine how to map key-value pairs to front matter fields.
+
+: <https://gohugo.io/shared/examples/data/books.json>
+
+Step 3
+: Create the content adapter.
+
+{{< code file=content/books/_content.gotmpl copy=true >}}
+{{/* Get remote data. */}}
+{{ $data := dict }}
+{{ $url := "https://gohugo.io/shared/examples/data/books.json" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "Unable to get remote resource %s: %s" $url . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %s" $url }}
+ {{ end }}
+{{ end }}
+
+{{/* Add pages and page resources. */}}
+{{ range $data }}
+
+ {{/* Add page. */}}
+ {{ $content := dict "mediaType" "text/markdown" "value" .summary }}
+ {{ $dates := dict "date" (time.AsTime .date) }}
+ {{ $params := dict "author" .author "isbn" .isbn "rating" .rating "tags" .tags }}
+ {{ $page := dict
+ "content" $content
+ "dates" $dates
+ "kind" "page"
+ "params" $params
+ "path" .title
+ "title" .title
+ }}
+ {{ $.AddPage $page }}
+
+ {{/* Add page resource. */}}
+ {{ $item := . }}
+ {{ with $url := $item.cover }}
+ {{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "Unable to get remote resource %s: %s" $url . }}
+ {{ else with .Value }}
+ {{ $content := dict "mediaType" .MediaType.Type "value" .Content }}
+ {{ $params := dict "alt" $item.title }}
+ {{ $resource := dict
+ "content" $content
+ "params" $params
+ "path" (printf "%s/cover.%s" $item.title .MediaType.SubType)
+ }}
+ {{ $.AddResource $resource }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %s" $url }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+{{ end }}
+{{< /code >}}
+
+Step 4
+: Create a single template to render each book review.
+
+{{< code file=layouts/books/single.html copy=true >}}
+{{ define "main" }}
+ <h1>{{ .Title }}</h1>
+
+ {{ with .Resources.GetMatch "cover.*" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ .Params.alt }}">
+ {{ end }}
+
+ <p>Author: {{ .Params.author }}</p>
+
+ <p>
+ ISBN: {{ .Params.isbn }}<br>
+ Rating: {{ .Params.rating }}<br>
+ Review date: {{ .Date | time.Format ":date_long" }}
+ </p>
+
+ {{ with .GetTerms "tags" }}
+ <p>Tags:</p>
+ <ul>
+ {{ range . }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+ </ul>
+ {{ end }}
+
+ {{ .Content }}
+{{ end }}
+{{< /code >}}
+
+## Multilingual sites
+
+With multilingual sites you can:
+
+1. Create one content adapter for all languages using the [`EnableAllLanguages`](#enablealllanguages) method as described above.
+1. Create content adapters unique to each language. See the examples below.
+
+### Translations by file name
+
+With this site configuration:
+
+{{< code-toggle file=hugo >}}
+[languages.en]
+weight = 1
+
+[languages.de]
+weight = 2
+{{< /code-toggle >}}
+
+Include a language designator in the content adapter's file name.
+
+```text
+content/
+└── books/
+ ├── _content.de.gotmpl
+ ├── _content.en.gotmpl
+ ├── _index.de.md
+ └── _index.en.md
+```
+
+### Translations by content directory
+
+With this site configuration:
+
+{{< code-toggle file=hugo >}}
+[languages.en]
+contentDir = 'content/en'
+weight = 1
+
+[languages.de]
+contentDir = 'content/de'
+weight = 2
+{{< /code-toggle >}}
+
+Create a single content adapter in each directory:
+
+```text
+content/
+├── de/
+│ └── books/
+│ ├── _content.gotmpl
+│ └── _index.md
+└── en/
+ └── books/
+ ├── _content.gotmpl
+ └── _index.md
+```
+
+## Page collisions
+
+Two or more pages collide when they have the same publication path. Due to concurrency, the content of the published page is indeterminate. Consider this example:
+
+```text
+content/
+└── books/
+ ├── _content.gotmpl <-- content adapter
+ ├── _index.md
+ └── the-hunchback-of-notre-dame.md
+```
+
+If the content adapter also creates books/the-hunchback-of-notre-dame, the content of the published page is indeterminate. You can not define the processing order.
+
+To detect page collisions, use the `--printPathWarnings` flag when building your site.
+
+[content formats]: /content-management/formats/#classification
+[front matter field]: /content-management/front-matter/#fields
+[media type]: https://en.wikipedia.org/wiki/Media_type
+[syntax]: /templates/introduction/
+[template functions]: /functions/
--- /dev/null
- : When using `ref` or `relref` to resolve page links and a link cannot resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`).
+---
+title: Links and cross references
+description: Shortcodes for creating links to documents.
+categories: [content management]
+keywords: [cross references,references,anchors,urls]
+menu:
+ docs:
+ parent: content-management
+ weight: 170
+weight: 170
+toc: true
+aliases: [/extras/crossreferences/]
+---
+
+The `ref` and `relref` shortcodes display the absolute and relative permalinks to a document, respectively.
+
+## Use of `ref` and `relref`
+
+The `ref` and `relref` shortcodes require a single argument: the path to a content document, with or without a file extension, with or without an anchor. Paths without a leading `/` are first resolved relative to the current page, then to the remainder of the site.
+
+```text
+.
+└── content
+ ├── about
+ | ├── _index.md
+ | └── credits.md
+ ├── pages
+ | ├── document1.md
+ | └── document2.md // has anchor #anchor
+ ├── products
+ | └── index.md
+ └── blog
+ └── my-post.md
+```
+
+The pages can be referenced as follows:
+
+```text
+{{</* ref "document2" */>}} <-- From pages/document1.md, relative path
+{{</* ref "document2#anchor" */>}}
+{{</* ref "document2.md" */>}}
+{{</* ref "document2.md#anchor" */>}}
+{{</* ref "#anchor" */>}} <-- From pages/document2.md
+{{</* ref "/blog/my-post" */>}} <-- From anywhere, absolute path
+{{</* ref "/blog/my-post.md" */>}}
+{{</* relref "document" */>}}
+{{</* relref "document.md" */>}}
+{{</* relref "#anchor" */>}}
+{{</* relref "/blog/my-post.md" */>}}
+```
+
+`index.md` can be reference either by its path or by its containing directory without the ending `/`. `_index.md` can be referenced only by its containing directory:
+
+```text
+{{</* ref "/about" */>}} <-- References /about/_index.md
+{{</* ref "/about/_index" */>}} <-- Raises REF_NOT_FOUND error
+{{</* ref "/about/credits.md" */>}} <-- References /about/credits.md
+
+{{</* ref "/products" */>}} <-- References /products/index.md
+{{</* ref "/products/index" */>}} <-- References /products/index.md
+```
+
+To generate a hyperlink using `ref` or `relref` in Markdown:
+
+```text
+[About]({{</* ref "/about" */>}} "About Us")
+```
+
+Hugo emits an error or warning if a document cannot be uniquely resolved. The error behavior is configurable; see below.
+
+### Link to another language version
+
+Using `ref` or `relref` without specifying a language, will make the reference resolve to the language of the current content page.
+
+To link to another language version of a document, use this syntax:
+
+```text
+{{</* relref path="document.md" lang="ja" */>}}
+```
+
+### Get another output format
+
+To link to another Output Format of a document, use this syntax:
+
+```text
+{{</* relref path="document.md" outputFormat="rss" */>}}
+```
+
+### Heading IDs
+
+When using Markdown document types, Hugo generates element IDs for every heading on a page. For example:
+
+```text
+## Reference
+```
+
+produces this HTML:
+
+```html
+<h2 id="reference">Reference</h2>
+```
+
+Get the permalink to a heading by appending the ID to the path when using the `ref` or `relref` shortcodes:
+
+```text
+{{</* ref "document.md#reference" */>}}
+{{</* relref "document.md#reference" */>}}
+```
+
+Generate a custom heading ID by including an attribute. For example:
+
+```text
+## Reference A {#foo}
+## Reference B {id="bar"}
+```
+
+produces this HTML:
+
+```html
+<h2 id="foo">Reference A</h2>
+<h2 id="bar">Reference B</h2>
+```
+
+Hugo will generate unique element IDs if the same heading appears more than once on a page. For example:
+
+```text
+## Reference
+## Reference
+## Reference
+```
+
+produces this HTML:
+
+```html
+<h2 id="reference">Reference</h2>
+<h2 id="reference-1">Reference</h2>
+<h2 id="reference-2">Reference</h2>
+```
+
+## Ref and RelRef Configuration
+
+The behavior can be configured in `hugo.toml`:
+
+refLinksErrorLevel ("ERROR")
++: When using `ref` or `relref` to resolve page links and a link cannot be resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`).
+
+refLinksNotFoundURL
+: URL to be used as a placeholder when a page reference cannot be found in `ref` or `relref`. Is used as-is.
--- /dev/null
- Create your content in the [Emacs Org Mode] format preceded by front matter. You can use Org Mode keywords for front matter. See [details].
+---
+title: Content formats
+description: Create your content using Markdown, HTML, Emacs Org Mode, AsciiDoc, Pandoc, or reStructuredText.
+categories: [content management]
+keywords: [markdown,asciidoc,pandoc,content format]
+menu:
+ docs:
+ parent: content-management
+ weight: 40
+weight: 40
+toc: true
+aliases: [/content/markdown-extras/,/content/supported-formats/,/doc/supported-formats/]
+---
+
+## Introduction
+
+You may mix content formats throughout your site. For example:
+
+```text
+content/
+└── posts/
+ ├── post-1.md
+ ├── post-2.adoc
+ ├── post-3.org
+ ├── post-4.pandoc
+ ├── post-5.rst
+ └── post-6.html
+```
+
+Regardless of content format, all content must have [front matter], preferably including both `title` and `date`.
+
+Hugo selects the content renderer based on the `markup` identifier in front matter, falling back to the file extension. See the [classification] table below for a list of markup identifiers and recognized file extensions.
+
+[classification]: #classification
+[front matter]: /content-management/front-matter/
+
+## Formats
+
+### Markdown
+
+Create your content in [Markdown] preceded by front matter.
+
+Markdown is Hugo's default content format. Hugo natively renders Markdown to HTML using [Goldmark]. Goldmark is fast and conforms to the [CommonMark] and [GitHub Flavored Markdown] specifications. You can configure Goldmark in your [site configuration][configure goldmark].
+
+Hugo provides custom Markdown features including:
+
+[Attributes]
+: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables.
+
+[Extensions]
+: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more.
+
+[Mathematics]
+: Include mathematical equations and expressions in Markdown using LaTeX markup.
+
+[Render hooks]
+: Override the conversion of Markdown to HTML when rendering fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element.
+
+[Attributes]: /content-management/markdown-attributes/
+[CommonMark]: https://spec.commonmark.org/current/
+[Extensions]: /getting-started/configuration-markup/#goldmark-extensions
+[GitHub Flavored Markdown]: https://github.github.com/gfm/
+[Goldmark]: https://github.com/yuin/goldmark
+[Markdown]: https://daringfireball.net/projects/markdown/
+[Mathematics]: /content-management/mathematics/
+[Render hooks]: /render-hooks/introduction/
+[configure goldmark]: /getting-started/configuration-markup/#goldmark
+
+### HTML
+
+Create your content in [HTML] preceded by front matter. The content is typically what you would place within an HTML document's `body` or `main` element.
+
+[HTML]: https://developer.mozilla.org/en-US/docs/Learn_web_development/Getting_started/Your_first_website/Creating_the_content
+
+### Emacs Org Mode
+
++Create your content in the [Emacs Org Mode] format preceded by front matter. You can use Org Mode keywords for front matter. See [details].
+
+[details]: /content-management/front-matter/#emacs-org-mode
+[Emacs Org Mode]: https://orgmode.org/
+
+### AsciiDoc
+
+Create your content in the [AsciiDoc] format preceded by front matter. Hugo renders AsciiDoc content to HTML using the Asciidoctor executable. You must install Asciidoctor and its dependencies (Ruby) to use the AsciiDoc content format.
+
+You can configure the AsciiDoc renderer in your [site configuration][configure asciidoc].
+
+In its default configuration, Hugo passes these CLI flags when calling the Asciidoctor executable:
+
+```text
+--no-header-footer
+```
+
+The CLI flags passed to the Asciidoctor executable depend on configuration. You may inspect the flags when building your site:
+
+```text
+hugo --logLevel info
+```
+
+[AsciiDoc]: https://asciidoc.org/
+[configure the AsciiDoc renderer]: /getting-started/configuration-markup/#asciidoc
+[configure asciidoc]: /getting-started/configuration-markup/#asciidoc
+
+### Pandoc
+
+Create your content in the [Pandoc] format preceded by front matter. Hugo renders Pandoc content to HTML using the Pandoc executable. You must install Pandoc to use the Pandoc content format.
+
+Hugo passes these CLI flags when calling the Pandoc executable:
+
+```text
+--mathjax
+```
+
+[Pandoc]: https://pandoc.org/
+
+### reStructuredText
+
+Create your content in the [reStructuredText] format preceded by front matter. Hugo renders reStructuredText content to HTML using [Docutils], specifically rst2html. You must install Docutils and its dependencies (Python) to use the reStructuredText content format.
+
+Hugo passes these CLI flags when calling the rst2html executable:
+
+```text
+--leave-comments --initial-header-level=2
+```
+
+[Docutils]: https://docutils.sourceforge.io/
+[reStructuredText]: https://docutils.sourceforge.io/rst.html
+
+## Classification
+
+Content format|Media type|Identifier|File extensions
+:--|:--|:--|:--
+Markdown|`text/markdown`|`markdown`|`markdown`,`md`, `mdown`
+HTML|`text/html`|`html`|`htm`, `html`
+Emacs Org Mode|`text/org`|`org`|`org`
+AsciiDoc|`text/asciidoc`|`asciidoc`|`ad`, `adoc`, `asciidoc`
+Pandoc|`text/pandoc`|`pandoc`|`pandoc`, `pdc`
+reStructuredText|`text/rst`|`rst`|`rst`
+
+When converting content to HTML, Hugo uses:
+
+- Native renderers for Markdown, HTML, and Emacs Org mode
+- External renderers for AsciiDoc, Pandoc, and reStructuredText
+
+Native renderers are faster than external renderers.
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: Front matter
+description: Use front matter to add metadata to your content.
+categories: [content management]
+keywords: [front matter,yaml,toml,json,metadata,archetypes]
+menu:
+ docs:
+ parent: content-management
+ weight: 60
+weight: 60
+toc: true
+aliases: [/content/front-matter/]
+---
+
+## Overview
+
+The front matter at the top of each content file is metadata that:
+
+- Describes the content
+- Augments the content
+- Establishes relationships with other content
+- Controls the published structure of your site
+- Determines template selection
+
+Provide front matter using a serialization format, one of [JSON], [TOML], or [YAML]. Hugo determines the front matter format by examining the delimiters that separate the front matter from the page content.
+
+[json]: https://www.json.org/
+[toml]: https://toml.io/
+[yaml]: https://yaml.org/
+
+See examples of front matter delimiters by toggling between the serialization formats below.
+
+{{< code-toggle file=content/example.md fm=true >}}
+title = 'Example'
+date = 2024-02-02T04:14:54-08:00
+draft = false
+weight = 10
+[params]
+author = 'John Smith'
+{{< /code-toggle >}}
+
+Front matter fields may be [boolean](g), [integer](g), [float](g), [string](g), [arrays](g), or [maps](g). Note that the TOML format also supports unquoted date/time values.
+
+## Fields
+
+The most common front matter fields are `date`, `draft`, `title`, and `weight`, but you can specify metadata using any of fields below.
+
+{{% note %}}
+The field names below are reserved. For example, you cannot create a custom field named `type`. Create custom fields under the `params` key. See the [parameters] section for details.
+
+[parameters]: #parameters
+{{% /note %}}
+
+###### aliases
+
+(`string array`) An array of one or more aliases, where each alias is a relative URL that will redirect the browser to the current location. Access these values from a template using the [`Aliases`] method on a `Page` object. See the [aliases] section for details.
+
+[`aliases`]: /methods/page/aliases/
+[aliases]: /content-management/urls/#aliases
+
+###### build
+
+(`map`) A map of [build options].
+
+[build options]: /content-management/build-options/
+
+###### cascade {#cascade-field}
+
+(`map`) A map of front matter keys whose values are passed down to the page’s descendants unless overwritten by self or a closer ancestor’s cascade. See the [cascade] section for details.
+
+[cascade]: #cascade
+
+###### date
+
+(`string`) The date associated with the page, typically the creation date. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Date`] method on a `Page` object.
+
+[`date`]: /methods/page/date/
+
+###### description
+
+(`string`) Conceptually different than the page `summary`, the description is typically rendered within a `meta` element within the `head` element of the published HTML file. Access this value from a template using the [`Description`] method on a `Page` object.
+
+[`description`]: /methods/page/description/
+
+###### draft
+
+(`bool`)
+If `true`, the page will not be rendered unless you pass the `--buildDrafts` flag to the `hugo` command. Access this value from a template using the [`Draft`] method on a `Page` object.
+
+[`draft`]: /methods/page/draft/
+
+###### expiryDate
+
+(`string`) The page expiration date. On or after the expiration date, the page will not be rendered unless you pass the `--buildExpired` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`ExpiryDate`] method on a `Page` object.
+
+[`expirydate`]: /methods/page/expirydate/
+
+###### headless
+
+(`bool`) Applicable to [leaf bundles], if `true` this value sets the `render` and `list` [build options] to `never`, creating a headless bundle of [page resources].
+
+[leaf bundles]: /content-management/page-bundles/#leaf-bundles
+[page resources]: /content-management/page-resources/
+
+###### isCJKLanguage
+
+(`bool`) Set to `true` if the content language is in the [CJK](g) family. This value determines how Hugo calculates word count, and affects the values returned by the [`WordCount`], [`FuzzyWordCount`], [`ReadingTime`], and [`Summary`] methods on a `Page` object.
+
+[`fuzzywordcount`]: /methods/page/wordcount/
+[`readingtime`]: /methods/page/readingtime/
+[`summary`]: /methods/page/summary/
+[`wordcount`]: /methods/page/wordcount/
+
+###### keywords
+
+(`string array`) An array of keywords, typically rendered within a `meta` element within the `head` element of the published HTML file, or used as a [taxonomy](g) to classify content. Access these values from a template using the [`Keywords`] method on a `Page` object.
+
+[`keywords`]: /methods/page/keywords/
+
+<!-- Added in v0.123.0 but purposefully omitted from documentation. -->
+<!--
+kind
+: The kind of page, e.g. "page", "section", "home" etc. This is usually derived from the content path.
+-->
+
+<!-- Added in v0.123.0 but purposefully omitted from documentation. -->
+<!--
+lang
+: The language code for this page. This is usually derived from the module mount or filename.
+-->
+
+###### lastmod
+
+(`string`) The date that the page was last modified. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`Lastmod`] method on a `Page` object.
+
+[`lastmod`]: /methods/page/date/
+
+###### layout
+
+(`string`) Provide a template name to [target a specific template], overriding the default [template lookup order]. Set the value to the base file name of the template, excluding its extension. Access this value from a template using the [`Layout`] method on a `Page` object.
+
+[`layout`]: /methods/page/layout/
+[template lookup order]: /templates/lookup-order/
+[target a specific template]: /templates/lookup-order/#target-a-template
+
+###### linkTitle
+
+(`string`) Typically a shorter version of the `title`. Access this value from a template using the [`LinkTitle`] method on a `Page` object.
+
+[`linktitle`]: /methods/page/linktitle/
+
+###### markup
+
+(`string`) An identifier corresponding to one of the supported [content formats]. If not provided, Hugo determines the content renderer based on the file extension.
+
+[content formats]: /content-management/formats/#classification
+
+###### menus
+
+(`string`, `string array`, or `map`) If set, Hugo adds the page to the given menu or menus. See the [menus] page for details.
+
+[menus]: /content-management/menus/#define-in-front-matter
+
+###### modified
+
+Alias to [lastmod](#lastmod).
+
+###### outputs
+
+(`string array`) The [output formats] to render.
+
+[output formats]: /templates/output-formats/
+
+<!-- Added in v0.123.0 but purposefully omitted from documentation. -->
+<!--
+path
+: The canonical page path.
+-->
+
+###### params
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.123.0 />}}
+
+(`map`) A map of custom [page parameters].
+
+[page parameters]: #parameters
+
+###### pubdate
+
+Alias to [publishDate](#publishdate).
+
+###### publishDate
+
+(`string`) The page publication date. Before the publication date, the page will not be rendered unless you pass the `--buildFuture` flag to the `hugo` command. Note that the TOML format also supports unquoted date/time values. See the [dates](#dates) section for examples. Access this value from a template using the [`PublishDate`] method on a `Page` object.
+
+[`publishdate`]: /methods/page/publishdate/
+
+###### published
+
+Alias to [publishDate](#publishdate).
+
+###### resources
+
+(`map array`) An array of maps to provide metadata for [page resources].
+
+[page-resources]: /content-management/page-resources/#page-resources-metadata
+
+###### sitemap
+
+(`map`) A map of sitemap options. See the [sitemap templates] page for details. Access these values from a template using the [`Sitemap`] method on a `Page` object.
+
+[sitemap templates]: /templates/sitemap/
+[`sitemap`]: /methods/page/sitemap/
+
+###### slug
+
+(`string`) Overrides the last segment of the URL path. Not applicable to section pages. See the [URL management] page for details. Access this value from a template using the [`Slug`] method on a `Page` object.
+
+[`slug`]: /methods/page/slug/
+[URL management]: /content-management/urls/#slug
+
+###### summary
+
+(`string`) Conceptually different than the page `description`, the summary either summarizes the content or serves as a teaser to encourage readers to visit the page. Access this value from a template using the [`Summary`] method on a `Page` object.
+
+[`Summary`]: /methods/page/summary/
+
+###### title
+
+(`string`) The page title. Access this value from a template using the [`Title`] method on a `Page` object.
+
+[`title`]: /methods/page/title/
+
+###### translationKey
+
+(`string`) An arbitrary value used to relate two or more translations of the same page, useful when the translated pages do not share a common path. Access this value from a template using the [`TranslationKey`] method on a `Page` object.
+
+[`translationkey`]: /methods/page/translationkey/
+
+###### type
+
+(`string`) The [content type](g), overriding the value derived from the top level section in which the page resides. Access this value from a template using the [`Type`] method on a `Page` object.
+
+[`type`]: /methods/page/type/
+
+###### unpublishdate
+
+Alias to [expirydate](#expirydate).
+
+###### url
+
+(`string`) Overrides the entire URL path. Applicable to regular pages and section pages. See the [URL management] page for details.
+
+###### weight
+(`int`) The page [weight](g), used to order the page within a [page collection](g). Access this value from a template using the [`Weight`] method on a `Page` object.
+
+[`weight`]: /methods/page/weight/
+
+## Parameters
+
++{{< new-in 0.123.0 />}}
+
+Specify custom page parameters under the `params` key in front matter:
+
+{{< code-toggle file=content/example.md fm=true >}}
+title = 'Example'
+date = 2024-02-02T04:14:54-08:00
+draft = false
+weight = 10
+[params]
+author = 'John Smith'
+{{< /code-toggle >}}
+
+Access these values from a template using the [`Params`] or [`Param`] method on a `Page` object.
+
+[`param`]: /methods/page/param/
+[`params`]: /methods/page/params/
+
+Hugo provides [embedded templates] to optionally insert meta data within the `head` element of your rendered pages. These embedded templates expect the following front matter parameters:
+
+Parameter|Data type|Used by these embedded templates
+:--|:--|:--
+`audio`|`[]string`|[`opengraph.html`]
+`images`|`[]string`|[`opengraph.html`], [`schema.html`], [`twitter_cards.html`]
+`videos`|`[]string`|[`opengraph.html`]
+
+The embedded templates will skip a parameter if not provided in front matter, but will throw an error if the data type is unexpected.
+
+[`opengraph.html`]: {{% eturl opengraph %}}
+[`schema.html`]: {{% eturl schema %}}
+[`twitter_cards.html`]: {{% eturl twitter_cards %}}
+[embedded templates]: /templates/embedded/
+
+## Taxonomies
+
+Classify content by adding taxonomy terms to front matter. For example, with this site configuration:
+
+{{< code-toggle file=hugo >}}
+[taxonomies]
+tag = 'tags'
+genre = 'genres'
+{{< /code-toggle >}}
+
+Add taxonomy terms as shown below:
+
+{{< code-toggle file=content/example.md fm=true >}}
+title = 'Example'
+date = 2024-02-02T04:14:54-08:00
+draft = false
+weight = 10
+tags = ['red','blue']
+genres = ['mystery','romance']
+[params]
+author = 'John Smith'
+{{< /code-toggle >}}
+
+You can add taxonomy terms to the front matter of any these [page kinds](g):
+
+- `home`
+- `page`
+- `section`
+- `taxonomy`
+- `term`
+
+Access taxonomy terms from a template using the [`Params`] or [`GetTerms`] method on a `Page` object. For example:
+
+{{< code file=layouts/_default/single.html >}}
+{{ with .GetTerms "tags" }}
+ <p>Tags</p>
+ <ul>
+ {{ range . }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+ </ul>
+{{ end }}
+{{< /code >}}
+
+[`Params`]: /methods/page/params/
+[`GetTerms`]: /methods/page/getterms/
+
+## Cascade
+
+Any [node](g) can pass down to its descendants a set of front matter values.
+
+### Target specific pages
+
+The `cascade` block can be an array with an optional `_target` keyword, allowing you to target different page sets while cascading values.
+
+{{< code-toggle file=content/_index.md fm=true >}}
+title ="Home"
+[[cascade]]
+[cascade.params]
+background = "yosemite.jpg"
+[cascade._target]
+path="/articles/**"
+lang="en"
+kind="page"
+[[cascade]]
+[cascade.params]
+background = "goldenbridge.jpg"
+[cascade._target]
+kind="section"
+{{</ code-toggle >}}
+
+Use any combination of these keywords to target a set of pages:
+
+###### path {#cascade-path}
+
+(`string`) A [Glob](https://github.com/gobwas/glob) pattern matching the content path below /content. Expects Unix-styled slashes. Note that this is the virtual path, so it starts at the mount root. The matching supports double-asterisks so you can match for patterns like `/blog/*/**` to match anything from the third level and down.
+
+###### kind {#cascade-kind}
+
+(`string`) A Glob pattern matching the Page's Kind(s), e.g. "{home,section}".
+
+###### lang {#cascade-lang}
+
+(`string`) A Glob pattern matching the Page's language, e.g. "{en,sv}".
+
+###### environment {#cascade-environment}
+
+(`string`) A Glob pattern matching the build environment, e.g. "{production,development}"
+
+Any of the above can be omitted.
+
+{{% note %}}
+With a multilingual site it may be more efficient to define the `cascade` values in your site configuration to avoid duplicating the `cascade` values on the section, taxonomy, or term page for each language.
+
+With a multilingual site, if you choose to define the `cascade` values in front matter, you must create a section, taxonomy, or term page for each language; the `lang` keyword is ignored.
+{{% /note %}}
+
+### Example
+
+{{< code-toggle file=content/posts/_index.md fm=true >}}
+date = 2024-02-01T21:25:36-08:00
+title = 'Posts'
+[cascade]
+ [cascade.params]
+ banner = 'images/typewriter.jpg'
+{{</ code-toggle >}}
+
+With the above example the posts section page and its descendants will return `images/typewriter.jpg` when `.Params.banner` is invoked unless:
+
+- Said descendant has its own `banner` value set
+- Or a closer ancestor node has its own `cascade.banner` value set.
+
+## Emacs Org Mode
+
+If your [content format] is [Emacs Org Mode], you may provide front matter using Org Mode keywords. For example:
+
+{{< code file=content/example.org lang=text >}}
+#+TITLE: Example
+#+DATE: 2024-02-02T04:14:54-08:00
+#+DRAFT: false
+#+AUTHOR: John Smith
+#+GENRES: mystery
+#+GENRES: romance
+#+TAGS: red
+#+TAGS: blue
+#+WEIGHT: 10
+{{< /code >}}
+
+Note that you can also specify array elements on a single line:
+
+{{< code file=content/example.org lang=text >}}
+#+TAGS[]: red blue
+{{< /code >}}
+
+[content format]: /content-management/formats/
+[emacs org mode]: https://orgmode.org/
+
+## Dates
+
+When populating a date field, whether a [custom page parameter](#parameters) or one of the four predefined fields ([`date`](#date), [`expiryDate`](#expirydate), [`lastmod`](#lastmod), [`publishDate`](#publishdate)), use one of these parsable formats:
+
+{{% include "functions/time/_common/parsable-date-time-strings.md" %}}
+
+To override the default time zone, set the [`timeZone`](https://gohugo.io/getting-started/configuration/#timezone) in your site configuration. The order of precedence for determining the time zone is:
+
+1. The time zone offset in the date/time string
+1. The time zone specified in your site configuration
+1. The `Etc/UTC` time zone
--- /dev/null
- A page resource is a file within a [page bundle]. A page bundle is a directory with an `index.md` or `_index.md` file at its root.
+---
+title: Image processing
+description: Resize, crop, rotate, filter, and convert images.
+categories: [content management,fundamentals]
+keywords: [resources,images]
+menu:
+ docs:
+ parent: content-management
+ weight: 90
+toc: true
+weight: 90
+---
+
+## Image resources
+
+To process an image you must access the file as a page resource, global resource, or remote resource.
+
+### Page resource
+
- {{< new-in 0.119.0 >}}
++A page resource is a file within a [page bundle]. A page bundle is a directory with an `index.md` or `_index.md` file at its root.
+
+```text
+content/
+└── posts/
+ └── post-1/ <-- page bundle
+ ├── index.md
+ └── sunset.jpg <-- page resource
+```
+
+To access an image as a page resource:
+
+```go-html-template
+{{ $image := .Resources.Get "sunset.jpg" }}
+```
+
+### Global resource
+
+A global resource is a file within the `assets` directory, or within any directory [mounted] to the `assets` directory.
+
+```text
+assets/
+└── images/
+ └── sunset.jpg <-- global resource
+```
+
+To access an image as a global resource:
+
+```go-html-template
+{{ $image := resources.Get "images/sunset.jpg" }}
+```
+
+### Remote resource
+
+A remote resource is a file on a remote server, accessible via HTTP or HTTPS. To access an image as a remote resource:
+
+```go-html-template
+{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}
+```
+
+## Image rendering
+
+Once you have accessed an image as a resource, render it in your templates using the `Permalink`, `RelPermalink`, `Width`, and `Height` properties.
+
+Example 1: Throws an error if the resource is not found.
+
+```go-html-template
+{{ $image := .Resources.GetMatch "sunset.jpg" }}
+<img src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}">
+```
+
+Example 2: Skips image rendering if the resource is not found.
+
+```go-html-template
+{{ $image := .Resources.GetMatch "sunset.jpg" }}
+{{ with $image }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
+{{ end }}
+```
+
+Example 3: A more concise way to skip image rendering if the resource is not found.
+
+```go-html-template
+{{ with .Resources.GetMatch "sunset.jpg" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
+{{ end }}
+```
+
+Example 4: Skips rendering if there's problem accessing a remote resource.
+
+```go-html-template
+{{ $url := "https://gohugo.io/img/hugo-logo.png" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+## Image processing methods
+
+The `image` resource implements the [`Process`], [`Resize`], [`Fit`], [`Fill`], [`Crop`], [`Filter`], [`Colors`] and [`Exif`] methods.
+
+{{% note %}}
+Metadata (EXIF, IPTC, XMP, etc.) is not preserved during image transformation. Use the `Exif` method with the _original_ image to extract EXIF metadata from JPEG, PNG, TIFF, and WebP images.
+{{% /note %}}
+
+### Process
+
++{{< new-in 0.119.0 />}}
+
+{{% note %}}
+The `Process` method is also available as a filter, which is more effective if you need to apply multiple filters to an image. See [Process filter](/functions/images/process).
+{{% /note %}}
+
+Process processes the image with the given specification. The specification can contain an optional action, one of `resize`, `crop`, `fit` or `fill`. This means that you can use this method instead of [`Resize`], [`Fit`], [`Fill`], or [`Crop`].
+
+See [Options](#image-processing-options) for available options.
+
+You can also use this method apply image processing that does not need any scaling, e.g. format conversions:
+
+```go-html-template
+{{/* Convert the image from JPG to PNG. */}}
+{{ $png := $jpg.Process "png" }}
+```
+
+Some more examples:
+
+```go-html-template
+{{/* Rotate the image 90 degrees counter-clockwise. */}}
+{{ $image := $image.Process "r90" }}
+
+{{/* Scaling actions. */}}
+{{ $image := $image.Process "resize 600x" }}
+{{ $image := $image.Process "crop 600x400" }}
+{{ $image := $image.Process "fit 600x400" }}
+{{ $image := $image.Process "fill 600x400" }}
+```
+
+### Resize
+
+Resize an image to the given width and/or height.
+
+If you specify both width and height, the resulting image will be disproportionally scaled unless the original image has the same aspect ratio.
+
+```go-html-template
+{{/* Resize to a width of 600px and preserve aspect ratio */}}
+{{ $image := $image.Resize "600x" }}
+
+{{/* Resize to a height of 400px and preserve aspect ratio */}}
+{{ $image := $image.Resize "x400" }}
+
+{{/* Resize to a width of 600px and a height of 400px */}}
+{{ $image := $image.Resize "600x400" }}
+```
+
+### Fit
+
+Downscale an image to fit the given dimensions while maintaining aspect ratio. You must provide both width and height.
+
+```go-html-template
+{{ $image := $image.Fit "600x400" }}
+```
+
+### Fill
+
+Crop and resize an image to match the given dimensions. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point.
+
+```go-html-template
+{{ $image := $image.Fill "600x400" }}
+```
+
+### Crop
+
+Crop an image to match the given dimensions without resizing. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point.
+
+```go-html-template
+{{ $image := $image.Crop "600x400" }}
+```
+
+### Filter
+
+Apply one or more [filters] to an image.
+
+```go-html-template
+{{ $image := $image.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}
+```
+
+Write this in a more functional style using pipes. Hugo applies the filters in the order given.
+
+```go-html-template
+{{ $image := $image | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}
+```
+
+Sometimes it can be useful to create the filter chain once and then reuse it.
+
+```go-html-template
+{{ $filters := slice (images.GaussianBlur 6) (images.Pixelate 8) }}
+{{ $image1 := $image1.Filter $filters }}
+{{ $image2 := $image2.Filter $filters }}
+```
+
+### Colors
+
+`.Colors` returns a slice of hex strings with the dominant colors in the image using a simple histogram method.
+
+```go-html-template
+{{ $colors := $image.Colors }}
+```
+
+This method is fast, but if you also scale down your images, it would be good for performance to extract the colors from the scaled down image.
+
+### EXIF
+
+Provides an [EXIF] object containing image metadata.
+
+You may access EXIF data in JPEG, PNG, TIFF, and WebP images. To prevent errors when processing images without EXIF data, wrap the access in a [`with`] statement.
+
+```go-html-template
+{{ with $image.Exif }}
+ Date: {{ .Date }}
+ Lat/Long: {{ .Lat }}/{{ .Long }}
+ Tags:
+ {{ range $k, $v := .Tags }}
+ TAG: {{ $k }}: {{ $v }}
+ {{ end }}
+{{ end }}
+```
+
+You may also access EXIF fields individually, using the [`lang.FormatNumber`] function to format the fields as needed.
+
+```go-html-template
+{{ with $image.Exif }}
+ <ul>
+ {{ with .Date }}<li>Date: {{ .Format "January 02, 2006" }}</li>{{ end }}
+ {{ with .Tags.ApertureValue }}<li>Aperture: {{ lang.FormatNumber 2 . }}</li>{{ end }}
+ {{ with .Tags.BrightnessValue }}<li>Brightness: {{ lang.FormatNumber 2 . }}</li>{{ end }}
+ {{ with .Tags.ExposureTime }}<li>Exposure Time: {{ . }}</li>{{ end }}
+ {{ with .Tags.FNumber }}<li>F Number: {{ . }}</li>{{ end }}
+ {{ with .Tags.FocalLength }}<li>Focal Length: {{ . }}</li>{{ end }}
+ {{ with .Tags.ISOSpeedRatings }}<li>ISO Speed Ratings: {{ . }}</li>{{ end }}
+ {{ with .Tags.LensModel }}<li>Lens Model: {{ . }}</li>{{ end }}
+ </ul>
+{{ end }}
+```
+
+#### EXIF methods
+
+Date
+: (`time.Time`) Returns the image creation date/time. Format with the [`time.Format`]function.
+
+[time.Format]: /functions/time/format/
+
+Lat
+: (`float64`) Returns the GPS latitude in degrees.
+
+Long
+: (`float64`) Returns the GPS longitude in degrees.
+
+Tags
+: (`exif.Tags`) Returns a collection of the available EXIF tags for this image. You may include or exclude specific tags from this collection in the [site configuration].
+
+## Image processing options
+
+The [`Resize`], [`Fit`], [`Fill`], and [`Crop`] methods accept a space-delimited, case-insensitive list of options. The order of the options within the list is irrelevant.
+
+### Dimensions
+
+With the [`Resize`] method you must specify width, height, or both. The [`Fit`], [`Fill`], and [`Crop`] methods require both width and height. All dimensions are in pixels.
+
+```go-html-template
+{{ $image := $image.Resize "600x" }}
+{{ $image := $image.Resize "x400" }}
+{{ $image := $image.Resize "600x400" }}
+{{ $image := $image.Fit "600x400" }}
+{{ $image := $image.Fill "600x400" }}
+{{ $image := $image.Crop "600x400" }}
+```
+
+### Rotation
+
+Rotates an image counter-clockwise by the given angle. Hugo performs rotation _before_ scaling. For example, if the original image is 600x400 and you wish to rotate the image 90 degrees counter-clockwise while scaling it by 50%:
+
+```go-html-template
+{{ $image = $image.Resize "200x r90" }}
+```
+
+In the example above, the width represents the desired width _after_ rotation.
+
+To rotate an image without scaling, use the dimensions of the original image:
+
+```go-html-template
+{{ with .Resources.GetMatch "sunset.jpg" }}
+ {{ with .Resize (printf "%dx%d r90" .Height .Width) }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
+ {{ end }}
+{{ end }}
+```
+
+In the example above, on the second line, we have reversed width and height to reflect the desired dimensions _after_ rotation.
+
+### Anchor
+
+When using the [`Crop`] or [`Fill`] method, the _anchor_ determines the placement of the crop box. You may specify `TopLeft`, `Top`, `TopRight`, `Left`, `Center`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`, or `Smart`.
+
+The default value is `Smart`, which uses [Smartcrop] image analysis to determine the optimal placement of the crop box. You may override the default value in the [site configuration].
+
+For example, if you have a 400x200 image with a bird in the upper left quadrant, you can create a 200x100 thumbnail containing the bird:
+
+```go-html-template
+{{ $image.Crop "200x100 TopLeft" }}
+```
+
+If you apply [rotation](#rotation) when using the [`Crop`] or [`Fill`] method, specify the anchor relative to the rotated image.
+
+### Target format
+
+By default, Hugo encodes the image in the source format. You may convert the image to another format by specifying `bmp`, `gif`, `jpeg`, `jpg`, `png`, `tif`, `tiff`, or `webp`.
+
+```go-html-template
+{{ $image.Resize "600x webp" }}
+```
+
+To convert an image without scaling, use the dimensions of the original image:
+
+```go-html-template
+{{ with .Resources.GetMatch "sunset.jpg" }}
+ {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
+ {{ end }}
+{{ end }}
+```
+
+### Quality
+
+Applicable to JPEG and WebP images, the `q` value determines the quality of the converted image. Higher values produce better quality images, while lower values produce smaller files. Set this value to a whole number between 1 and 100, inclusive.
+
+The default value is 75. You may override the default value in the [site configuration].
+
+```go-html-template
+{{ $image.Resize "600x webp q50" }}
+```
+
+### Hint
+
+Applicable to WebP images, this option corresponds to a set of predefined encoding parameters, and is equivalent to the `-preset` flag for the [`cwebp`] encoder.
+
+[`cwebp`]: https://developers.google.com/speed/webp/docs/cwebp
+
+Value|Example
+:--|:--
+`drawing`|Hand or line drawing with high-contrast details
+`icon`|Small colorful image
+`photo`|Outdoor photograph with natural lighting
+`picture`|Indoor photograph such as a portrait
+`text`|Image that is primarily text
+
+The default value is `photo`. You may override the default value in the [site configuration].
+
+```go-html-template
+{{ $image.Resize "600x webp picture" }}
+```
+
+### Background color
+
+When converting an image from a format that supports transparency (e.g., PNG) to a format that does _not_ support transparency (e.g., JPEG), you may specify the background color of the resulting image.
+
+Use either a 3-digit or 6-digit hexadecimal color code (e.g., `#00f` or `#0000ff`).
+
+The default value is `#ffffff` (white). You may override the default value in the [site configuration].
+
+```go-html-template
+{{ $image.Resize "600x jpg #b31280" }}
+```
+
+### Resampling filter
+
+You may specify the resampling filter used when resizing an image. Commonly used resampling filters include:
+
+Filter|Description
+:--|:--
+`Box`|Simple and fast averaging filter appropriate for downscaling
+`Lanczos`|High-quality resampling filter for photographic images yielding sharp results
+`CatmullRom`|Sharp cubic filter that is faster than the Lanczos filter while providing similar results
+`MitchellNetravali`|Cubic filter that produces smoother results with less ringing artifacts than CatmullRom
+`Linear`|Bilinear resampling filter, produces smooth output, faster than cubic filters
+`NearestNeighbor`|Fastest resampling filter, no antialiasing
+
+The default value is `Box`. You may override the default value in the [site configuration].
+
+```go-html-template
+{{ $image.Resize "600x400 Lanczos" }}
+```
+
+See [github.com/disintegration/imaging] for the complete list of resampling filters. If you wish to improve image quality at the expense of performance, you may wish to experiment with the alternative filters.
+
+## Image processing examples
+
+_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
+
+{{< imgproc "sunset.jpg" "resize 300x" />}}
+
+{{< imgproc "sunset.jpg" "fill 90x120 left" />}}
+
+{{< imgproc "sunset.jpg" "fill 90x120 right" />}}
+
+{{< imgproc "sunset.jpg" "fit 90x90" />}}
+
+{{< imgproc "sunset.jpg" "crop 250x250 center" />}}
+
+{{< imgproc "sunset.jpg" "resize 300x q10" />}}
+
+This is the shortcode used to generate the examples above:
+
+{{< readfile file=layouts/shortcodes/imgproc.html highlight=go-html-template >}}
+
+Call the shortcode from your Markdown like this:
+
+```go-html-template
+{{</* imgproc "sunset.jpg" "resize 300x" /*/>}}
+```
+
+{{% note %}}
+Note the self-closing shortcode syntax above. You may call the `imgproc` shortcode with or without **inner content**.
+{{% /note %}}
+
+## Imaging configuration
+
+### Processing options
+
+Define an `imaging` section in your site configuration to set the default [image processing options](#image-processing-options).
+
+{{< code-toggle config=imaging />}}
+
+anchor
+: See image processing options: [anchor](#anchor).
+
+bgColor
+: See image processing options: [background color](#background-color).
+
+hint
+: See image processing options: [hint](#hint).
+
+quality
+: See image processing options: [quality](#quality).
+
+resampleFilter
+: See image processing options: [resampling filter](#resampling-filter).
+
+### EXIF data
+
+Define an `imaging.exif` section in your site configuration to control the availability of EXIF data.
+
+{{< code-toggle file=hugo >}}
+[imaging.exif]
+includeFields = ""
+excludeFields = ""
+disableDate = false
+disableLatLong = false
+{{< /code-toggle >}}
+
+disableDate
+: Hugo extracts the image creation date/time into `.Date`. Set this to `true` to disable. Default is `false`.
+
+disableLatLong
+: Hugo extracts the GPS latitude and longitude into `.Lat` and `.Long`. Set this to `true` to disable. Default is `false`.
+
+excludeFields
+: Regular expression matching the EXIF tags to exclude from the `.Tags` collection. Default is `""`.
+
+includeFields
+: Regular expression matching the EXIF tags to include in the `.Tags` collection. Default is `""`. To include all available tags, set this value to `".*"`.
+
+{{% note %}}
+To improve performance and decrease cache size, Hugo excludes the following tags: `ColorSpace`, `Contrast`, `Exif`, `Exposure[M|P|B]`, `Flash`, `GPS`, `JPEG`, `Metering`, `Resolution`, `Saturation`, `Sensing`, `Sharp`, and `WhiteBalance`.
+
+To control tag availability, change the `excludeFields` or `includeFields` settings as described above.
+{{% /note %}}
+
+## Smart cropping of images
+
+By default, Hugo uses the [Smartcrop] library when cropping images with the `Crop` or `Fill` methods. You can set the anchor point manually, but in most cases the `Smart` option will make a good choice.
+
+Examples using the sunset image from above:
+
+{{< imgproc "sunset.jpg" "fill 200x200 smart" />}}
+
+{{< imgproc "sunset.jpg" "crop 200x200 smart" />}}
+
+## Image processing performance consideration
+
+Hugo caches processed images in the `resources` directory. If you include this directory in source control, Hugo will not have to regenerate the images in a CI/CD workflow (e.g., GitHub Pages, GitLab Pages, Netlify, etc.). This results in faster builds.
+
+If you change image processing methods or options, or if you rename or remove images, the `resources` directory will contain unused images. To remove the unused images, perform garbage collection with:
+
+```sh
+hugo --gc
+```
+
+[`anchor`]: /content-management/image-processing#anchor
+[mounted]: /hugo-modules/configuration#module-configuration-mounts
+[page bundle]: /content-management/page-bundles/
+[`lang.FormatNumber`]: /functions/lang/formatnumber/
+[filters]: /functions/images/filter/#image-filters
+[github.com/disintegration/imaging]: https://github.com/disintegration/imaging#image-resizing
+[Smartcrop]: https://github.com/muesli/smartcrop#smartcrop
+[Exif]: https://en.wikipedia.org/wiki/Exif
+[`Process`]: #process
+[`Colors`]: #colors
+[`Crop`]: #crop
+[`Exif`]: #exif
+[`Fill`]: #fill
+[`Filter`]: #filter
+[`Fit`]: #fit
+[`Resize`]: #resize
+[site configuration]: #processing-options
+[`with`]: /functions/go-template/with/
--- /dev/null
- {{< new-in 0.122.0 >}}
+---
+title: Mathematics in Markdown
+linkTitle: Mathematics
+description: Include mathematical equations and expressions in Markdown using LaTeX markup.
+categories: [content management]
+keywords: [katex,latex,math,mathjax,typesetting]
+menu:
+ docs:
+ parent: content-management
+ weight: 270
+weight: 270
+toc: true
+math: true
+---
+
- You can configure Hugo to render mathematical markup on the client-side using the MathJax or KaTeX display engine, or you can render the markup while building your site with the [`transform.ToMath`]function.
++{{< new-in 0.122.0 />}}
+
+## Overview
+
+Mathematical equations and expressions written in [LaTeX] are common in academic and scientific publications. Your browser typically renders this mathematical markup using an open-source JavaScript display engine such as [MathJax] or [KaTeX].
+
+For example, with this LaTeX markup:
+
+```text
+\[
+\begin{aligned}
+KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\
+JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2}))
+\end{aligned}
+\]
+```
+
+The MathJax display engine renders this:
+
+\[
+\begin{aligned}
+KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\
+JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2}))
+\end{aligned}
+\]
+
+Equations and expressions can be displayed inline with other text, or as standalone blocks. Block presentation is also known as "display" mode.
+
+Whether an equation or expression appears inline, or as a block, depends on the delimiters that surround the mathematical markup. Delimiters are defined in pairs, where each pair consists of an opening and closing delimiter. The opening and closing delimiters may be the same, or different.
+
+{{% note %}}
- }
++You can configure Hugo to render mathematical markup on the client side using the MathJax or KaTeX display engine, or you can render the markup with the [`transform.ToMath`] function while building your site.
+
+The first approach is described below.
+
+[`transform.ToMath`]: /functions/transform/tomath/
+{{% /note %}}
+
+## Setup
+
+Follow these instructions to include mathematical equations and expressions in your Markdown using LaTeX markup.
+
+###### Step 1
+
+Enable and configure the Goldmark [passthrough extension] in your site configuration. The passthrough extension preserves raw Markdown within delimited snippets of text, including the delimiters themselves.
+
+{{< code-toggle file=hugo copy=true >}}
+[markup.goldmark.extensions.passthrough]
+enable = true
+
+[markup.goldmark.extensions.passthrough.delimiters]
+block = [['\[', '\]'], ['$$', '$$']]
+inline = [['\(', '\)']]
+
+[params]
+math = true
+{{< /code-toggle >}}
+
+The configuration above enables mathematical rendering on every page unless you set the `math` parameter to `false` in front matter. To enable mathematical rendering as needed, set the `math` parameter to `false` in your site configuration, and set the `math` parameter to `true` in front matter. Use this parameter in your base template as shown in [Step 3].
+
+{{% note %}}
+The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration and JavaScript, you will need to double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting.
+
+See the [inline delimiters](#inline-delimiters) section for details.
+{{% /note %}}
+
+To disable passthrough of inline snippets, omit the `inline` key from the configuration:
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.extensions.passthrough.delimiters]
+block = [['\[', '\]'], ['$$', '$$']]
+{{< /code-toggle >}}
+
+You can define your own opening and closing delimiters, provided they match the delimiters that you set in [Step 2].
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.extensions.passthrough.delimiters]
+block = [['@@', '@@']]
+inline = [['@', '@']]
+{{< /code-toggle >}}
+
+###### Step 2
+
+Create a partial template to load MathJax or KaTeX. The example below loads MathJax, or you can use KaTeX as described in the [engines](#engines) section.
+
+{{< code file=layouts/partials/math.html copy=true >}}
+<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
+<script>
+ MathJax = {
+ tex: {
+ displayMath: [['\\[', '\\]'], ['$$', '$$']], // block
+ inlineMath: [['\\(', '\\)']] // inline
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
- <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8" crossorigin="anonymous"></script>
- <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
++ },
++ loader:{
++ load: ['ui/safe']
++ },
+ };
+</script>
+{{< /code >}}
+
+The delimiters above must match the delimiters in your site configuration.
+
+###### Step 3
+
+Conditionally call the partial template from the base template.
+
+{{< code file=layouts/_default/baseof.html >}}
+<head>
+ ...
+ {{ if .Param "math" }}
+ {{ partialCached "math.html" . }}
+ {{ end }}
+ ...
+</head>
+{{< /code >}}
+
+The example above loads the partial template if you have set the `math` parameter in front matter to `true`. If you have not set the `math` parameter in front matter, the conditional statement falls back to the `math` parameter in your site configuration.
+
+###### Step 4
+
+Include mathematical equations and expressions in Markdown using LaTeX markup.
+
+{{< code file=content/math-examples.md copy=true >}}
+This is an inline \(a^*=x-b^*\) equation.
+
+These are block equations:
+
+\[a^*=x-b^*\]
+
+\[ a^*=x-b^* \]
+
+\[
+a^*=x-b^*
+\]
+
+These are also block equations:
+
+$$a^*=x-b^*$$
+
+$$ a^*=x-b^* $$
+
+$$
+a^*=x-b^*
+$$
+{{< /code >}}
+
+If you set the `math` parameter to `false` in your site configuration, you must set the `math` parameter to `true` in front matter. For example:
+
+{{< code-toggle file=content/math-examples.md fm=true >}}
+title = 'Math examples'
+date = 2024-01-24T18:09:49-08:00
+[params]
+math = true
+{{< /code-toggle >}}
+
+## Inline delimiters
+
+The configuration, JavaScript, and examples above use the `\(...\)` delimiter pair for inline equations. The `$...$` delimiter pair is a common alternative, but using it may result in unintended formatting if you use the `$` symbol outside of math contexts.
+
+If you add the `$...$` delimiter pair to your configuration and JavaScript, you must double-escape the `$` when outside of math contexts, regardless of whether mathematical rendering is enabled on the page. For example:
+
+```text
+A \\$5 bill _saved_ is a \\$5 bill _earned_.
+```
+
+{{% note %}}
+If you use the `$...$` delimiter pair for inline equations, and occasionally use the `$` symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by [this KaTeX limitation](https://github.com/KaTeX/KaTeX/issues/437).
+{{% /note %}}
+
+## Engines
+
+MathJax and KaTeX are open-source JavaScript display engines. Both engines are fast, but at the time of this writing MathJax v3.2.2 is slightly faster than KaTeX v0.16.11.
+
+{{% note %}}
+If you use the `$...$` delimiter pair for inline equations, and occasionally use the `$` symbol outside of math contexts, you must use MathJax instead of KaTeX to avoid unintended formatting caused by [this KaTeX limitation](https://github.com/KaTeX/KaTeX/issues/437).
+
+See the [inline delimiters](#inline-delimiters) section for details.
+{{% /note %}}
+
+To use KaTeX instead of MathJax, replace the partial template from [Step 2] with this:
+
+{{< code file=layouts/partials/math.html copy=true >}}
++<link
++ rel="stylesheet"
++ href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css"
++ integrity="sha384-zh0CIslj+VczCZtlzBcjt5ppRcsAmDnRem7ESsYwWwg3m/OaJ2l4x7YBZl9Kxxib"
++ crossorigin="anonymous"
++>
++<script
++ defer
++ src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"
++ integrity="sha384-Rma6DA2IPUwhNxmrB/7S3Tno0YY7sFu9WSYMCuulLhIqYSGZ2gKCJWIqhBWqMQfh"
++ crossorigin="anonymous">
++</script>
++<script
++ defer
++ src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/contrib/auto-render.min.js"
++ integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh"
++ crossorigin="anonymous"
++ onload="renderMathInElement(document.body);">
++</script>
+<script>
+ document.addEventListener("DOMContentLoaded", function() {
+ renderMathInElement(document.body, {
+ delimiters: [
+ {left: '\\[', right: '\\]', display: true}, // block
+ {left: '$$', right: '$$', display: true}, // block
+ {left: '\\(', right: '\\)', display: false}, // inline
+ ],
+ throwOnError : false
+ });
+ });
+</script>
+{{< /code >}}
+
+The delimiters above must match the delimiters in your site configuration.
+
+## Chemistry
+
+Both MathJax and KaTeX provide support for chemical equations. For example:
+
+```text
+$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
+```
+
+$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
+
+As shown in [Step 2] above, MathJax supports chemical equations without additional configuration. To add chemistry support to KaTeX, enable the mhchem extension as described in the KaTeX [documentation](https://katex.org/docs/libs).
+
+[KaTeX]: https://katex.org/
+[LaTeX]: https://www.latex-project.org/
+[MathJax]: https://www.mathjax.org/
+[Step 1]: #step-1
+[Step 2]: #step-2
+[Step 3]: #step-3
+[passthrough extension]: /getting-started/configuration-markup/#passthrough
--- /dev/null
- When building the English site:
+---
+title: Multilingual mode
+linkTitle: Multilingual
+description: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations.
+categories: [content management]
+keywords: [multilingual,i18n,internationalization]
+menu:
+ docs:
+ parent: content-management
+ weight: 230
+weight: 230
+toc: true
+aliases: [/content/multilingual/,/tutorials/create-a-multilingual-site/]
+---
+
+## Configure languages
+
+This is the default language configuration:
+
+{{< code-toggle config=languages />}}
+
+In the above, `en` is the language key.
+
+Language keys must conform to the syntax described in [RFC 5646]. For example:
+
+- `en`
+- `en-US`
+
+Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. Omit the `art-x-` prefix from the language key. For example:
+
+- `hugolang`
+
+{{% note %}}
+Private use subtags must not exceed 8 alphanumeric characters.
+{{% /note %}}
+
+[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
+[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
+
+This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration.
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'de'
+defaultContentLanguageInSubdir = true
+
+[languages.de]
+contentDir = 'content/de'
+disabled = false
+languageCode = 'de-DE'
+languageDirection = 'ltr'
+languageName = 'Deutsch'
+title = 'Projekt Dokumentation'
+weight = 1
+
+[languages.de.params]
+subtitle = 'Referenz, Tutorials und Erklärungen'
+
+[languages.en]
+contentDir = 'content/en'
+disabled = false
+languageCode = 'en-US'
+languageDirection = 'ltr'
+languageName = 'English'
+title = 'Project Documentation'
+weight = 2
+
+[languages.en.params]
+subtitle = 'Reference, Tutorials, and Explanations'
+{{< /code-toggle >}}
+
+defaultContentLanguage
+: (`string`) The project's default language key, conforming to the syntax described in [RFC 5646]. This value must match one of the defined language keys. Examples:
+
+- `en`
+- `en-GB`
+- `pt-BR`
+
+defaultContentLanguageInSubdir
+: (`bool`) If `true`, Hugo renders the default language site in a subdirectory matching the `defaultContentLanguage`. Default is `false`.
+
+contentDir
+: (`string`) The `content` directory for this language. Omit if [translating by file name].
+
+disabled
+: (`bool`) If `true`, Hugo will not render content for this language. Default is `false`.
+
+languageCode
+: (`string`) The language tag as described in [RFC 5646]. This value does not affect localization or URLs. Hugo uses this value to populate the `language` element in the [built-in RSS template], and the `lang` attribute of the `html` element in the [built-in alias template]. Examples:
+
+- `en`
+- `en-GB`
+- `pt-BR`
+
+languageDirection
+: (`string`) The language direction, either left-to-right (`ltr`) or right-to-left (`rtl`). Use this value in your templates with the global [`dir`] HTML attribute.
+
+languageName
+: (`string`) The language name, typically used when rendering a language switcher.
+
+title
+: (`string`) The site title for this language (optional).
+
+weight
+: (`int`) The language weight. When set to a non-zero value, this is the primary sort criteria for this language.
+
+[`dir`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir
+[built-in RSS template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml
+[built-in alias template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/alias.html
+[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
+[translating by file name]: #translation-by-file-name
+
+### Site parameters
+
+Set language-specific site parameters under each language's `params` key:
+
+{{< code-toggle file=hugo >}}
+[params]
+color = "red"
+
+[languages]
+ [languages.de]
+ languageCode = 'de-DE'
+ title = 'Projekt Dokumentation'
+ weight = 1
+ [languages.de.params]
+ color = 'blue'
+ subtitle = 'Referenz, Tutorials und Erklärungen'
+ [languages.en]
+ languageCode = 'en-US'
+ title = 'Project Documentation'
+ weight = 2
+ [languages.en.params]
+ subtitle = 'Reference, Tutorials, and Explanations'
+{{< /code-toggle >}}
+
+When building the English site:
+
+```go-html-template
+{{ site.Params.color }} --> red
+{{ site.Params.subtitle }} --> Reference, Tutorials, and Explanations
+```
+
++When building the German site:
+
+```go-html-template
+{{ site.Params.color }} --> blue
+{{ site.Params.subtitle }} --> 'Referenz, Tutorials und Erklärungen'
+```
+
+### Disable a language
+
+To disable a language within a `languages` object in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[languages.es]
+disabled = true
+{{< /code-toggle >}}
+
+To disable one or more languages in the root of your site configuration:
+
+{{< code-toggle file=hugo >}}
+disableLanguages = ["es", "fr"]
+{{< /code-toggle >}}
+
+To disable one or more languages using an environment variable:
+
+```sh
+HUGO_DISABLELANGUAGES="es fr" hugo
+```
+
+Note that you cannot disable the default content language.
+
+### Configure multilingual multihost
+
+Hugo supports multiple languages in a multihost configuration. This means you can configure a `baseURL` per `language`.
+
+{{% note %}}
+If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different.
+{{% /note %}}
+
+Example:
+
+{{< code-toggle file=hugo >}}
+[languages]
+ [languages.en]
+ baseURL = 'https://en.example.org/'
+ languageName = 'English'
+ title = 'In English'
+ weight = 2
+ [languages.fr]
+ baseURL = 'https://fr.example.org'
+ languageName = 'Français'
+ title = 'En Français'
+ weight = 1
+{{</ code-toggle >}}
+
+With the above, the two sites will be generated into `public` with their own root:
+
+```text
+public
+├── en
+└── fr
+```
+
+**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.org/`.**
+
+When you run `hugo server` we will start multiple HTTP servers. You will typically see something like this in the console:
+
+```text
+Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1) fr
+Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) en
+Press Ctrl+C to stop
+```
+
+Live reload and `--navigateToChanged` between the servers work as expected.
+
+## Translate your content
+
+There are two ways to manage your content translations. Both ensure each page is assigned a language and is linked to its counterpart translations.
+
+### Translation by file name
+
+Considering the following example:
+
+1. `/content/about.en.md`
+1. `/content/about.fr.md`
+
+The first file is assigned the English language and is linked to the second.
+The second file is assigned the French language and is linked to the first.
+
+Their language is __assigned__ according to the language code added as a __suffix to the file name__.
+
+By having the same **path and base file name**, the content pieces are __linked__ together as translated pages.
+
+{{% note %}}
+If a file has no language code, it will be assigned the default language.
+{{% /note %}}
+
+### Translation by content directory
+
+This system uses different content directories for each of the languages. Each language's `content` directory is set using the `contentDir` parameter.
+
+{{< code-toggle file=hugo >}}
+languages:
+ en:
+ weight: 10
+ languageName: "English"
+ contentDir: "content/english"
+ fr:
+ weight: 20
+ languageName: "Français"
+ contentDir: "content/french"
+{{< /code-toggle >}}
+
+The value of `contentDir` can be any valid path -- even absolute path references. The only restriction is that the content directories cannot overlap.
+
+Considering the following example in conjunction with the configuration above:
+
+1. `/content/english/about.md`
+1. `/content/french/about.md`
+
+The first file is assigned the English language and is linked to the second.
+The second file is assigned the French language and is linked to the first.
+
+Their language is __assigned__ according to the `content` directory they are __placed__ in.
+
+By having the same **path and basename** (relative to their language `content` directory), the content pieces are __linked__ together as translated pages.
+
+### Bypassing default linking
+
+Any pages sharing the same `translationKey` set in front matter will be linked as translated pages regardless of basename or location.
+
+Considering the following example:
+
+1. `/content/about-us.en.md`
+1. `/content/om.nn.md`
+1. `/content/presentation/a-propos.fr.md`
+
+{{< code-toggle >}}
+translationKey: "about"
+{{< /code-toggle >}}
+
+By setting the `translationKey` front matter parameter to `about` in all three pages, they will be __linked__ as translated pages.
+
+### Localizing permalinks
+
+Because paths and file names are used to handle linking, all translated pages will share the same URL (apart from the language subdirectory).
+
+To localize URLs:
+
+- For a regular page, set either [`slug`] or [`url`] in front matter
+- For a section page, set [`url`] in front matter
+
+[`slug`]: /content-management/urls/#slug
+[`url`]: /content-management/urls/#url
+
+For example, a French translation can have its own localized slug.
+
+{{< code-toggle file=content/about.fr.md fm=true >}}
+title: A Propos
+slug: "a-propos"
+{{< /code-toggle >}}
+
+At render, Hugo will build both `/about/` and `/fr/a-propos/` without affecting the translation link.
+
+### Page bundles
+
+To avoid the burden of having to duplicate files, each Page Bundle inherits the resources of its linked translated pages' bundles except for the content files (Markdown files, HTML files etc...).
+
+Therefore, from within a template, the page will have access to the files from all linked pages' bundles.
+
+If, across the linked bundles, two or more files share the same basename, only one will be included and chosen as follows:
+
+* File from current language bundle, if present.
+* First file found across bundles by order of language `Weight`.
+
+{{% note %}}
+Page Bundle resources follow the same language assignment logic as content files, both by file name (`image.jpg`, `image.fr.jpg`) and by directory (`english/about/header.jpg`, `french/about/header.jpg`).
+{{%/ note %}}
+
+## Reference translated content
+
+To create a list of links to translated content, use a template similar to the following:
+
+{{< code file=layouts/partials/i18nlist.html >}}
+{{ if .IsTranslated }}
+<h4>{{ i18n "translations" }}</h4>
+<ul>
+ {{ range .Translations }}
+ <li>
+ <a href="{{ .RelPermalink }}">{{ .Language.Lang }}: {{ .LinkTitle }}{{ if .IsPage }} ({{ i18n "wordCount" . }}){{ end }}</a>
+ </li>
+ {{ end }}
+</ul>
+{{ end }}
+{{< /code >}}
+
+The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template. It will not print anything if there are no translations for a given page.
+
+The above also uses the [`i18n` function][i18func] described in the next section.
+
+### List all available languages
+
+`.AllTranslations` on a `Page` can be used to list all translations, including the page itself. On the home page it can be used to build a language navigator:
+
+{{< code file=layouts/partials/allLanguages.html >}}
+<ul>
+{{ range $.Site.Home.AllTranslations }}
+<li><a href="{{ .RelPermalink }}">{{ .Language.LanguageName }}</a></li>
+{{ end }}
+</ul>
+{{< /code >}}
+
+## Translation of strings
+
+See the [`lang.Translate`] template function.
+
+[`lang.Translate`]: /functions/lang/translate
+
+## Localization
+
+The following localization examples assume your site's primary language is English, with translations to French and German.
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'en'
+
+[languages]
+[languages.en]
+contentDir = 'content/en'
+languageName = 'English'
+weight = 1
+[languages.fr]
+contentDir = 'content/fr'
+languageName = 'Français'
+weight = 2
+[languages.de]
+contentDir = 'content/de'
+languageName = 'Deutsch'
+weight = 3
+
+{{< /code-toggle >}}
+
+### Dates
+
+With this front matter:
+
+{{< code-toggle >}}
+date = 2021-11-03T12:34:56+01:00
+{{< /code-toggle >}}
+
+And this template code:
+
+```go-html-template
+{{ .Date | time.Format ":date_full" }}
+```
+
+The rendered page displays:
+
+Language|Value
+:--|:--
+English|Wednesday, November 3, 2021
+Français|mercredi 3 novembre 2021
+Deutsch|Mittwoch, 3. November 2021
+
+See [`time.Format`] for details.
+
+### Currency
+
+With this template code:
+
+```go-html-template
+{{ 512.5032 | lang.FormatCurrency 2 "USD" }}
+```
+
+The rendered page displays:
+
+Language|Value
+:--|:--
+English|$512.50
+Français|512,50 $US
+Deutsch|512,50 $
+
+See [lang.FormatCurrency] and [lang.FormatAccounting] for details.
+
+### Numbers
+
+With this template code:
+
+```go-html-template
+{{ 512.5032 | lang.FormatNumber 2 }}
+```
+
+The rendered page displays:
+
+Language|Value
+:--|:--
+English|512.50
+Français|512,50
+Deutsch|512,50
+
+See [lang.FormatNumber] and [lang.FormatNumberCustom] for details.
+
+### Percentages
+
+With this template code:
+
+```go-html-template
+{{ 512.5032 | lang.FormatPercent 2 }}
+```
+
+The rendered page displays:
+
+Language|Value
+:--|:--
+English|512.50%
+Français|512,50 %
+Deutsch|512,50 %
+
+See [lang.FormatPercent] for details.
+
+## Menus
+
+Localization of menu entries depends on how you define them:
+
+- When you define menu entries [automatically] using the section pages menu, you must use translation tables to localize each entry.
+- When you define menu entries [in front matter], they are already localized based on the front matter itself. If the front matter values are insufficient, use translation tables to localize each entry.
+- When you define menu entries [in site configuration], you must create language-specific menu entries under each language key. If the names of the menu entries are insufficient, use translation tables to localize each entry.
+
+### Create language-specific menu entries
+
+#### Method 1 -- Use a single configuration file
+
+For a simple menu with a small number of entries, use a single configuration file. For example:
+
+{{< code-toggle file=hugo >}}
+[languages.de]
+languageCode = 'de-DE'
+languageName = 'Deutsch'
+weight = 1
+
+[[languages.de.menus.main]]
+name = 'Produkte'
+pageRef = '/products'
+weight = 10
+
+[[languages.de.menus.main]]
+name = 'Leistungen'
+pageRef = '/services'
+weight = 20
+
+[languages.en]
+languageCode = 'en-US'
+languageName = 'English'
+weight = 2
+
+[[languages.en.menus.main]]
+name = 'Products'
+pageRef = '/products'
+weight = 10
+
+[[languages.en.menus.main]]
+name = 'Services'
+pageRef = '/services'
+weight = 20
+{{< /code-toggle >}}
+
+#### Method 2 -- Use a configuration directory
+
+With a more complex menu structure, create a [configuration directory] and split the menu entries into multiple files, one file per language. For example:
+
+```text
+config/
+└── _default/
+ ├── menus.de.toml
+ ├── menus.en.toml
+ └── hugo.toml
+```
+
+{{< code-toggle file=config/_default/menus.de >}}
+[[main]]
+name = 'Produkte'
+pageRef = '/products'
+weight = 10
+[[main]]
+name = 'Leistungen'
+pageRef = '/services'
+weight = 20
+{{< /code-toggle >}}
+
+{{< code-toggle file=config/_default/menus.en >}}
+[[main]]
+name = 'Products'
+pageRef = '/products'
+weight = 10
+[[main]]
+name = 'Services'
+pageRef = '/services'
+weight = 20
+{{< /code-toggle >}}
+
+[configuration directory]: /getting-started/configuration/#configuration-directory
+
+### Use translation tables
+
+When rendering the text that appears in menu each entry, the [example menu template] does this:
+
+```go-html-template
+{{ or (T .Identifier) .Name | safeHTML }}
+```
+
+It queries the translation table for the current language using the menu entry's `identifier` and returns the translated string. If the translation table does not exist, or if the `identifier` key is not present in the translation table, it falls back to `name`.
+
+The `identifier` depends on how you define menu entries:
+
+- If you define the menu entry [automatically] using the section pages menu, the `identifier` is the page's `.Section`.
+- If you define the menu entry [in site configuration] or [in front matter], set the `identifier` property to the desired value.
+
+For example, if you define menu entries in site configuration:
+
+{{< code-toggle file=hugo >}}
+[[menus.main]]
+ identifier = 'products'
+ name = 'Products'
+ pageRef = '/products'
+ weight = 10
+[[menus.main]]
+ identifier = 'services'
+ name = 'Services'
+ pageRef = '/services'
+ weight = 20
+{{< / code-toggle >}}
+
+Create corresponding entries in the translation tables:
+
+{{< code-toggle file=i18n/de >}}
+products = 'Produkte'
+services = 'Leistungen'
+{{< / code-toggle >}}
+
+[example menu template]: /templates/menu/#example
+[automatically]: /content-management/menus/#define-automatically
+[in front matter]: /content-management/menus/#define-in-front-matter
+[in site configuration]: /content-management/menus/#define-in-site-configuration
+
+## Missing translations
+
+If a string does not have a translation for the current language, Hugo will use the value from the default language. If no default value is set, an empty string will be shown.
+
+While translating a Hugo website, it can be handy to have a visual indicator of missing translations. The [`enableMissingTranslationPlaceholders` configuration option][config] will flag all untranslated strings with the placeholder `[i18n] identifier`, where `identifier` is the id of the missing translation.
+
+{{% note %}}
+Hugo will generate your website with these missing translation placeholders. It might not be suitable for production environments.
+{{% /note %}}
+
+For merging of content from other languages (i.e. missing content translations), see [lang.Merge].
+
+To track down missing translation strings, run Hugo with the `--printI18nWarnings` flag:
+
+```sh
+hugo --printI18nWarnings | grep i18n
+i18n|MISSING_TRANSLATION|en|wordCount
+```
+
+## Multilingual themes support
+
+To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria:
+
+* Come from the built-in `.Permalink` or `.RelPermalink`
+* Be constructed with the [`relLangURL`] or [`absLangURL`] template function, or be prefixed with `{{ .LanguagePrefix }}`
+
+If there is more than one language defined, the `LanguagePrefix` method will return `/en` (or whatever the current language is). If not enabled, it will be an empty string (and is therefore harmless for single-language Hugo websites).
+
+## Generate multilingual content with `hugo new content`
+
+If you organize content with translations in the same directory:
+
+```sh
+hugo new content post/test.en.md
+hugo new content post/test.de.md
+```
+
+If you organize content with translations in different directories:
+
+```sh
+hugo new content content/en/post/test.md
+hugo new content content/de/post/test.md
+```
+
+[`abslangurl`]: /functions/urls/abslangurl/
+[config]: /getting-started/configuration/
+[go-i18n-source]: https://github.com/nicksnyder/go-i18n
+[go-i18n]: https://github.com/nicksnyder/go-i18n
+[Hugo Multilingual Part 1: Content translation]: https://regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/
+[i18func]: /functions/lang/translate/
+[lang.FormatAccounting]: /functions/lang/formataccounting/
+[lang.FormatCurrency]: /functions/lang/formatcurrency/
+[lang.FormatNumber]: /functions/lang/formatnumber/
+[lang.FormatNumberCustom]: /functions/lang/formatnumbercustom/
+[lang.FormatPercent]: /functions/lang/formatpercent/
+[lang.Merge]: /functions/lang/merge/
+[menus]: /content-management/menus/
+[OS environment]: /getting-started/configuration/#configure-with-environment-variables
+[`rellangurl`]: /functions/urls/rellangurl/
+[`time.Format`]: /functions/time/format/
--- /dev/null
- : A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants.
+---
+title: Page bundles
+description: Use page bundles to logically associate one or more resources with content.
+categories: [content management]
+keywords: [page,bundle,leaf,branch]
+menu :
+ docs:
+ parent: content-management
+ weight: 30
+weight: 30
+toc: true
+---
+
+## Introduction
+
+A page bundle is a directory that encapsulates both content and associated resources.
+
+By way of example, this site has an "about" page and a "privacy" page:
+
+```text
+content/
+├── about/
+│ ├── index.md
+│ └── welcome.jpg
+└── privacy.md
+```
+
+The "about" page is a page bundle. It logically associates a resource with content by bundling them together. Resources within a page bundle are [page resources], accessible with the [`Resources`] method on the `Page` object.
+
+Page bundles are either _leaf bundles_ or _branch bundles_.
+
+leaf bundle
- : A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page.
++: A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants.
+
+branch bundle
- A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants.
++: A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page.
+
+{{% note %}}
+In the definitions above and the examples below, the extension of the index file depends on the [content format](g). For example, use `index.md` for Markdown content, `index.html` for HTML content, `index.adoc` for AsciiDoc content, etc.
+{{% /note %}}
+
+## Comparison
+
+Page bundle characteristics vary by bundle type.
+
+| | Leaf bundle | Branch bundle |
+|---------------------|---------------------------------------------------------|---------------------------------------------------------|
+| Index file | `index.md` | `_index.md` |
+| Example | `content/about/index.md` | `content/posts/_index.md ` |
+| [Page kinds](g) | `page` | `home`, `section`, `taxonomy`, or `term` |
+| Template types | [single] | [home], [section], [taxonomy], or [term] |
+| Descendant pages | None | Zero or more |
+| Resource location | Adjacent to the index file or in a nested subdirectory | Same as a leaf bundles, but excludes descendant bundles |
+| [Resource types](g) | `page`, `image`, `video`, etc. | all but `page` |
+
+[single]: /templates/types/#single
+[home]: /templates/types/#home
+[section]: /templates/types/#section
+[taxonomy]: /templates/types/#taxonomy
+[term]: /templates/types/#term
+
+Files with [resource type](g) `page` include content written in Markdown, HTML, AsciiDoc, Pandoc, reStructuredText, and Emacs Org Mode. In a leaf bundle, excluding the index file, these files are only accessible as page resources. In a branch bundle, these files are only accessible as content pages.
+
+## Leaf bundles
+
- A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page.
++A _leaf bundle_ is a directory that contains an `index.md` file and zero or more resources. Analogous to a physical leaf, a leaf bundle is at the end of a branch. It has no descendants.
+
+```text
+content/
+├── about
+│ └── index.md
+├── posts
+│ ├── my-post
+│ │ ├── content-1.md
+│ │ ├── content-2.md
+│ │ ├── image-1.jpg
+│ │ ├── image-2.png
+│ │ └── index.md
+│ └── my-other-post
+│ └── index.md
+└── another-section
+ ├── foo.md
+ └── not-a-leaf-bundle
+ ├── bar.md
+ └── another-leaf-bundle
+ └── index.md
+```
+
+There are four leaf bundles in the example above:
+
+about
+: This leaf bundle does not contain any page resources.
+
+my-post
+: This leaf bundle contains an index file, two resources of [resource type](g) `page`, and two resources of resource type `image`.
+
+- content-1, content-2
+
+ These are resources of resource type `page`, accessible via the [`Resources`] method on the `Page` object. Hugo will not render these as individual pages.
+
+- image-1, image-2
+
+ These are resources of resource type `image`, accessible via the `Resources` method on the `Page` object
+
+my-other-post
+: This leaf bundle does not contain any page resources.
+
+another-leaf-bundle
+: This leaf bundle does not contain any page resources.
+
+{{% note %}}
+Create leaf bundles at any depth within the `content` directory, but a leaf bundle may not contain another bundle. Leaf bundles do not have descendants.
+{{% /note %}}
+
+## Branch bundles
+
- Create branch bundles at any depth within the `content` directory, but a leaf bundle may not contain another bundle. Leaf bundles do not have descendants.
++A _branch bundle_ is a directory that contains an `_index.md` file and zero or more resources. Analogous to a physical branch, a branch bundle may have descendants including leaf bundles and other branch bundles. Top level directories with or without `_index.md` files are also branch bundles. This includes the home page.
+
+```text
+content/
+├── branch-bundle-1/
+│ ├── _index.md
+│ ├── content-1.md
+│ ├── content-2.md
+│ ├── image-1.jpg
+│ └── image-2.png
+├── branch-bundle-2/
+│ ├── a-leaf-bundle/
+│ │ └── index.md
+│ └── _index.md
+└── _index.md
+```
+
+There are three branch bundles in the example above:
+
+home page
+: This branch bundle contains an index file, two descendant branch bundles, and no resources.
+
+branch-bundle-1
+: This branch bundle contains an index file, two resources of [resource type](g) `page`, and two resources of resource type `image`.
+
+branch-bundle-2
+: This branch bundle contains an index file and a leaf bundle.
+
+{{% note %}}
++Create branch bundles at any depth within the `content` directory. Branch bundles may have descendants.
+{{% /note %}}
+
+## Headless bundles
+
+Use [build options] in front matter to create an unpublished leaf or branch bundle whose content and resources you can include in other pages.
+
+[`Resources`]: /methods/page/resources/
+[build options]: /content-management/build-options/
+[page resources]: /content-management/page-resources/
--- /dev/null
- `_index.md` files at their root. Page resources are only available to the
+---
+title: Page resources
+description: Use page resources to logically associate assets with a page.
+categories: [content management]
+keywords: [bundle,content,resources]
+menu:
+ docs:
+ parent: content-management
+ weight: 80
+weight: 80
+toc: true
+---
+
+Page resources are only accessible from [page bundles](/content-management/page-bundles), those directories with `index.md` or
- {{< new-in 0.123.0 >}}
++`_index.md` files at their root. Page resources are only available to the
+page with which they are bundled.
+
+In this example, `first-post` is a page bundle with access to 10 page resources including audio, data, documents, images, and video. Although `second-post` is also a page bundle, it has no page resources and is unable to directly access the page resources associated with `first-post`.
+
+```text
+content
+└── post
+ ├── first-post
+ │ ├── images
+ │ │ ├── a.jpg
+ │ │ ├── b.jpg
+ │ │ └── c.jpg
+ │ ├── index.md (root of page bundle)
+ │ ├── latest.html
+ │ ├── manual.json
+ │ ├── notice.md
+ │ ├── office.mp3
+ │ ├── pocket.mp4
+ │ ├── rating.pdf
+ │ └── safety.txt
+ └── second-post
+ └── index.md (root of page bundle)
+```
+
+## Examples
+
+Use any of these methods on a `Page` object to capture page resources:
+
+ - [`Resources.ByType`]
+ - [`Resources.Get`]
+ - [`Resources.GetMatch`]
+ - [`Resources.Match`]
+
+ Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action.
+
+[`Resource`]: /methods/resource
+[`Resources.ByType`]: /methods/page/resources#bytype
+[`Resources.GetMatch`]: /methods/page/resources#getmatch
+[`Resources.Get`]: /methods/page/resources#get
+[`Resources.Match`]: /methods/page/resources#match
+
+The following examples assume this content structure:
+
+```text
+content/
+└── example/
+ ├── data/
+ │ └── books.json <-- page resource
+ ├── images/
+ │ ├── a.jpg <-- page resource
+ │ └── b.jpg <-- page resource
+ ├── snippets/
+ │ └── text.md <-- page resource
+ └── index.md
+```
+
+Render a single image, and throw an error if the file does not exist:
+
+```go-html-template
+{{ $path := "images/a.jpg" }}
+{{ with .Resources.Get $path }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ else }}
+ {{ errorf "Unable to get page resource %q" $path }}
+{{ end }}
+```
+
+Render all images, resized to 300 px wide:
+
+```go-html-template
+{{ range .Resources.ByType "image" }}
+ {{ with .Resize "300x" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+Render the markdown snippet:
+
+```go-html-template
+{{ with .Resources.Get "snippets/text.md" }}
+ {{ .Content }}
+{{ end }}
+```
+
+List the titles in the data file, and throw an error if the file does not exist.
+
+```go-html-template
+{{ $path := "data/books.json" }}
+{{ with .Resources.Get $path }}
+ {{ with . | transform.Unmarshal }}
+ <p>Books:</p>
+ <ul>
+ {{ range . }}
+ <li>{{ .title }}</li>
+ {{ end }}
+ </ul>
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get page resource %q" $path }}
+{{ end }}
+```
+
+## Metadata
+
+The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm).
+
+{{% note %}}
+Resources of type `page` get `Title` etc. from their own front matter.
+{{% /note %}}
+
+name
+: (`string`) Sets the value returned in `Name`.
+
+{{% note %}}
+The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources.
+{{% /note %}}
+
+title
+: (`string`) Sets the value returned in `Title`
+
+params
+: (`map`) A map of custom key-value pairs.
+
+### Resources metadata example
+
+{{< code-toggle file=content/example.md fm=true >}}
+title: Application
+date : 2018-01-25
+resources :
+- src : "images/sunset.jpg"
+ name : "header"
+- src : "documents/photo_specs.pdf"
+ title : "Photo Specifications"
+ params:
+ icon : "photo"
+- src : "documents/guide.pdf"
+ title : "Instruction Guide"
+- src : "documents/checklist.pdf"
+ title : "Document Checklist"
+- src : "documents/payment.docx"
+ title : "Proof of Payment"
+- src : "**.pdf"
+ name : "pdf-file-:counter"
+ params :
+ icon : "pdf"
+- src : "**.docx"
+ params :
+ icon : "word"
+{{</ code-toggle >}}
+
+From the example above:
+
+- `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`.
+- `documents/photo_specs.pdf` will get the `photo` icon.
+- `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`.
+- Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon.
+- All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`.
+- Every docx in the bundle will receive the `word` icon.
+
+{{% note %}}
+The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
+{{% /note %}}
+
+### The `:counter` placeholder in `name` and `title`
+
+The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`.
+
+The counter starts at 1 the first time they are used in either `name` or `title`.
+
+For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as:
+
+{{< code-toggle file=content/inspections/engine/index.md fm=true >}}
+title = 'Engine inspections'
+[[resources]]
+ src = "*specs.pdf"
+ title = "Specification #:counter"
+[[resources]]
+ src = "**.pdf"
+ name = "pdf-file-:counter"
+{{</ code-toggle >}}
+
+the `Name` and `Title` will be assigned to the resource files as follows:
+
+| Resource file | `Name` | `Title` |
+|-------------------|-------------------|-----------------------|
+| checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` |
+| guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` |
+| other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` |
+| photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` |
+
+## Multilingual
+
++{{< new-in 0.123.0 />}}
+
+By default, with a multilingual single-host site, Hugo does not duplicate shared page resources when building the site.
+
+{{% note %}}
+This behavior is limited to Markdown content. Shared page resources for other [content formats] are copied into each language bundle.
+
+[content formats]: /content-management/formats/
+{{% /note %}}
+
+Consider this site configuration:
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'de'
+defaultContentLanguageInSubdir = true
+
+[languages.de]
+languageCode = 'de-DE'
+languageName = 'Deutsch'
+weight = 1
+
+[languages.en]
+languageCode = 'en-US'
+languageName = 'English'
+weight = 2
+{{< /code-toggle >}}
+
+And this content:
+
+```text
+content/
+└── my-bundle/
+ ├── a.jpg <-- shared page resource
+ ├── b.jpg <-- shared page resource
+ ├── c.de.jpg
+ ├── c.en.jpg
+ ├── index.de.md
+ └── index.en.md
+```
+
+With v0.122.0 and earlier, Hugo duplicated the shared page resources, creating copies for each language:
+
+```text
+public/
+├── de/
+│ ├── my-bundle/
+│ │ ├── a.jpg <-- shared page resource
+│ │ ├── b.jpg <-- shared page resource
+│ │ ├── c.de.jpg
+│ │ └── index.html
+│ └── index.html
+├── en/
+│ ├── my-bundle/
+│ │ ├── a.jpg <-- shared page resource (duplicate)
+│ │ ├── b.jpg <-- shared page resource (duplicate)
+│ │ ├── c.en.jpg
+│ │ └── index.html
+│ └── index.html
+└── index.html
+
+```
+
+With v0.123.0 and later, Hugo places the shared resources in the page bundle for the default content language:
+
+```text
+public/
+├── de/
+│ ├── my-bundle/
+│ │ ├── a.jpg <-- shared page resource
+│ │ ├── b.jpg <-- shared page resource
+│ │ ├── c.de.jpg
+│ │ └── index.html
+│ └── index.html
+├── en/
+│ ├── my-bundle/
+│ │ ├── c.en.jpg
+│ │ └── index.html
+│ └── index.html
+└── index.html
+```
+
+This approach reduces build times, storage requirements, bandwidth consumption, and deployment times, ultimately reducing cost.
+
+{{% note %}}
+To resolve Markdown link and image destinations to the correct location, you must use link and image render hooks that capture the page resource with the [`Resources.Get`] method, and then invoke its [`RelPermalink`] method.
+
+By default, with multilingual single-host sites, Hugo enables its [embedded link render hook] and [embedded image render hook] to resolve Markdown link and image destinations.
+
+You may override the embedded render hooks as needed, provided they capture the resource as described above.
+
+[embedded link render hook]: /render-hooks/links/#default
+[embedded image render hook]: /render-hooks/images/#default
+[`Resources.Get`]: /methods/page/resources/#get
+[`RelPermalink`]: /methods/resource/relpermalink/
+{{% /note %}}
+
+Although duplicating shared page resources is inefficient, you can enable this feature in your site configuration if desired:
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark]
+duplicateResourceFiles = true
+{{< /code-toggle >}}
--- /dev/null
- A section is a top-level content directory, or any content directory with an `_index.md` file. A content directory with an `_index.md` file is also known as a [branch bundle](g). Section templates receive one or more page [collections](g) in [context](g).
+---
+title: Sections
+description: Organize content into sections.
+
+categories: [content management]
+keywords: [lists,sections,content types,organization]
+menu:
+ docs:
+ parent: content-management
+ weight: 120
+weight: 120
+toc: true
+aliases: [/content/sections/]
+---
+
+## Overview
+
- Although top-level directories without `_index.md` files are sections, we recommend creating `_index.md` files in _all_ sections.
++A section is a top-level content directory, or any content directory with an `_index.md` file. A content directory with an `_index.md` file is also known as a [branch bundle](g). Section templates receive one or more page [collections](g) in [context](g).
+
+{{% note %}}
++Although top-level directories without `_index.md` files are sections, we recommend creating `_index.md` files in _all_ sections.
+{{% /note %}}
+
+A typical site consists of one or more sections. For example:
+
+```text
+content/
+├── articles/ <-- section (top-level directory)
+│ ├── 2022/
+│ │ ├── article-1/
+│ │ │ ├── cover.jpg
+│ │ │ └── index.md
+│ │ └── article-2.md
+│ └── 2023/
+│ ├── article-3.md
+│ └── article-4.md
+├── products/ <-- section (top-level directory)
+│ ├── product-1/ <-- section (has _index.md file)
+│ │ ├── benefits/ <-- section (has _index.md file)
+│ │ │ ├── _index.md
+│ │ │ ├── benefit-1.md
+│ │ │ └── benefit-2.md
+│ │ ├── features/ <-- section (has _index.md file)
+│ │ │ ├── _index.md
+│ │ │ ├── feature-1.md
+│ │ │ └── feature-2.md
+│ │ └── _index.md
+│ └── product-2/ <-- section (has _index.md file)
+│ ├── benefits/ <-- section (has _index.md file)
+│ │ ├── _index.md
+│ │ ├── benefit-1.md
+│ │ └── benefit-2.md
+│ ├── features/ <-- section (has _index.md file)
+│ │ ├── _index.md
+│ │ ├── feature-1.md
+│ │ └── feature-2.md
+│ └── _index.md
+├── _index.md
+└── about.md
+```
+
+The example above has two top-level sections: articles and products. None of the directories under articles are sections, while all of the directories under products are sections. A section within a section is a known as a nested section or subsection.
+
+## Explanation
+
+Sections and non-sections behave differently.
+
+||Sections|Non-sections
+:--|:-:|:-:
+Directory names become URL segments|:heavy_check_mark:|:heavy_check_mark:
+Have logical ancestors and descendants|:heavy_check_mark:|:x:
+Have list pages|:heavy_check_mark:|:x:
+
+With the file structure from the [example above](#overview):
+
+1. The list page for the articles section includes all articles, regardless of directory structure; none of the subdirectories are sections.
+
+1. The articles/2022 and articles/2023 directories do not have list pages; they are not sections.
+
+1. The list page for the products section, by default, includes product-1 and product-2, but not their descendant pages. To include descendant pages, use the `RegularPagesRecursive` method instead of the `Pages` method in the list template.
+
+[`Pages`]: /methods/page/pages/
+[`RegularPagesRecursive`]: /methods/page/regularpagesrecursive/
+
+1. All directories in the products section have list pages; each directory is a section.
+
+## Template selection
+
+Hugo has a defined [lookup order] to determine which template to use when rendering a page. The [lookup rules] consider the top-level section name; subsection names are not considered when selecting a template.
+
+With the file structure from the [example above](#overview):
+
+Content directory|Section template
+:--|:--
+`content/products`|`layouts/products/list.html`
+`content/products/product-1`|`layouts/products/list.html`
+`content/products/product-1/benefits`|`layouts/products/list.html`
+
+Content directory|Single template
+:--|:--
+`content/products`|`layouts/products/single.html`
+`content/products/product-1`|`layouts/products/single.html`
+`content/products/product-1/benefits`|`layouts/products/single.html`
+
+If you need to use a different template for a subsection, specify `type` and/or `layout` in front matter.
+
+[lookup rules]: /templates/lookup-order/#lookup-rules
+[lookup order]: /templates/lookup-order/
+
+## Ancestors and descendants
+
+A section has one or more ancestors (including the home page), and zero or more descendants. With the file structure from the [example above](#overview):
+
+```text
+content/products/product-1/benefits/benefit-1.md
+```
+
+The content file (benefit-1.md) has four ancestors: benefits, product-1, products, and the home page. This logical relationship allows us to use the `.Parent` and `.Ancestors` methods to traverse the site structure.
+
+For example, use the `.Ancestors` method to render breadcrumb navigation.
+
+{{< code file=layouts/partials/breadcrumb.html >}}
+<nav aria-label="breadcrumb" class="breadcrumb">
+ <ol>
+ {{ range .Ancestors.Reverse }}
+ <li>
+ <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+ </li>
+ {{ end }}
+ <li class="active">
+ <a aria-current="page" href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+ </li>
+ </ol>
+</nav>
+{{< /code >}}
+
+With this CSS:
+
+```css
+.breadcrumb ol {
+ padding-left: 0;
+}
+
+.breadcrumb li {
+ display: inline;
+}
+
+.breadcrumb li:not(:last-child)::after {
+ content: "»";
+}
+```
+
+Hugo renders this, where each breadcrumb is a link to the corresponding page:
+
+```text
+Home » Products » Product 1 » Benefits » Benefit 1
+```
+
+[archetype]: /content-management/archetypes/
+[content type]: /content-management/types/
+[directory structure]: /getting-started/directory-structure/
+[section templates]: /templates/types/#section
+[leaf bundles]: /content-management/page-bundles/#leaf-bundles
+[branch bundles]: /content-management/page-bundles/#branch-bundles
--- /dev/null
- description: Shortcodes are simple snippets inside your content files calling built-in or custom templates.
+---
+title: Shortcodes
- keywords: [markdown,content,shortcodes]
++description: Use embedded, custom, or inline shortcodes to insert elements such as videos, images, and social media embeds into your content.
+categories: [content management]
- toc: true
++keywords: []
+menu:
+ docs:
+ parent: content-management
+ weight: 100
+weight: 100
- testparam: "Hugo Rocks!"
+aliases: [/extras/shortcodes/]
- ## What a shortcode is
++toc: true
+---
+
- Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video `<iframe>`'s) to Markdown content. We think this contradicts the beautiful simplicity of Markdown's syntax.
++## Introduction
++
++{{% glossary-term shortcode %}}
++
++There are three types of shortcodes: embedded, custom, and inline.
++
++## Embedded
++
++Hugo's embedded shortcodes are pre-defined templates within the application. Refer to each shortcode's documentation for specific usage instructions and available arguments.
++
++{{< list-pages-in-section path=/shortcodes >}}
++
++## Custom
++
++Create custom shortcodes to simplify and standardize content creation. For example, the following shortcode template generates an audio player using a [global resource](g):
++
++{{< code file=layouts/shortcodes/audio.html >}}
++{{ with resources.Get (.Get "src") }}
++ <audio controls preload="auto" src="{{ .RelPermalink }}"></audio>
++{{ end }}
++{{< /code >}}
++
++Then call the shortcode from within markup:
++
++{{< code file=content/example.md >}}
++{{</* audio src=/audio/test.mp3 */>}}
++{{< /code >}}
++
++Learn more about creating shortcodes in the [shortcode templates] section.
++
++[shortcode templates]: /templates/shortcode/
++
++## Inline
++
++An inline shortcode is a shortcode template defined within content.
++
++Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection.
++
++To conform with this security model, creating shortcode templates within content is disabled by default. If you trust your content authors, you can enable this functionality in your site's configuration:
++
++{{< code-toggle file=hugo >}}
++[security]
++enableInlineShortcodes = true
++{{< /code-toggle >}}
++
++The following example demonstrates an inline shortcode, `date.inline`, that accepts a single positional argument: a date/time [layout string].
++
++[layout string]: /functions/time/format/#layout-string
++
++{{< code file=content/example.md >}}
++Today is
++{{</* date.inline ":date_medium" */>}}
++ {{- now | time.Format (.Get 0) -}}
++{{</* /date.inline */>}}.
++
++Today is {{</* date.inline ":date_full" */>}}.
++{{< /code >}}
++
++In the example above, the inline shortcode is executed twice: once upon definition and again when subsequently called. Hugo renders this to:
++
++```html
++<p>Today is Jan 30, 2025.</p>
++<p>Today is Thursday, January 30, 2025</p>
++```
++
++Inline shortcodes process their inner content within the same context as regular shortcode templates, allowing you to use any available [shortcode method].
++
++[shortcode method]: /templates/shortcode/#methods
++
++{{% note %}}
++You cannot [nest](#nesting) inline shortcodes.
++{{% /note %}}
++
++Learn more about creating shortcodes in the [shortcode templates] section.
++
++## Calling
+
- Hugo created **shortcodes** to circumvent these limitations.
++Shortcode calls involve three syntactical elements: tags, arguments, and notation.
+
- A shortcode is a simple snippet inside a content file that Hugo will render using a predefined template. Note that shortcodes will not work in template files. If you need the type of drop-in functionality that shortcodes provide but in a template, you most likely want a [partial template][partials] instead.
++### Tags
+
- In addition to cleaner Markdown, shortcodes can be updated any time to reflect new classes, techniques, or standards. At the point of site generation, Hugo shortcodes will easily merge in your changes. You avoid a possibly complicated search and replace operation.
++Some shortcodes expect content between opening and closing tags. For example, the embedded [`details`] shortcode requires an opening and closing tag:
+
- ## Use shortcodes
++```text
++{{</* details summary="See the details" */>}}
++This is a **bold** word.
++{{</* /details */>}}
++```
++
++Some shortcodes do not accept content. For example, the embedded [`instagram`] shortcode requires a single _positional_ argument:
++
++```text
++{{</* instagram CxOWiQNP2MO */>}}
++```
++
++Some shortcodes optionally accept content. For example, you can call the embedded [`qr`] shortcode with content:
++
++```text
++{{</* qr */>}}
++https://gohugo.io
++{{</* /qr */>}}
++```
++
++Or use the self-closing syntax with a trailing slash to pass the text as an argument:
+
- {{< youtube 2xkNJL4gJ9E >}}
++```text
++{{</* qr text=https://gohugo.io /*/>}}
++```
++
++[`details`]: /shortcodes/details
++[`instagram`]: /shortcodes/instagram
++[`qr`]: /shortcodes/qr
++
++Refer to each shortcode's documentation for specific usage instructions and available arguments.
++
++### Arguments
+
- In your content files, a shortcode can be called by calling `{{%/* shortcodename arguments */%}}`. Shortcode arguments are space delimited, and arguments with internal spaces must be quoted.
++Shortcode arguments can be either _named_ or _positional_.
+
- The first word in the shortcode declaration is always the name of the shortcode. Arguments follow the name. Depending upon how the shortcode is defined, the arguments may be named, positional, or both, although you can't mix argument types in a single call. The format for named arguments models that of HTML with the format `name="value"`.
++Named arguments are passed as case-sensitive key-value pairs, as seen in this example with the embedded [`figure`] shortcode. The `src` argument, for instance, is required.
+
- Some shortcodes use or require closing shortcodes. Again like HTML, the opening and closing shortcodes match (name only) with the closing declaration, which is prepended with a slash.
++[`figure`]: /shortcodes/figure
+
- Here are two examples of paired shortcodes:
++```text
++{{</* figure src=/images/kitten.jpg */>}}
++```
+
- ```go-html-template
- {{%/* mdshortcode */%}}Stuff to `process` in the *center*.{{%/* /mdshortcode */%}}
++Positional arguments, on the other hand, are determined by their position. The embedded `instagram` shortcode, for example, expects the first argument to be the Instagram post ID.
+
- ```go-html-template
- {{</* highlight go */>}} A bunch of code here {{</* /highlight */>}}
++```text
++{{</* instagram CxOWiQNP2MO */>}}
+```
+
- The examples above use two different delimiters, the difference being the `%` character in the first and the `<>` characters in the second.
++Shortcode arguments are space delimited, and arguments with internal spaces must be quoted.
++
++```text
++{{</* figure src=/images/kitten.jpg alt="A white kitten" */>}}
+```
+
- ### Shortcodes with raw string arguments
++Shortcodes accept [scalar](g) arguments, one of [string](g), [integer](g), [floating point](g), or [boolean](g).
+
- You can pass multiple lines as arguments to a shortcode by using raw string literals:
++```text
++{{</* my-shortcode name="John Smith" age=24 married=false */>}}
++```
+
- ```go-html-template
++You can optionally use multiple lines when providing several arguments to a shortcode for better readability:
+
- ### Shortcodes with Markdown
++```text
++{{</* figure
++ src=/images/kitten.jpg
++ alt="A white kitten"
++ caption="This is a white kitten"
++ loading=lazy
++*/>}}
++```
++
++Use a [raw string literal](g) if you need to pass a multiline string:
++
++```text
+{{</* myshortcode `This is some <b>HTML</b>,
+and a new line with a "quoted string".` */>}}
+```
+
- Shortcodes using the `%` as the outer-most delimiter will be fully rendered when sent to the content renderer. This means that the rendered output from a shortcode can be part of the page's table of contents, footnotes, etc.
++Shortcodes can accept named arguments, positional arguments, or both, but you must use either named or positional arguments exclusively within a single shortcode call; mixing them is not allowed.
+
- ### Shortcodes without Markdown
++Refer to each shortcode's documentation for specific usage instructions and available arguments.
+
- The `<` character indicates that the shortcode's inner content does *not* need further rendering. Often shortcodes without Markdown include internal HTML:
++### Notation
+
- ```go-html-template
- {{</* myshortcode */>}}<p>Hello <strong>World!</strong></p>{{</* /myshortcode */>}}
- ```
++Shortcodes can be called using two different notations, distinguished by their tag delimiters.
+
- ### Nested shortcodes
++Notation|Example
++:--|:--
++Markdown|`{{%/* foo */%}} ## Section 1 {{%/* /foo */%}}`
++Standard|`{{</* foo */>}} ## Section 2 {{</* /foo */>}}`
++
++###### Markdown notation
++
++Hugo processes the shortcode before the page content is rendered by the Markdown renderer. This means, for instance, that Markdown headings inside a Markdown-notation shortcode will be included when invoking the [`TableOfContents`] method on the `Page` object.
++
++[`TableOfContents`]: /methods/page/tableofcontents/
++
++###### Standard notation
++
++With standard notation, Hugo processes the shortcode separately, merging the output into the page content after Markdown rendering. This means, for instance, that Markdown headings inside a standard-notation shortcode will be excluded when invoking the `TableOfContents` method on the `Page` object.
+
- You can call shortcodes within other shortcodes by creating your own templates that leverage the `.Parent` method. `.Parent` allows you to check the context in which the shortcode is being called. See [Shortcode templates][sctemps].
++By way of example, with this shortcode template:
+
- ## Embedded shortcodes
++{{< code file=layouts/shortcodes/foo.html >}}
++{{ .Inner }}
++{{< /code >}}
++
++And this markdown:
++
++{{< code file=content/example.md >}}
++{{%/* foo */%}} ## Section 1 {{%/* /foo */%}}
++
++{{</* foo */>}} ## Section 2 {{</* /foo */>}}
++{{< /code >}}
++
++Hugo renders this HTML:
++
++```html
++<h2 id="heading">Section 1</h2>
++
++## Section 2
++```
+
- See the [shortcodes](/shortcodes/) section.
++In the above, "Section 1" will be included when invoking the `TableOfContents` method, while "Section 2" will not.
+
- ## Privacy configuration
++The shortcode author determines which notation to use. Consult each shortcode's documentation for specific usage instructions and available arguments.
+
- To learn how to configure your Hugo site to meet the new EU privacy regulation, see [privacy protections].
++## Nesting
+
- ## Create custom shortcodes
++Shortcodes (excluding [inline](#inline) shortcodes) can be nested, creating parent-child relationships. For example, a gallery shortcode might contain several image shortcodes:
+
- To learn more about creating custom shortcodes, see the [shortcode template documentation].
++{{< code file=content/example.md >}}
++{{</* gallery class="content-gallery" */>}}
++ {{</* image src="/images/a.jpg" */>}}
++ {{</* image src="/images/b.jpg" */>}}
++ {{</* image src="/images/c.jpg" */>}}
++{{</* /gallery */>}}
++{{< /code >}}
+
- [privacy protections]: /about/privacy/
- [partials]: /templates/partial/
- [quickstart]: /getting-started/quick-start/
- [sctemps]: /templates/shortcode/
- [shortcode template documentation]: /templates/shortcode/
- [Vimeo]: https://vimeo.com/
- [YouTube Videos]: https://www.youtube.com/
++The [shortcode templates][nesting] section provides a detailed explanation and examples.
+
++[nesting]: /templates/shortcode/#nesting
--- /dev/null
- {{< new-in 0.136.0 >}}
+---
+title: URL management
+description: Control the structure and appearance of URLs through front matter entries and settings in your site configuration.
+categories: [content management]
+keywords: [aliases,redirects,permalinks,urls]
+menu:
+ docs:
+ parent: content-management
+ weight: 180
+weight: 180
+toc: true
+aliases: [/extras/permalinks/,/extras/aliases/,/extras/urls/,/doc/redirects/,/doc/alias/,/doc/aliases/]
+---
+
+## Overview
+
+By default, when Hugo renders a page, the resulting URL matches the file path within the `content` directory. For example:
+
+```text
+content/posts/post-1.md → https://example.org/posts/post-1/
+```
+
+You can change the structure and appearance of URLs with front matter values and site configuration options.
+
+## Front matter
+
+### `slug`
+
+Set the `slug` in front matter to override the last segment of the path. The `slug` value does not affect section pages.
+
+{{< code-toggle file=content/posts/post-1.md fm=true >}}
+title = 'My First Post'
+slug = 'my-first-post'
+{{< /code-toggle >}}
+
+The resulting URL will be:
+
+```text
+https://example.org/posts/my-first-post/
+```
+
+### `url`
+
+Set the `url` in front matter to override the entire path. Use this with either regular pages or section pages.
+
+{{% note %}}
+Hugo does not sanitize the `url` front matter field, allowing you to generate:
+
+- File paths that contain characters reserved by the operating system. For example, file paths on Windows may not contain any of these [reserved characters]. Hugo throws an error if a file path includes a character reserved by the current operating system.
+- URLs that contain disallowed characters. For example, the less than sign (`<`) is not allowed in a URL.
+
+[reserved characters]: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
+{{% /note %}}
+
+If you set both `slug` and `url` in front matter, the `url` value takes precedence.
+
+#### Include a colon
+
- {{< new-in "0.131.0" >}}
++{{< new-in 0.136.0 />}}
+
+If you need to include a colon in the `url` front matter field, escape it with backslash characters. Use one backslash if you wrap the string within single quotes, or use two backslashes if you wrap the string within double quotes. With YAML front matter, use a single backslash if you omit quotation marks.
+
+For example, with this front matter:
+
+{{< code-toggle file=content/example.md fm=true >}}
+title: Example
+url: "my\\:example"
+{{< /code-toggle >}}
+
+The resulting URL will be:
+
+```text
+https://example.org/my:example/
+```
+
+As described above, this will fail on Windows because the colon (`:`) is a reserved character.
+
+#### File extensions
+
+With this front matter:
+
+{{< code-toggle file=content/posts/post-1.md fm=true >}}
+title = 'My First Article'
+url = 'articles/my-first-article'
+{{< /code-toggle >}}
+
+The resulting URL will be:
+
+```text
+https://example.org/articles/my-first-article/
+```
+
+If you include a file extension:
+
+{{< code-toggle file=content/posts/post-1.md fm=true >}}
+title = 'My First Article'
+url = 'articles/my-first-article.html'
+{{< /code-toggle >}}
+
+The resulting URL will be:
+
+```text
+https://example.org/articles/my-first-article.html
+```
+
+#### Leading slashes
+
+With monolingual sites, `url` values with or without a leading slash are relative to the [`baseURL`]. With multilingual sites, `url` values with a leading slash are relative to the `baseURL`, and `url` values without a leading slash are relative to the `baseURL` plus the language prefix.
+
+[`baseURL`]: /getting-started/configuration/#baseurl
+
+Site type|Front matter `url`|Resulting URL
+:--|:--|:--
+monolingual|`/about`|`https://example.org/about/`
+monolingual|`about`|`https://example.org/about/`
+multilingual|`/about`|`https://example.org/about/`
+multilingual|`about`|`https://example.org/de/about/`
+
+#### Permalinks tokens in front matter
+
++{{< new-in 0.131.0 />}}
+
+You can also use [tokens](#tokens) when setting the `url` value. This is typically used in `cascade` sections:
+
+{{< code-toggle file=content/foo/bar/_index.md fm=true >}}
+title ="Bar"
+[[cascade]]
+ url = "/:sections[last]/:slug"
+{{< /code-toggle >}}
+
+## Site configuration
+
+### Permalinks
+
+In your site configuration, define a URL pattern for each top-level section. Each URL pattern can target a given language and/or page kind.
+
+Front matter `url` values override the URL patterns defined in the `permalinks` section of your site configuration.
+
+#### Monolingual examples {#permalinks-monolingual-examples}
+
+With this content structure:
+
+```text
+content/
+├── posts/
+│ ├── bash-in-slow-motion.md
+│ └── tls-in-a-nutshell.md
+├── tutorials/
+│ ├── git-for-beginners.md
+│ └── javascript-bundling-with-hugo.md
+└── _index.md
+```
+
+Render tutorials under "training", and render the posts under "articles" with a date-base hierarchy:
+
+{{< code-toggle file=hugo >}}
+[permalinks.page]
+posts = '/articles/:year/:month/:slug/'
+tutorials = '/training/:slug/'
+[permalinks.section]
+posts = '/articles/'
+tutorials = '/training/'
+{{< /code-toggle >}}
+
+The structure of the published site will be:
+
+```text
+public/
+├── articles/
+│ ├── 2023/
+│ │ ├── 04/
+│ │ │ └── bash-in-slow-motion/
+│ │ │ └── index.html
+│ │ └── 06/
+│ │ └── tls-in-a-nutshell/
+│ │ └── index.html
+│ └── index.html
+├── training/
+│ ├── git-for-beginners/
+│ │ └── index.html
+│ ├── javascript-bundling-with-hugo/
+│ │ └── index.html
+│ └── index.html
+└── index.html
+```
+
+To create a date-based hierarchy for regular pages in the content root:
+
+{{< code-toggle file=hugo >}}
+[permalinks.page]
+"/" = "/:year/:month/:slug/"
+{{< /code-toggle >}}
+
+Use the same approach with taxonomy terms. For example, to omit the taxonomy segment of the URL:
+
+{{< code-toggle file=hugo >}}
+[permalinks.term]
+'tags' = '/:slug/'
+{{< /code-toggle >}}
+
+#### Multilingual example {#permalinks-multilingual-example}
+
+Use the `permalinks` configuration as a component of your localization strategy.
+
+With this content structure:
+
+```text
+content/
+├── en/
+│ ├── books/
+│ │ ├── les-miserables.md
+│ │ └── the-hunchback-of-notre-dame.md
+│ └── _index.md
+└── es/
+ ├── books/
+ │ ├── les-miserables.md
+ │ └── the-hunchback-of-notre-dame.md
+ └── _index.md
+```
+
+And this site configuration:
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'en'
+defaultContentLanguageInSubdir = true
+
+[languages.en]
+contentDir = 'content/en'
+languageCode = 'en-US'
+languageDirection = 'ltr'
+languageName = 'English'
+weight = 1
+
+[languages.en.permalinks.page]
+books = "/books/:slug/"
+
+[languages.en.permalinks.section]
+books = "/books/"
+
+[languages.es]
+contentDir = 'content/es'
+languageCode = 'es-ES'
+languageDirection = 'ltr'
+languageName = 'Español'
+weight = 2
+
+[languages.es.permalinks.page]
+books = "/libros/:slug/"
+
+[languages.es.permalinks.section]
+books = "/libros/"
+{{< /code-toggle >}}
+
+The structure of the published site will be:
+
+```text
+public/
+├── en/
+│ ├── books/
+│ │ ├── les-miserables/
+│ │ │ └── index.html
+│ │ ├── the-hunchback-of-notre-dame/
+│ │ │ └── index.html
+│ │ └── index.html
+│ └── index.html
+├── es/
+│ ├── libros/
+│ │ ├── les-miserables/
+│ │ │ └── index.html
+│ │ ├── the-hunchback-of-notre-dame/
+│ │ │ └── index.html
+│ │ └── index.html
+│ └── index.html
+└── index.html
+````
+
+#### Tokens
+
+Use these tokens when defining the URL pattern. You can also use these tokens when setting the [`url`](#permalinks-tokens-in-front-matter) value in front matter.
+
+`:year`
+: The 4-digit year as defined in the front matter `date` field.
+
+`:month`
+: The 2-digit month as defined in the front matter `date` field.
+
+`:monthname`
+: The name of the month as defined in the front matter `date` field.
+
+`:day`
+: The 2-digit day as defined in the front matter `date` field.
+
+`:weekday`
+: The 1-digit day of the week as defined in the front matter `date` field (Sunday = 0).
+
+`:weekdayname`
+: The name of the day of the week as defined in the front matter `date` field.
+
+`:yearday`
+: The 1- to 3-digit day of the year as defined in the front matter `date` field.
+
+`:section`
+: The content's section.
+
+`:sections`
+: The content's sections hierarchy. You can use a selection of the sections using _slice syntax_: `:sections[1:]` includes all but the first, `:sections[:last]` includes all but the last, `:sections[last]` includes only the last, `:sections[1:2]` includes section 2 and 3. Note that this slice access will not throw any out-of-bounds errors, so you don't have to be exact.
+
+`:title`
+: The title as defined in front matter, else the automatic title. Hugo generates titles automatically for section, taxonomy, and term pages that are not backed by a file.
+
+`:slug`
+: The slug as defined in front matter, else the title as defined in front matter, else the automatic title. Hugo generates titles automatically for section, taxonomy, and term pages that are not backed by a file.
+
+`:filename`
+: The content's file name without extension, applicable to the `page` page kind.
+
+`:slugorfilename`
+: The slug as defined in front matter, else the content's file name without extension, applicable to the `page` page kind.
+
+For time-related values, you can also use the layout string components defined in Go's [time package]. For example:
+
+[time package]: https://pkg.go.dev/time#pkg-constants
+
+{{< code-toggle file=hugo >}}
+permalinks:
+ posts: /:06/:1/:2/:title/
+{{< /code-toggle >}}
+
+### Appearance
+
+The appearance of a URL is either ugly or pretty.
+
+Type|Path|URL
+:--|:--|:--
+ugly|content/about.md|`https://example.org/about.html`
+pretty|content/about.md|`https://example.org/about/`
+
+By default, Hugo produces pretty URLs. To generate ugly URLs, change your site configuration:
+
+{{< code-toggle file=hugo >}}
+uglyURLs = true
+{{< /code-toggle >}}
+
+You can also enable uglyURLs by section. For example, with a site that contains sections for books and films:
+
+{{< code-toggle file=hugo >}}
+[uglyURLs]
+books = true
+films = false
+{{< /code-toggle >}}
+
+### Post-processing
+
+Hugo provides two mutually exclusive configuration options to alter URLs _after_ it renders a page.
+
+#### Canonical URLs
+
+{{% note %}}
+This is a legacy configuration option, superseded by template functions and Markdown render hooks, and will likely be [removed in a future release].
+
+[removed in a future release]: https://github.com/gohugoio/hugo/issues/4733
+{{% /note %}}
+
+If enabled, Hugo performs a search and replace _after_ it renders the page. It searches for site-relative URLs (those with a leading slash) associated with `action`, `href`, `src`, `srcset`, and `url` attributes. It then prepends the `baseURL` to create absolute URLs.
+
+```html
+<a href="/about"> → <a href="https://example.org/about/">
+<img src="/a.gif"> → <img src="https://example.org/a.gif">
+```
+
+This is an imperfect, brute force approach that can affect content as well as HTML attributes. As noted above, this is a legacy configuration option that will likely be removed in a future release.
+
+To enable:
+
+{{< code-toggle file=hugo >}}
+canonifyURLs = true
+{{< /code-toggle >}}
+
+#### Relative URLs
+
+{{% note %}}
+Do not enable this option unless you are creating a serverless site, navigable via the file system.
+{{% /note %}}
+
+If enabled, Hugo performs a search and replace _after_ it renders the page. It searches for site-relative URLs (those with a leading slash) associated with `action`, `href`, `src`, `srcset`, and `url` attributes. It then transforms the URL to be relative to the current page.
+
+For example, when rendering `content/posts/post-1`:
+
+```html
+<a href="/about"> → <a href="../../about">
+<img src="/a.gif"> → <img src="../../a.gif">
+```
+
+This is an imperfect, brute force approach that can affect content as well as HTML attributes. As noted above, do not enable this option unless you are creating a serverless site.
+
+To enable:
+
+{{< code-toggle file=hugo >}}
+relativeURLs = true
+{{< /code-toggle >}}
+
+## Aliases
+
+Create redirects from old URLs to new URLs with aliases:
+
+- An alias with a leading slash is relative to the `baseURL`
+- An alias without a leading slash is relative to the current directory
+
+### Examples {#alias-examples}
+
+Change the file name of an existing page, and create an alias from the previous URL to the new URL:
+
+{{< code-toggle file=content/posts/new-file-name.md >}}
+aliases = ['/posts/previous-file-name']
+{{< /code-toggle >}}
+
+Each of these directory-relative aliases is equivalent to the site-relative alias above:
+
+- `previous-file-name`
+- `./previous-file-name`
+- `../posts/previous-file-name`
+
+You can create more than one alias to the current page:
+
+{{< code-toggle file=content/posts/new-file-name.md >}}
+aliases = ['previous-file-name','original-file-name']
+{{< /code-toggle >}}
+
+In a multilingual site, use a directory-relative alias, or include the language prefix with a site-relative alias:
+
+{{< code-toggle file=content/posts/new-file-name.de.md >}}
+aliases = ['/de/posts/previous-file-name']
+{{< /code-toggle >}}
+
+### How aliases work
+
+Using the first example above, Hugo generates the following site structure:
+
+```text
+public/
+├── posts/
+│ ├── new-file-name/
+│ │ └── index.html
+│ ├── previous-file-name/
+│ │ └── index.html
+│ └── index.html
+└── index.html
+```
+
+The alias from the previous URL to the new URL is a client-side redirect:
+
+{{< code file=posts/previous-file-name/index.html >}}
+<!DOCTYPE html>
+<html lang="en-us">
+ <head>
+ <title>https://example.org/posts/new-file-name/</title>
+ <link rel="canonical" href="https://example.org/posts/new-file-name/">
+ <meta name="robots" content="noindex">
+ <meta charset="utf-8">
+ <meta http-equiv="refresh" content="0; url=https://example.org/posts/new-file-name/">
+ </head>
+</html>
+{{< /code >}}
+
+Collectively, the elements in the `head` section:
+
+- Tell search engines that the new URL is canonical
+- Tell search engines not to index the previous URL
+- Tell the browser to redirect to the new URL
+
+Hugo renders alias files before rendering pages. A new page with the previous file name will overwrite the alias, as expected.
+
+### Customize
+
+To override Hugo's embedded `alias` template, copy the [source code] to a file with the same name in the `layouts` directory. The template receives the following context:
+
+Permalink
+: The link to the page being aliased.
+
+Page
+: The Page data for the page being aliased.
+
+[source code]: {{% eturl alias %}}
--- /dev/null
- linkTitle: In this section
- description: Contribute to Hugo development, documentation, and themes.
+---
+title: Contribute to the Hugo project
++linktitle: Contribute
++description: Contribute to development, documentation, and themes.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: contribute-in-this-section
+ parent: contribute
+ weight: 10
+weight: 10
+aliases: [/tutorials/how-to-contribute-to-hugo/,/community/contributing/]
+---
+
+Hugo relies heavily on the enthusiasm and participation of the open-source community. We need your support.
--- /dev/null
- You can build, install, and test Hugo at any point in its development history. The examples below build and install the extended version of Hugo.
+---
+title: Development
+description: Contribute to the development of Hugo.
+categories: [contribute]
+keywords: [development]
+menu:
+ docs:
+ parent: contribute
+ weight: 20
+weight: 20
+toc: true
+---
+
+## Introduction
+
+You can contribute to the Hugo project by:
+
+- Answering questions on the [forum]
+- Improving the [documentation]
+- Monitoring the [issue queue]
+- Creating or improving [themes]
+- Squashing [bugs]
+
+Please submit documentation issues and pull requests to the [documentation repository].
+
+If you have an idea for an enhancement or new feature, create a new topic on the [forum] in the "Feature" category. This will help you to:
+
+- Determine if the capability already exists
+- Measure interest
+- Refine the concept
+
+If there is sufficient interest, [create a proposal]. Do not submit a pull request until the project lead accepts the proposal.
+
+For a complete guide to contributing to Hugo, see the [Contribution Guide].
+
+[bugs]: https://github.com/gohugoio/hugo/issues?q=is%3Aopen+is%3Aissue+label%3ABug
+[contributing]: CONTRIBUTING.md
+[create a proposal]: https://github.com/gohugoio/hugo/issues/new?labels=Proposal%2C+NeedsTriage&template=feature_request.md
+[documentation repository]: https://github.com/gohugoio/hugoDocs
+[documentation]: /documentation
+[forum]: https://discourse.gohugo.io
+[issue queue]: https://github.com/gohugoio/hugo/issues
+[themes]: https://themes.gohugo.io/
+[contribution guide]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md
+
+## Prerequisites
+
+To build the extended or extended/deploy edition from source you must:
+
+1. Install [Git]
+1. Install [Go] version 1.23.0 or later
+1. Install a C compiler, either [GCC] or [Clang]
+1. Update your `PATH` environment variable as described in the [Go documentation]
+
+[Clang]: https://clang.llvm.org/
+[GCC]: https://gcc.gnu.org/
+[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+[Go documentation]: https://go.dev/doc/code#Command
+[Go]: https://go.dev/doc/install
+
+{{% note %}}
+See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows.
+{{% /note %}}
+
+## GitHub workflow
+
+{{% note %}}
+This section assumes that you have a working knowledge of Go, Git and GitHub, and are comfortable working on the command line.
+{{% /note %}}
+
+Use this workflow to create and submit pull requests.
+
+Step 1
+: Fork the [project repository].
+
+[project repository]: https://github.com/gohugoio/hugo/
+
+Step 2
+: Clone your fork.
+
+Step 3
+: Create a new branch with a descriptive name that includes the corresponding issue number.
+
+For a new feature:
+
+```sh
+git checkout -b feat/implement-some-feature-99999
+```
+
+For a bug fix:
+
+```sh
+git checkout -b fix/fix-some-bug-99999
+```
+
+Step 4
+: Make changes.
+
+Step 5
+: Compile and install.
+
+To compile and install the standard edition:
+
+```text
+go install
+```
+
+To compile and install the extended edition:
+
+```text
+CGO_ENABLED=1 go install -tags extended
+```
+
+To compile and install the extended/deploy edition:
+
+```text
+CGO_ENABLED=1 go install -tags extended,withdeploy
+```
+
+Step 6
+: Test your changes:
+
+```text
+go test ./...
+```
+
+Step 7
+: Commit your changes with a descriptive commit message:
+
+- Provide a summary on the first line, typically 50 characters or less, followed by a blank line.
+- Optionally, provide a detailed description where each line is 80 characters or less, followed by a blank line.
+- Add one or more "Fixes" or "Closes" keywords, each on its own line, referencing the [issues] addressed by this change.
+
+[issues]: https://github.com/gohugoio/hugo/issues
+
+For example:
+
+```sh
+git commit -m "tpl/strings: Create wrap function
+
+The strings.Wrap function wraps a string into one or more lines,
+splitting the string after the given number of characters, but not
+splitting in the middle of a word.
+
+Fixes #99998
+Closes #99999"
+```
+
+See the [commit message guidelines] for details.
+
+[commit message guidelines]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md#git-commit-message-guidelines
+
+Step 8
+: Push the new branch to your fork of the documentation repository.
+
+Step 9
+: Visit the [project repository] and create a pull request (PR).
+
+Step 10
+: A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR.
+
+## Building from source
+
++You can build, install, and test Hugo at any point in its development history. The examples below build and install the extended edition of Hugo.
+
+To build and install the latest release:
+
+```sh
+CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
+```
+
+To build and install a specific release:
+
+```sh
+CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@v0.141.0
+```
+
+To build and install at the latest commit on the master branch:
+
+```sh
+CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@master
+```
+
+To build and install at a specific commit:
+
+```sh
+CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@0851c17
+```
--- /dev/null
- ### Glossary of terms
+---
+title: Documentation
+description: Help us to improve the documentation by identifying issues and suggesting changes.
+categories: [contribute]
+keywords: [documentation]
+menu:
+ docs:
+ parent: contribute
+ weight: 30
+weight: 30
+toc: true
+aliases: [/contribute/docs/]
+---
+
+## Introduction
+
+We welcome corrections and improvements to the documentation. Please note that the documentation resides in its own repository, separate from the project repository.
+
+For corrections and improvements to the current documentation, please submit issues and pull requests to the [documentation repository].
+
+For documentation related to a new feature, please include the documentation changes when you submit a pull request to the [project repository].
+
+## Guidelines
+
+### Style
+
+Please adhere to Google's [developer documentation style guide].
+
+[developer documentation style guide]: https://developers.google.com/style
+
+### Markdown
+
+Please follow these guidelines:
+
+- Use [ATX] headings, not [setext] headings, levels 2 through 4
+- Use [fenced code blocks], not [indented code blocks]
+- Use hyphens, not asterisks, with unordered [list items]
+- Use the [note shortcode] instead of blockquotes or bold text
+- Do not mix [raw HTML] within Markdown
+- Do not use bold text instead of a heading or description term (`dt`)
+- Remove consecutive blank lines (maximum of two)
+- Remove trailing spaces
+
- Each term in the glossary has its own dedicated page located within the `content/en/getting-started/glossary` directory. While these individual glossary pages are not published as standalone web pages during the build process, their content is included in other pages as needed.
++### Glossary
+
- Lookups are case-insensitive, ignore formatting, and support both singular and plural forms. For example, all of these variations will link to the same glossary entry:
++Glossary terms are maintained on individual pages. While not directly accessible to site visitors, these pages act as a central repository for term definitions.
++
++Definitions must be presented in complete sentences, with the first sentence always introducing the term being defined. To enhance readability and consistency, the first occurrence of the term and any other referenced glossary terms should be italicized.
+
+To link to a term definition on the glossary page, use this custom link syntax:
+
+```text
+[term](g)
+```
+
- [glossary of terms]: /getting-started/glossary/
- [`glossary-term`]: #glossary-term
-
++Lookups are case-insensitive, ignore formatting, and support both singular and plural forms. For example, all of these variations will link to the same glossary term:
+
+```text
+[global resource](g)
+[Global Resource](g)
+[Global Resources](g)
+[`Global Resources`](g)
+```
+
+To insert a term definition, use the [`glossary-term`] shortcode:
+
+```text
+{{%/* glossary-term "global resource" */%}}
+```
+
- Please link to the [glossary of terms] when necessary, and use the terms consistently throughout the documentation. Of special note:
+### Terminology
+
- Use the [glossary link] (`gl`) shortcode to insert a link to the glossary entry for the given term, and use the [glossary term] (`gt`) shortcode to insert the definition of the given term.
-
++Please link to the glossary (see above) when necessary, and use the terms consistently throughout the documentation. Of special note:
+
+- The term "front matter" is two words unless you are referring to the configuration key
+- The term "home page" is two words
+- The term "website" is one word
+- The term "standalone" is one word, not hyphenated
+- Use the word "map" instead of "dictionary"
+- Use the word "flag" instead of "option" when referring to a command line flag
++- Use "client side" as a noun, and "client-side" as an adjective
+- Capitalize the word "Markdown"
+- Hyphenate the term "open-source" when used an adjective.
+
- [glossary]: /getting-started/glossary/
-
+### Page titles and headings
+
+Please follow these guidelines for page titles and headings:
+
+- Use sentence-style capitalization
+- Avoid formatted strings in headings and page titles
+- Shorter is better
+
+### Use active voice with present tense
+
+In software documentation, passive voice is unavoidable in some cases. Please use active voice when possible.
+
+No → With Hugo you can build a static site.\
+Yes → Build a static site with Hugo.
+
+No → This will cause Hugo to generate HTML files in the `public` directory.\
+Yes → Hugo generates HTML files in the `public` directory.
+
+### Use second person instead of third person
+
+No → Users should exercise caution when deleting files.\
+Better → You must be cautious when deleting files.\
+Best → Be cautious when deleting files.
+
+### Avoid adverbs when possible
+
+No → Hugo is extremely fast.\
+Yes → Hugo is fast.
+
+{{% note %}}
+"It's an adverb, Sam. It's a lazy tool of a weak mind." (Outbreak, 1995).
+{{% /note %}}
+
+### Level 6 headings
+
+Level 6 headings are styled as `dt` elements. This was implemented to support a [glossary] with linkable terms.
+
- {{< new-in 0.127.0 >}}
+### Function and method descriptions
+
+When adding a page to the [functions] or [methods] section, begin the description with the word "Returns". With functions and methods that return a boolean value, begin the description with the phrase "Reports whether".
+
+For example:
+
+- `Returns the URL aliases as defined in front matter.`
+- `Reports whether the given page is in the given section.`
+
+[functions]: /functions
+[methods]: /methods
+
+### Directory names, file names, and file paths
+
+Enclose directory names, file names, and file paths within backticks, with the following exceptions:
+
+- Page titles
+- Section headings (h1-h6)
+- Definition list terms
+- The description field in front matter
+
+### Miscellaneous
+
+Other guidelines to consider:
+
+- Do not place list items directly under a heading; include an introductory sentence or phrase before the list.
+- Avoid use of **bold** text. Use the [note shortcode] to draw attention to important content.
+- Do not place description terms (`dt`) within backticks unless required for syntactic clarity.
+- Do not use Hugo's `ref` or `relref` shortcodes. We use a link render hook to resolve and validate link destinations, including fragments.
+- Shorter is better. If there is more than one way to do something, describe the current best practice. For example, avoid phrases such as "you can also do..." and "in older versions you had to..."
+- When including code samples, use short snippets that demonstrate the concept.
+- The Hugo user community is global; use [basic english](https://simple.wikipedia.org/wiki/Basic_English) when possible.
+
+## Code examples
+
+Indent code by two spaces. With examples of template code, include a space after opening action delimiters, and include a space before closing action delimiters.
+
+### Fenced code blocks
+
+Always include the language code when using a fenced code block:
+
+````text
+```go-html-template
+{{ if eq $foo "bar" }}
+ {{ print "foo is bar" }}
+{{ end }}
+```
+````
+
+```go-html-template
+{{ if eq $foo "bar" }}
+ {{ print "foo is bar" }}
+{{ end }}
+```
+
+### Shortcode calls
+
+Use this syntax to include shortcodes calls within your code examples:
+
+```text
+{{</*/* foo */*/>}}
+{{%/*/* foo */*/%}}
+```
+
+```text
+{{</* foo */>}}
+{{%/* foo */%}}
+```
+
+### Site configuration
+
+Use the [code-toggle shortcode] to include site configuration examples:
+
+```text
+{{</* code-toggle file=hugo */>}}
+baseURL = 'https://example.org/'
+languageCode = 'en-US'
+title = 'My Site'
+{{</* /code-toggle */>}}
+```
+
+{{< code-toggle file=hugo >}}
+baseURL = 'https://example.org/'
+languageCode = 'en-US'
+title = 'My Site'
+{{< /code-toggle >}}
+
+### Front matter
+
+Use the [code-toggle shortcode] to include front matter examples:
+
+```text
+{{</* code-toggle file=content/posts/my-first-post.md fm=true */>}}
+title = 'My first post'
+date = 2023-11-09T12:56:07-08:00
+draft = false
+{{</* /code-toggle */>}}
+```
+
+{{< code-toggle file=content/posts/my-first-post.md fm=true >}}
+title = 'My first post'
+date = 2023-11-09T12:56:07-08:00
+draft = false
+{{< /code-toggle >}}
+
+### Other code examples
+
+Use the [code shortcode] for other code examples that require a file name:
+
+```text
+{{</* code file=layouts/_default/single.html */>}}
+{{ range .Site.RegularPages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+{{ end }}
+{{</* /code */>}}
+```
+
+{{< code file=layouts/_default/single.html >}}
+{{ range .Site.RegularPages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+{{ end }}
+{{< /code >}}
+
+## Shortcodes
+
+These shortcodes are commonly used throughout the documentation. Other shortcodes are available for specialized use.
+
+### code
+
+Use the `code` shortcode for other code examples that require a file name. See the [code examples] above. This shortcode takes these arguments:
+
+copy
+: (`bool`) Whether to display a copy-to-clipboard button. Default is `false`.
+
+file
+: (`string`) The file name to display.
+
+lang
+: (`string`) The code language. If you do not provide a `lang` argument, the code language is determined by the file extension. If the file extension is `html`, sets the code language to `go-html-template`. Default is `text`.
+
+```text
+{{</* code file=content/something/foo.md lang=text copy=true */>}}
+Some code here
+{{</* /code */>}}
+```
+
+{{< code file=content/something/foo.md lang=text copy=true >}}
+Some code here
+{{< /code >}}
+
+### code-toggle
+
+Use the `code-toggle` shortcode to display examples of site configuration, front matter, or data files. See the [code examples] above. This shortcode takes these arguments:
+
+config
+: (`string`) The section of `site.Data.docs.config` to render.
+
+copy
+: (`bool`) Whether to display a copy-to-clipboard button. Default is `false`.
+
+file
+: (`string`) The file name to display. Omit the file extension for site configuration examples. Default is `hugo`
+
+fm
+: (`bool`) Whether the example is front matter. Default is `false`.
+
+skipHeader
+: (`bool`) Whether to omit top level key(s) when rendering a section of `site.Data.docs.config`.
+
+```text
+{{</* code-toggle */>}}
+title: Example
+draft: false
+{{</* /code-toggle */>}}
+```
+
+{{< code-toggle >}}
+title: Example
+draft: false
+{{< /code-toggle >}}
+
+### deprecated-in
+
+Use the `deprecated-in` shortcode to indicate that a feature is deprecated:
+
+```text
+{{%/* deprecated-in 0.127.0 */%}}
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{%/* /deprecated-in */%}}
+```
+
+{{% deprecated-in 0.127.0 %}}
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{% /deprecated-in %}}
+
+### eturl
+
+Use the embedded template URL (`eturl`) shortcode to insert an absolute URL to the source code for an embedded template. The shortcode takes a single argument, the base file name of the template (omit the file extension).
+
+```text
+This is a link to the [embedded alias template].
+
+[embedded alias template]: {{%/* eturl alias */%}}
+```
+
+This is a link to the [embedded alias template].
+
+[embedded alias template]: {{% eturl alias %}}
+
+### glossary-term
+
+Use the `glossary-term` shortcode to insert the definition of the given glossary term.
+
+```text
+{{%/* glossary-term scalar */%}}
+```
+
+{{% glossary-term scalar %}}
+
+### include
+
+Use the `include` shortcode to include content from another page.
+
+```text
+{{%/* include "functions/_common/glob-patterns" */%}}
+```
+
+### new-in
+
+Use the `new-in` shortcode to indicate a new feature:
+
+```text
+{{</* new-in 0.127.0 */>}}
+```
+
- When deprecating a function or method, add this to front matter:
++{{< new-in 0.127.0 />}}
+
+### note
+
+Use the `note` shortcode with `{{%/* */%}}` delimiters to call attention to important content:
+
+```text
+{{%/* note */%}}
+Use the [`math.Mod`] function to control...
+
+[`math.Mod`]: /functions/math/mod/
+{{%/* /note */%}}
+```
+
+{{% note %}}
+Use the [`math.Mod`] function to control...
+
+[`math.Mod`]: /functions/math/mod/
+{{% /note %}}
+
+## New features
+
+Use the "new-in" shortcode to indicate a new feature:
+
+{{< code file=content/something/foo.md lang=text >}}
+{{</* new-in 0.120.0 */>}}
+{{< /code >}}
+
+The "new in" label will be hidden if the specified version is older than a predefined threshold, based on differences in major and minor versions. See [details](https://github.com/gohugoio/hugoDocs/blob/master/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/new-in.html).
+
+## Deprecated features
+
+Use the "deprecated-in" shortcode to indicate that a feature is deprecated:
+
+{{< code file=content/something/foo.md >}}
+{{%/* deprecated-in 0.120.0 */%}}
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{%/* /deprecated-in */%}}
+{{< /code >}}
+
- expiryDate: 2024-10-30
++When deprecating a function or method, add something like this to front matter:
+
+{{< code-toggle file=content/something/foo.md fm=true >}}
- Set the `expiryDate` to one year from the date of deprecation, and add a brief front matter comment to explain the setting.
++expiryDate: 2024-10-30 # deprecated 2022-10-30 in v0.123.0
+{{< /code-toggle >}}
+
- [glossary of terms]: /getting-started/glossary/
++Set the `expiryDate` to two years from the date of deprecation, and add a brief front matter comment to explain the setting.
+
+## GitHub workflow
+
+{{% note %}}
+This section assumes that you have a working knowledge of Git and GitHub, and are comfortable working on the command line.
+{{% /note %}}
+
+Use this workflow to create and submit pull requests.
+
+Step 1
+: Fork the [documentation repository].
+
+Step 2
+: Clone your fork.
+
+Step 3
+: Create a new branch with a descriptive name that includes the corresponding issue number, if any:
+
+```sh
+git checkout -b restructure-foo-page-99999
+```
+
+Step 4
+: Make changes.
+
+Step 5
+: Build the site locally to preview your changes.
+
+Step 6
+: Commit your changes with a descriptive commit message:
+
+- Provide a summary on the first line, typically 50 characters or less, followed by a blank line.
+- Optionally, provide a detailed description where each line is 80 characters or less, followed by a blank line.
+- Optionally, add one or more "Fixes" or "Closes" keywords, each on its own line, referencing the [issues] addressed by this change.
+
+For example:
+
+```sh
+git commit -m "Restructure the taxonomy page
+
+This restructures the taxonomy page by splitting topics into logical
+sections, each with one or more examples.
+
+Fixes #9999
+Closes #9998"
+```
+
+Step 7
+: Push the new branch to your fork of the documentation repository.
+
+Step 8
+: Visit the [documentation repository] and create a pull request (PR).
+
+Step 9
+: A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR.
+
+[ATX]: https://spec.commonmark.org/0.30/#atx-headings
+[Microsoft Writing Style Guide]: https://learn.microsoft.com/en-us/style-guide/welcome/
++[`glossary-term`]: #glossary-term
+[basic english]: https://simple.wikipedia.org/wiki/Basic_English
+[code examples]: #code-examples
+[code shortcode]: #code
+[code-toggle shortcode]: #code-toggle
+[documentation repository]: https://github.com/gohugoio/hugoDocs/
+[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks
++[glossary]: /quick-reference/glossary/
+[indented code blocks]: https://spec.commonmark.org/0.30/#indented-code-blocks
+[issues]: https://github.com/gohugoio/hugoDocs/issues
+[list items]: https://spec.commonmark.org/0.30/#list-items
+[note shortcode]: #note
+[project repository]: https://github.com/gohugoio/hugo
+[raw HTML]: https://spec.commonmark.org/0.30/#raw-html
+[setext]: https://spec.commonmark.org/0.30/#setext-heading
--- /dev/null
- linkTitle: Hugo
+---
+title: Hugo Documentation
- layout: documentation-home
++linkTitle: Docs
+description: Hugo is the world's fastest static website engine. It's written in Go (aka Golang) and developed by bep, spf13 and friends.
+menu:
+ main:
+ weight: 1
+weight: 1
++layout: list
+---
+
+A fast and flexible [static site generator] built with love by [bep], [spf13], and [friends] in [Go].
+
+Hugo is optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a complete site in seconds, often less.
+
+[bep]: https://github.com/bep
+[spf13]: https://github.com/spf13
+[friends]: https://github.com/gohugoio/hugo/graphs/contributors
+[go]: https://go.dev/
+[static site generator]: https://en.wikipedia.org/wiki/Static_site_generator
+
+Below you will find some of the most common and helpful pages from our documentation.
--- /dev/null
- {{< new-in 0.140.2 >}}
+---
+_comment: Do not remove front matter.
+---
+
+anchorLineNos
+: (`bool`) Whether to render each line number as an HTML anchor element, setting the `id` attribute of the surrounding `span` element to the line number. Irrelevant if `lineNos` is `false`. Default is `false`.
+
+codeFences
+: (`bool`) Whether to highlight fenced code blocks. Default is `true`.
+
+guessSyntax
+: (`bool`) Whether to automatically detect the language if the `LANG` argument is blank or set to a language for which there is no corresponding [lexer](g). Falls back to a plain text lexer if unable to automatically detect the language. Default is `false`.
+
+{{% note %}}
+The Chroma syntax highlighter includes lexers for approximately 250 languages, but only 5 of these have implemented automatic language detection.
+{{% /note %}}
+
+hl_Lines
+: (`string`) A space-delimited list of lines to emphasize within the highlighted code. To emphasize lines 2, 3, 4, and 7, set this value to `2-4 7`. This option is independent of the `lineNoStart` option.
+
+hl_inline
+: (`bool`) Whether to render the highlighted code without a wrapping container. Default is `false`.
+
+lineAnchors
+: (`string`) When rendering a line number as an HTML anchor element, prepend this value to the `id` attribute of the surrounding `span` element. This provides unique `id` attributes when a page contains two or more code blocks. Irrelevant if `lineNos` or `anchorLineNos` is `false`.
+
+lineNoStart
+: (`int`) The number to display at the beginning of the first line. Irrelevant if `lineNos` is `false`. Default is `1`.
+
+lineNos
+: (`bool`) Whether to display a number at the beginning of each line. Default is `false`.
+
+lineNumbersInTable
+: (`bool`) Whether to render the highlighted code in an HTML table with two cells. The left table cell contains the line numbers, while the right table cell contains the code. Irrelevant if `lineNos` is `false`. Default is `true`.
+
+noClasses
+: (`bool`) Whether to use inline CSS styles instead of an external CSS file. To use an external CSS file, set this value to `false` and generate the CSS file using the `hugo gen chromastyles` command. Default is `true`.
+
+style
+: (`string`) The CSS styles to apply to the highlighted code. See the [style gallery] for examples. Case-sensitive. Default is `monokai`.
+
+[style gallery]: https://xyproto.github.io/splash/docs/
+
+tabWidth
+: (`int`) Substitute this number of spaces for each tab character in your highlighted code. Irrelevant if `noClasses` is `false`. Default is `4`.
+
+wrapperClass
++{{< new-in 0.140.2 />}}
+: (`string`) The class or classes to use for the outermost element of the highlighted code. Default is `highlight`.
+
+{{% note %}}
+Instead of specifying both `lineNos` and `lineNumbersInTable`, you can use the following shorthand notation:
+
+lineNos=inline
+: equivalent to `lineNos=true` and `lineNumbersInTable=false`
+
+lineNos=table
+: equivalent to `lineNos=true` and `lineNumbersInTable=true`
+{{% /note %}}
--- /dev/null
- linkTitle: In this section
- description: A list of Hugo template functions including examples.
+---
+title: Functions
++
++description: Use these functions within your templates and archetypes.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: functions-in-this-section
+ parent: functions
+ weight: 10
+weight: 10
+showSectionMenu: true
+aliases: [/layout/functions/,/templates/functions]
+---
+
+Use these functions within your templates and archetypes.
--- /dev/null
- Note that the `key` can be either a `string` or a `string slice`. The latter is useful to create a deeply nested structure, e.g.:
+---
+title: collections.Dictionary
+description: Returns a map composed of the given key-value pairs.
+categories: []
+keywords: []
+action:
+ aliases: [dict]
+ related:
+ - functions/collections/Slice
+ returnType: map[string]any
+ signatures: ['collections.Dictionary [VALUE...]']
+aliases: [/functions/dict]
+---
+
+Specify the key-value pairs as individual arguments:
+
+```go-html-template
+{{ $m := dict "a" 1 "b" 2 }}
+```
+
+The above produces this data structure:
+
+```json
+{
+ "a": 1,
+ "b": 2
+}
+```
+
+To create an empty map:
+
+```go-html-template
+{{ $m := dict }}
+```
+
++Note that the `key` can be either a `string` or a `[]string`. The latter is useful to create a deeply nested structure, e.g.:
+
+```go-html-template
+{{ $m := dict (slice "a" "b" "c") "value" }}
+```
+
+The above produces this data structure:
+
+```json
+{
+ "a": {
+ "b": {
+ "c": "value"
+ }
+ }
+}
+```
--- /dev/null
+---
+title: collections.Last
+description: Returns the given collection, limited to the last N elements.
+categories: []
+keywords: []
+action:
+ aliases: [last]
+ related:
+ - functions/collections/After
+ - functions/collections/First
+ returnType: any
+ signatures: [collections.Last N COLLECTION]
+aliases: [/functions/last]
+---
+
+```go-html-template
+{{ range last 10 .Pages }}
+ {{ .Render "summary" }}
+{{ end }}
+```
+
+Set `N` to zero to return an empty collection.
+
+```go-html-template
+{{ $emptyPageCollection := last 0 .Pages}}
+```
+
+Use `last` and [`where`] together.
+
++[`where`]: /functions/collections/where/
++
+```go-html-template
+{{ range where .Pages "Section" "articles" | last 5 }}
+ {{ .Render "summary" }}
+{{ end }}
+```
--- /dev/null
- - methods/page/scratch
- - methods/page/store
- - methods/shortcode/scratch
+---
+title: collections.NewScratch
+description: Returns a locally scoped "scratch pad" to store and manipulate data.
+categories: []
+keywords: []
+action:
+ aliases: [newScratch]
+ related:
- The `collections.NewScratch` function creates a locally scoped [scratch pad](g) to store and manipulate data. To create a scratch pad that is attached to a `Page` object, use the [`Scratch`] or [`Store`] method.
-
- [`Scratch`]: /methods/page/scratch/
- [`Store`]: /methods/page/store/
++ - methods/page/Store
++ - methods/site/Store
++ - methods/shortcode/Store
++ - functions/hugo/Store
+ returnType: maps.Scratch
+ signatures: [collections.NewScratch ]
++toc: true
+---
+
- Sets the value of a given key.
++Use the `collections.NewScratch` function to create a locally scoped [scratch pad](g) to store and manipulate data. To create a scratch pad with a different [scope](g), refer to the [scope](#scope) section below.
+
+## Methods
+
+###### Set
+
- Gets the value of a given key.
++Sets the value of the given key.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "greeting" "Hello" }}
+```
+
+###### Get
+
- Adds a given value to existing value(s) of the given key.
++Gets the value of the given key.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "greeting" "Hello" }}
+{{ $s.Get "greeting" }} → Hello
+```
+
+###### Add
+
++Adds the given value to existing value(s) of the given key.
+
+For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "greeting" "Hello" }}
+{{ $s.Add "greeting" "Welcome" }}
+{{ $s.Get "greeting" }} → HelloWelcome
+```
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "total" 3 }}
+{{ $s.Add "total" 7 }}
+{{ $s.Get "total" }} → 10
+```
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "greetings" (slice "Hello") }}
+{{ $s.Add "greetings" (slice "Welcome" "Cheers") }}
+{{ $s.Get "greetings" }} → [Hello Welcome Cheers]
+```
+
+###### SetInMap
+
+Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.SetInMap "greetings" "english" "Hello" }}
+{{ $s.SetInMap "greetings" "french" "Bonjour" }}
+{{ $s.Get "greetings" }} → map[english:Hello french:Bonjour]
+```
+
+###### DeleteInMap
+
+Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.SetInMap "greetings" "english" "Hello" }}
+{{ $s.SetInMap "greetings" "french" "Bonjour" }}
+{{ $s.DeleteInMap "greetings" "english" }}
+{{ $s.Get "greetings" }} → map[french:Bonjour]
+```
+
+###### GetSortedMapValues
+
+Returns an array of values from `key` sorted by `mapKey`.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.SetInMap "greetings" "english" "Hello" }}
+{{ $s.SetInMap "greetings" "french" "Bonjour" }}
+{{ $s.GetSortedMapValues "greetings" }} → [Hello Bonjour]
+```
+
+###### Delete
+
+Removes the given key.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.Set "greeting" "Hello" }}
+{{ $s.Delete "greeting" }}
+```
+
+###### Values
+
+Returns the raw backing map. Do not use with `Scratch` or `Store` methods on a `Page` object due to concurrency issues.
+
+```go-html-template
+{{ $s := newScratch }}
+{{ $s.SetInMap "greetings" "english" "Hello" }}
+{{ $s.SetInMap "greetings" "french" "Bonjour" }}
+
+{{ $map := $s.Values }}
+```
++
++{{% include "_common/scratch-pad-scope.md" %}}
--- /dev/null
- `like` {{< new-in 0.116.0 >}}
+---
+title: collections.Where
+description: Returns the given collection, removing elements that do not satisfy the comparison condition.
+categories: []
+keywords: []
+action:
+ aliases: [where]
+ related: []
+ returnType: any
+ signatures: ['collections.Where COLLECTION KEY [OPERATOR] VALUE']
+toc: true
+aliases: [/functions/where]
+---
+
+The `where` function returns the given collection, removing elements that do not satisfy the comparison condition. The comparison condition is composed of the `KEY`, `OPERATOR`, and `VALUE` arguments:
+
+```text
+collections.Where COLLECTION KEY [OPERATOR] VALUE
+ --------------------
+ comparison condition
+```
+
+Hugo will test for equality if you do not provide an `OPERATOR` argument. For example:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "books" }}
+{{ $books := where .Site.Data.books "genres" "suspense" }}
+```
+
+## Arguments
+
+The where function takes three or four arguments. The `OPERATOR` argument is optional.
+
+COLLECTION
+: (`any`) A [page collection](g) or a [slice](g) of [maps](g).
+
+KEY
+: (`string`) The key of the page or map value to compare with `VALUE`. With page collections, commonly used comparison keys are `Section`, `Type`, and `Params`. To compare with a member of the page `Params` map, [chain](g) the subkey as shown below:
+
+```go-html-template
+{{ $result := where .Site.RegularPages "Params.foo" "bar" }}
+```
+
+OPERATOR
+: (`string`) The logical comparison [operator](#operators).
+
+VALUE
+: (`any`) The value with which to compare. The values to compare must have comparable data types. For example:
+
+Comparison|Result
+:--|:--
+`"123" "eq" "123"`|`true`
+`"123" "eq" 123`|`false`
+`false "eq" "false"`|`false`
+`false "eq" false`|`true`
+
+When one or both of the values to compare is a slice, use the `in`, `not in`, or `intersect` operators as described below.
+
+## Operators
+
+Use any of the following logical operators:
+
+`=`, `==`, `eq`
+: (`bool`) Reports whether the given field value is equal to `VALUE`.
+
+`!=`, `<>`, `ne`
+: (`bool`) Reports whether the given field value is not equal to `VALUE`.
+
+`>=`, `ge`
+: (`bool`) Reports whether the given field value is greater than or equal to `VALUE`.
+
+`>`, `gt`
+: `true` Reports whether the given field value is greater than `VALUE`.
+
+`<=`, `le`
+: (`bool`) Reports whether the given field value is less than or equal to `VALUE`.
+
+`<`, `lt`
+: (`bool`) Reports whether the given field value is less than `VALUE`.
+
+`in`
+: (`bool`) Reports whether the given field value is a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in).
+
+`not in`
+: (`bool`) Reports whether the given field value is not a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in).
+
+`intersect`
+: (`bool`) Reports whether the given field value (a slice) contains one or more elements in common with `VALUE`. See [details](/functions/collections/intersect).
+
- {{< new-in 0.116.0 >}}
++`like` {{< new-in 0.116.0 />}}
+: (`bool`) Reports whether the given field value matches the regular expression specified in `VALUE`. Use the `like` operator to compare `string` values. The `like` operator returns `false` when comparing other data types to the regular expression.
+
+{{% note %}}
+The examples below perform comparisons within a page collection, but the same comparisons are applicable to a slice of maps.
+{{% /note %}}
+
+## String comparison
+
+Compare the value of the given field to a [`string`](g):
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "eq" "books" }}
+{{ $pages := where .Site.RegularPages "Section" "ne" "books" }}
+```
+
+## Numeric comparison
+
+Compare the value of the given field to an [`int`](g) or [`float`](g):
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $pages := where $books "Params.price" "eq" 42 }}
+{{ $pages := where $books "Params.price" "ne" 42.67 }}
+{{ $pages := where $books "Params.price" "ge" 42 }}
+{{ $pages := where $books "Params.price" "gt" 42.67 }}
+{{ $pages := where $books "Params.price" "le" 42 }}
+{{ $pages := where $books "Params.price" "lt" 42.67 }}
+```
+
+## Boolean comparison
+
+Compare the value of the given field to a [`bool`](g):
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $pages := where $books "Params.fiction" "eq" true }}
+{{ $pages := where $books "Params.fiction" "eq" false }}
+{{ $pages := where $books "Params.fiction" "ne" true }}
+{{ $pages := where $books "Params.fiction" "ne" false }}
+```
+
+## Member comparison
+
+Compare a [`scalar`](g) to a [`slice`](g).
+
+For example, to return a collection of pages where the `color` page parameter is either "red" or "yellow":
+
+```go-html-template
+{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
+
+{{ $colors := slice "red" "yellow" }}
+{{ $pages := where $fruit "Params.color" "in" $colors }}
+```
+
+To return a collection of pages where the "color" page parameter is neither "red" nor "yellow":
+
+```go-html-template
+{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
+
+{{ $colors := slice "red" "yellow" }}
+{{ $pages := where $fruit "Params.color" "not in" $colors }}
+```
+
+## Intersection comparison
+
+Compare a [`slice`] to a [`slice`], returning collection elements with common values. This is frequently used when comparing taxonomy terms.
+
+For example, to return a collection of pages where any of the terms in the "genres" taxonomy are "suspense" or "romance":
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $genres := slice "suspense" "romance" }}
+{{ $pages := where $books "Params.genres" "intersect" $genres }}
+```
+
+## Regular expression comparison
+
++{{< new-in 0.116.0 />}}
+
+To return a collection of pages where the "author" page parameter begins with either "victor" or "Victor":
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }}
+```
+
+{{% include "functions/_common/regular-expressions.md" %}}
+
+{{% note %}}
+Use the `like` operator to compare string values. Comparing other data types will result in an empty collection.
+{{% /note %}}
+
+## Date comparison
+
+### Predefined dates
+
+There are four predefined front matter dates: [`date`], [`publishDate`], [`lastmod`], and [`expiryDate`]. Regardless of the front matter data format (TOML, YAML, or JSON) these are [`time.Time`] values, allowing precise comparisons.
+
+[`date`]: /methods/page/date/
+[`publishdate`]: /methods/page/publishdate/
+[`lastmod`]: /methods/page/lastmod/
+[`expirydate`]: /methods/page/expirydate/
+[`time.Time`]: https://pkg.go.dev/time#Time
+
+For example, to return a collection of pages that were created before the current year:
+
+```go-html-template
+{{ $startOfYear := time.AsTime (printf "%d-01-01" now.Year) }}
+{{ $pages := where .Site.RegularPages "Date" "lt" $startOfYear }}
+```
+
+### Custom dates
+
+With custom front matter dates, the comparison depends on the front matter data format (TOML, YAML, or JSON).
+
+{{% note %}}
+Using TOML for pages with custom front matter dates enables precise date comparisons.
+{{% /note %}}
+
+With TOML, date values are first-class citizens. TOML has a date data type while JSON and YAML do not. If you quote a TOML date, it is a string. If you do not quote a TOML date value, it is [`time.Time`] value, enabling precise comparisons.
+
+In the TOML example below, note that the event date is not quoted.
+
+{{< code file="content/events/2024-user-conference.md" >}}
++++
+title = '2024 User Conference"
+eventDate = 2024-04-01
++++
+{{< /code >}}
+
+To return a collection of future events:
+
+```go-html-template
+{{ $events := where .Site.RegularPages "Type" "events" }}
+{{ $futureEvents := where $events "Params.eventDate" "gt" now }}
+```
+
+When working with YAML or JSON, or quoted TOML values, custom dates are strings; you cannot compare them with `time.Time` values. String comparisons may be possible if the custom date layout is consistent from one page to the next. To be safe, filter the pages by ranging through the collection:
+
+```go-html-template
+{{ $events := where .Site.RegularPages "Type" "events" }}
+{{ $futureEvents := slice }}
+{{ range $events }}
+ {{ if gt (time.AsTime .Params.eventDate) now }}
+ {{ $futureEvents = $futureEvents | append . }}
+ {{ end }}
+{{ end }}
+```
+
+## Nil comparison
+
+To return a collection of pages where the "color" parameter is present in front matter, compare to `nil`:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.color" "ne" nil }}
+```
+
+To return a collection of pages where the "color" parameter is not present in front matter, compare to `nil`:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.color" "eq" nil }}
+```
+
+In both examples above, note that `nil` is not quoted.
+
+## Nested comparison
+
+These are equivalent:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Type" "tutorials" }}
+{{ $pages = where $pages "Params.level" "eq" "beginner" }}
+```
+
+```go-html-template
+{{ $pages := where (where .Site.RegularPages "Type" "tutorials") "Params.level" "eq" "beginner" }}
+```
+
+## Portable section comparison
+
+Useful for theme authors, avoid hardcoding section names by using the `where` function with the [`MainSections`] method on a `Site` object.
+
+[`MainSections`]: /methods/site/mainsections/
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "in" .Site.MainSections }}
+```
+
+With this construct, a theme author can instruct users to specify their main sections in the site configuration:
+
+{{< code-toggle file=hugo >}}
+[params]
+mainSections = ['blog','galleries']
+{{< /code-toggle >}}
+
+If `params.mainSections` is not defined in the site configuration, the `MainSections` method returns a slice with one element---the top level section with the most pages.
+
+## Boolean/undefined comparison
+
+Consider this site content:
+
+```text
+content/
+├── posts/
+│ ├── _index.md
+│ ├── post-1.md <-- front matter: exclude = false
+│ ├── post-2.md <-- front matter: exclude = true
+│ └── post-3.md <-- front matter: exclude not defined
+└── _index.md
+```
+
+The first two pages have an "exclude" field in front matter, but the last page does not. When testing for _equality_, the third page is _excluded_ from the result. When testing for _inequality_, the third page is _included_ in the result.
+
+### Equality test
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "eq" false }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "eq" true }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-2/">Post 2</a></li>
+</ul>
+```
+
+### Inequality test
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "ne" false }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-2/">Post 2</a></li>
+ <li><a href="/posts/post-3/">Post 3</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "ne" true }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+ <li><a href="/posts/post-3/">Post 3</a></li>
+</ul>
+```
+
+To exclude a page with an undefined field from a boolean _inequality_ test:
+
+1. Create a collection using a boolean comparison
+1. Create a collection using a nil comparison
+1. Subtract the second collection from the first collection using the [`collections.Complement`] function.
+
+[`collections.Complement`]: /functions/collections/complement/
+
+This template:
+
+```go-html-template
+{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" true }}
+{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
+<ul>
+ {{ range $p1 | complement $p2 }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" false }}
+{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
+<ul>
+ {{ range $p1 | complement $p2 }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 2</a></li>
+</ul>
+```
--- /dev/null
- related:
- - functions/hash/Xxhash
- - functions/crypto/HMAC
- - functions/crypto/MD5
- - functions/crypto/SHA1
- - functions/crypto/SHA256
+---
+title: crypto.FNV32a
+description: Returns the 32-bit FNV (Fowler–Noll–Vo) non-cryptographic hash of the given string.
+categories: []
+keywords: []
+action:
+ aliases: []
- expiryDate: 2025-07-31 # deprecated 2024-07-31
++ related: []
+ returnType: int
+ signatures: [crypto.FNV32a STRING]
-
- ```go-html-template
- {{ crypto.FNV32a "Hello world" }} → 1498229191
- ```
++expiryDate: 2026-07-31 # deprecated 2024-07-31 in v0.129.0
+---
+
+{{% deprecated-in 0.129.0 %}}
+Use [`hash.FNV32a`] instead.
+
+[`hash.FNV32a`]: /functions/hash/FNV32a/
+{{% /deprecated-in %}}
--- /dev/null
- {{< new-in 0.128.0 >}}
+---
+title: css.PostCSS
+description: Processes the given resource with PostCSS using any PostCSS plugin.
+categories: []
+keywords: []
+action:
+ aliases: [postCSS]
+ related:
+ - functions/css/Sass
+ - functions/css/TailwindCSS
+ returnType: resource.Resource
+ signatures: ['css.PostCSS [OPTIONS] RESOURCE']
+toc: true
+---
+
- : Create a PostCSS configuration file in the root of your project. You must name this file `postcss.config.js` or another [supported file name]. For example:
++{{< new-in 0.128.0 />}}
+
+```go-html-template
+{{ with resources.Get "css/main.css" | postCSS }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}">
+{{ end }}
+```
+
+## Setup
+
+Follow the steps below to transform CSS using any of the available [PostCSS plugins].
+
++[postcss plugins]: https://postcss.org/docs/postcss-plugins
++
+Step 1
+: Install [Node.js].
+
++[node.js]: https://nodejs.org/en/download
++
+Step 2
+: Install the required Node.js packages in the root of your project. For example, to add vendor prefixes to your CSS rules:
+
+```sh
+npm i -D postcss postcss-cli autoprefixer
+```
+
+Step 3
- ```js
++: Create a PostCSS configuration file in the root of your project.
+
- ```
++{{< code file=postcss.config.js >}}
+module.exports = {
+ plugins: [
+ require('autoprefixer')
+ ]
+};
- const purgecss = require('@fullhuman/postcss-purgecss');
++{{< /code >}}
+
+{{% note %}}
+{{% include "functions/resources/_common/postcss-windows-warning.md" %}}
+{{% /note %}}
+
+Step 4
+: Place your CSS file within the `assets/css` directory.
+
+Step 5
+: Process the resource with PostCSS:
+
+```go-html-template
+{{ with resources.Get "css/main.css" | postCSS }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}">
+{{ end }}
+```
+
+## Options
+
+The `css.PostCSS` method takes an optional map of options.
+
+config
+: (`string`) The directory that contains the PostCSS configuration file. Default is the root of the project directory.
+
+noMap
+: (`bool`) Default is `false`. If `true`, disables inline sourcemaps.
+
+inlineImports
+: (`bool`) Default is `false`. Enable inlining of @import statements. It does so recursively, but will only import a file once. URL imports (e.g. `@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');`) and imports with media queries will be ignored. Note that this import routine does not care about the CSS spec, so you can have @import anywhere in the file. Hugo will look for imports relative to the module mount and will respect theme overrides.
+
+skipInlineImportsNotFound
+: (`bool`) Default is `false`. Before Hugo 0.99.0 when `inlineImports` was enabled and we failed to resolve an import, we logged it as a warning. We now fail the build. If you have regular CSS imports in your CSS that you want to preserve, you can either use imports with URL or media queries (Hugo does not try to resolve those) or set `skipInlineImportsNotFound` to true.
+
+```go-html-template
+{{ $opts := dict "config" "config-directory" "noMap" true }}
+{{ with resources.Get "css/main.css" | postCSS $opts }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}">
+{{ end }}
+```
+
+## No configuration file
+
+To avoid using a PostCSS configuration file, you can specify a minimal configuration using the options map.
+
+use
+: (`string`) A space-delimited list of PostCSS plugins to use.
+
+parser
+: (`string`) A custom PostCSS parser.
+
+stringifier
+: (`string`) A custom PostCSS stringifier.
+
+syntax
+: (`string`) Custom postcss syntax.
+
+```go-html-template
+{{ $opts := dict "use" "autoprefixer postcss-color-alpha" }}
+{{ with resources.Get "css/main.css" | postCSS $opts }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}">
+{{ end }}
+```
+
+## Check environment
+
+The current Hugo environment name (set by `--environment` or in configuration or OS environment) is available in the Node context, which allows constructs like this:
+
+```js
+const autoprefixer = require('autoprefixer');
- autoprefixer,
- process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null
+module.exports = {
+ plugins: [
-
- [node.js]: https://nodejs.org/en/download
- [postcss plugins]: https://postcss.org/docs/postcss-plugins
- [supported file name]: https://github.com/postcss/postcss-load-config#usage
- [transpile to CSS]: /functions/css/sass/
++ process.env.HUGO_ENVIRONMENT !== 'development' ? autoprefixer : null
+ ]
+}
+```
--- /dev/null
- {{< new-in 0.128.0 >}}
+---
+title: css.Sass
+description: Transpiles Sass to CSS.
+categories: []
+keywords: []
+action:
+ aliases: [toCSS]
+ related:
+ - functions/resources/Fingerprint
+ - functions/resources/Minify
+ - functions/css/PostCSS
+ - functions/resources/PostProcess
+ returnType: resource.Resource
+ signatures: ['css.Sass [OPTIONS] RESOURCE']
+toc: true
+---
+
- {{ $opts := dict "transpiler" "libsass" "targetPath" "css/style.css" }}
++{{< new-in 0.128.0 />}}
+
+```go-html-template
+{{ with resources.Get "sass/main.scss" }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | minify | fingerprint }}
++ {{ $opts := dict
++ "enableSourceMap" (not hugo.IsProduction)
++ "outputStyle" (cond hugo.IsProduction "compressed" "expanded")
++ "targetPath" "css/main.css"
++ "transpiler" "libsass"
++ }}
+ {{ with . | toCSS $opts }}
- : (`slice`) {{< new-in 0.139.0 >}} A slice of deprecation IDs to silence. The deprecation IDs are printed to in the warning message, e.g "import" in `WARN Dart Sass: DEPRECATED [import] ...`. This is for Dart Sass only.
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
+ {{ end }}
++ {{ else }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}">
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language.
+
+Sass has two forms of syntax: [SCSS] and [indented]. Hugo supports both.
+
+[scss]: https://sass-lang.com/documentation/syntax#scss
+[indented]: https://sass-lang.com/documentation/syntax#the-indented-syntax
+
+## Options
+
+transpiler
+: (`string`) The transpiler to use, either `libsass` (default) or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass) below.
+
+targetPath
+: (`string`) If not set, the transformed resource's target path will be the original path of the asset file with its extension replaced by `.css`.
+
+vars
+: (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
+
+```scss
+// LibSass
+@import "hugo:vars";
+
+// Dart Sass
+@use "hugo:vars" as v;
+```
+
+outputStyle
+: (`string`) Output styles available to LibSass include `nested` (default), `expanded`, `compact`, and `compressed`. Output styles available to Dart Sass include `expanded` (default) and `compressed`.
+
+precision
+: (`int`) Precision of floating point math. Not applicable to Dart Sass.
+
+enableSourceMap
+: (`bool`) If `true`, generates a source map.
+
+sourceMapIncludeSources
+: (`bool`) If `true`, embeds sources in the generated source map. Not applicable to LibSass.
+
+includePaths
+: (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
+
+```go-html-template
+{{ $opts := dict
+ "transpiler" "dartsass"
+ "targetPath" "css/style.css"
+ "vars" site.Params.styles
+ "enableSourceMap" (not hugo.IsProduction)
+ "includePaths" (slice "node_modules/bootstrap/scss")
+}}
+{{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
+{{ end }}
+```
+
+silenceDeprecations
- The extended version of Hugo includes [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass].
++: (`slice`) {{< new-in 0.139.0 />}} A slice of deprecation IDs to silence. The deprecation IDs are printed to in the warning message, e.g "import" in `WARN Dart Sass: DEPRECATED [import] ...`. This is for Dart Sass only.
+
+## Dart Sass
+
- {{ $opts := dict "transpiler" "dartsass" "targetPath" "css/style.css" }}
++Hugo's extended and extended/deploy editions include [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass].
+
+Use the latest features of the Sass language by installing Dart Sass in your development and production environments.
+
+### Installation overview
+
+Dart Sass is compatible with Hugo v0.114.0 and later.
+
+If you have been using Embedded Dart Sass[^1] with Hugo v0.113.0 and earlier, uninstall Embedded Dart Sass, then install Dart Sass. If you have installed both, Hugo will use Dart Sass.
+
+If you install Hugo as a [Snap package] there is no need to install Dart Sass. The Hugo Snap package includes Dart Sass.
+
+[^1]: In 2023, the Sass team deprecated Embedded Dart Sass in favor of Dart Sass.
+
+### Installing in a development environment
+
+When you install Dart Sass somewhere in your PATH, Hugo will find it.
+
+OS|Package manager|Site|Installation
+:--|:--|:--|:--
+Linux|Homebrew|[brew.sh]|`brew install sass/sass/sass`
+Linux|Snap|[snapcraft.io]|`sudo snap install dart-sass`
+macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass`
+Windows|Chocolatey|[chocolatey.org]|`choco install sass`
+Windows|Scoop|[scoop.sh]|`scoop install sass`
+
+You may also install [prebuilt binaries] for Linux, macOS, and Windows.
+
+Run `hugo env` to list the active transpilers.
+
+### Installing in a production environment
+
+For [CI/CD] deployments (e.g., GitHub Pages, GitLab Pages, Netlify, etc.) you must edit the workflow to install Dart Sass before Hugo builds the site[^2]. Some providers allow you to use one of the package managers above, or you can download and extract one of the prebuilt binaries.
+
+[^2]: You do not have to do this if (a) you have not modified the assets cache location, and (b) you have not set `useResourceCacheWhen` to `never` in your [site configuration], and (c) you add and commit your `resources` directory to your repository.
+
+#### GitHub Pages
+
+To install Dart Sass for your builds on GitHub Pages, add this step to the GitHub Pages workflow file:
+
+```yaml
+- name: Install Dart Sass
+ run: sudo snap install dart-sass
+```
+
+If you are using GitHub Pages for the first time with your repository, GitHub provides a [starter workflow] for Hugo that includes Dart Sass. This is the simplest way to get started.
+
+#### GitLab Pages
+
+To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file should look something like this:
+
+```yaml
+variables:
+ HUGO_VERSION: 0.141.0
+ DART_SASS_VERSION: 1.83.4
+ GIT_DEPTH: 0
+ GIT_STRATEGY: clone
+ GIT_SUBMODULE_STRATEGY: recursive
+ TZ: America/Los_Angeles
+image:
+ name: golang:1.20-buster
+pages:
+ script:
+ # Install Dart Sass
+ - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - cp -r dart-sass/* /usr/local/bin
+ - rm -rf dart-sass*
+ # Install Hugo
+ - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - apt install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ # Build
+ - hugo --gc --minify
+ artifacts:
+ paths:
+ - public
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+```
+
+#### Netlify
+
+To install Dart Sass for your builds on Netlify, the `netlify.toml` file should look something like this:
+
+```toml
+[build.environment]
+HUGO_VERSION = "0.141.0"
+DART_SASS_VERSION = "1.83.4"
+NODE_VERSION = "22"
+TZ = "America/Los_Angeles"
+
+[build]
+publish = "public"
+command = """\
+ curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ export PATH=/opt/build/repo/dart-sass:$PATH && \
+ hugo --gc --minify \
+ """
+```
+
+### Example
+
+To transpile with Dart Sass, set `transpiler` to `dartsass` in the options map passed to `css.Sass`. For example:
+
+```go-html-template
+{{ with resources.Get "sass/main.scss" }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | minify | fingerprint }}
++ {{ $opts := dict
++ "enableSourceMap" (not hugo.IsProduction)
++ "outputStyle" (cond hugo.IsProduction "compressed" "expanded")
++ "targetPath" "css/main.css"
++ "transpiler" "dartsass"
++ }}
+ {{ with . | toCSS $opts }}
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
+ {{ end }}
++ {{ else }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}">
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+### Miscellaneous
+
+If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model.
+
+[brew.sh]: https://brew.sh/
+[chocolatey.org]: https://community.chocolatey.org/packages/sass
+[ci/cd]: https://en.wikipedia.org/wiki/CI/CD
+[dart sass]: https://sass-lang.com/dart-sass
+[libsass]: https://sass-lang.com/libsass
+[prebuilt binaries]: https://github.com/sass/dart-sass/releases/latest
+[scoop.sh]: https://scoop.sh/#/apps?q=sass
+[site configuration]: /getting-started/configuration/#configure-build
+[snap package]: /installation/linux/#snap
+[snapcraft.io]: https://snapcraft.io/dart-sass
+[starter workflow]: https://github.com/actions/starter-workflows/blob/main/pages/hugo.yml
--- /dev/null
- {{< new-in 0.128.0 >}}
+---
+title: css.TailwindCSS
+description: Processes the given resource with the Tailwind CSS CLI.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/resources/Fingerprint
+ - functions/resources/Minify
+ - functions/css/PostCSS
+ returnType: resource.Resource
+ signatures: ['css.TailwindCSS [OPTIONS] RESOURCE']
+toc: true
+---
+
- {{% todo %}}remove this admonition when feature is stable.{{% /todo %}}
++{{< new-in 0.128.0 />}}
+
- {{% note %}}
- This is an experimental feature pending the release of TailwindCSS v4.0.
++Use the `css.TailwindCSS` function to process your Tailwind CSS files. This function uses the Tailwind CSS CLI to:
+
- The functionality, configuration requirements, and documentation are subject to change at any time and may be not compatible with prior releases.
- {{% /note %}}
++1. Scan your templates for Tailwind CSS utility class usage.
++1. Compile those utility classes into standard CSS.
++1. Generate an optimized CSS output file.
+
- ## Prerequisites
++## Setup
+
- To use this function you must install the Tailwind CSS CLI v4.0 or later. You may install the CLI as an npm package or as a standalone executable. See the [Tailwind CSS documentation] for details.
++###### Step 1
+
- [Tailwind CSS documentation]: https://tailwindcss.com/docs/installation
++Install the Tailwind CSS CLI v4.0 or later:
+
- {{% note %}}
- Prior to the release of Tailwind CSS v4.0 you must install [v4.0.0-alpha.26](https://github.com/tailwindlabs/tailwindcss/releases/tag/v4.0.0-alpha.26) or later.
++```sh
++npm install --save-dev tailwindcss @tailwindcss/cli
++```
+
- `npm install --save-dev tailwindcss@next @tailwindcss/cli@next`
++The TailwindCSS CLI is also available as a [standalone executable] if you want to use it without installing Node.js.
+
- {{% /note %}}
++[standalone executable]: https://github.com/tailwindlabs/tailwindcss/releases/latest
+
- ## Options
++###### Step 2
+
- minify
- : (`bool`) Whether to optimize and minify the output. Default is `false`.
++Add this to your site configuration:
+
- optimize
- : (`bool`) Whether to optimize the output without minifying. Default is `false`.
++{{< code-toggle file=hugo copy=true >}}
++[[module.mounts]]
++source = "assets"
++target = "assets"
++[[module.mounts]]
++source = "hugo_stats.json"
++target = "assets/notwatching/hugo_stats.json"
++disableWatch = true
++[build.buildStats]
++enable = true
++[[build.cachebusters]]
++source = "assets/notwatching/hugo_stats\\.json"
++target = "css"
++[[build.cachebusters]]
++source = "(postcss|tailwind)\\.config\\.js"
++target = "css"
++{{< /code-toggle >}}
+
- inlineImports
- : (`bool`) Whether to enable inlining of `@import` statements. Inlining is performed recursively, but currently once only per file. It is not possible to import the same file in different scopes (root, media query, etc.). Note that this import routine does not care about the CSS specification, so you can have `@import` statements anywhere in the file. Default is `false`.
+
- skipInlineImportsNotFound
- : (`bool`) When `inlineImports` is enabled, we fail the build if an import cannot be resolved. Enable this option to allow the build to continue and leave the import statement in place. Note that the inline importer does not process URL location or imports with media queries, so those will be left as-is even without enabling this option. Default is `false`.
++###### Step 3
+
- ## Example
++Create a CSS entry file:
+
- Define a [cache buster] in your site configuration:
++{{< code file=assets/css/main.css copy=true >}}
++@import "tailwindcss";
++@source "hugo_stats.json";
++{{< /code >}}
+
- [cache buster]: /getting-started/configuration-build/#configure-cache-busters
++Tailwind CSS respects `.gitignore` files. This means that if `hugo_stats.json` is listed in your `.gitignore` file, Tailwind CSS will ignore it. To make `hugo_stats.json` available to Tailwind CSS you must explicitly source it as shown in the example above.
+
- {{< code-toggle file=hugo >}}
- [[build.cachebusters]]
- source = 'layouts/.*'
- target = 'css'
- {{< /code-toggle >}}
++###### Step 4
+
- Process the resource:
-
- ```go-html-template
- {{ with resources.Get "css/main.css" }}
- {{ $opts := dict "minify" true }}
- {{ with . | css.TailwindCSS $opts }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
++Create a partial template to process the CSS with the Tailwind CSS CLI:
+
- ```
++{{< code file=layouts/partials/css.html copy=true >}}
++{{ with (templates.Defer (dict "key" "global")) }}
++ {{ with resources.Get "css/main.css" }}
++ {{ $opts := dict
++ "minify" hugo.IsProduction
++ "inlineImports" true
++ }}
++ {{ with . | css.TailwindCSS $opts }}
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
++ {{ end }}
++ {{ else }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}">
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
- The example above publishes the minified CSS file to `public/css/main.css`.
++{{< /code >}}
++
++###### Step 5
++
++Call the partial template from your base template:
+
- See [this repository] for more information about the integration with Tailwind CSS v4.0.
++{{< code file=layouts/default/baseof.html >}}
++<head>
++ ...
++ {{ partialCached "css.html" . }}
++ ...
++<head>
++{{< /code >}}
+
- [this repository]: https://github.com/bep/hugo-testing-tailwindcss-v4
++###### Step 6
+
++Optionally create a `tailwind.config.js` file in the root of your project as shown below. This is necessary if you use the [Tailwind CSS IntelliSense
++extension] for Visual Studio Code.
++
++[Tailwind CSS IntelliSense
++extension]: https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
++
++{{< code file=tailwind.config.js copy=true >}}
++/*
++This file is present to satisfy a requirement of the Tailwind CSS IntelliSense
++extension for Visual Studio Code.
++
++https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
++
++The rest of this file is intentionally empty.
++*/
++{{< /code >}}
++
++## Options
++
++minify
++: (`bool`) Whether to optimize and minify the output. Default is `false`.
++
++optimize
++: (`bool`) Whether to optimize the output without minifying. Default is `false`.
++
++inlineImports
++: (`bool`) Whether to enable inlining of `@import` statements. Inlining is performed recursively, but currently once only per file. It is not possible to import the same file in different scopes (root, media query, etc.). Note that this import routine does not care about the CSS specification, so you can have `@import` statements anywhere in the file. Default is `false`.
++
++skipInlineImportsNotFound
++: (`bool`) When `inlineImports` is enabled, we fail the build if an import cannot be resolved. Enable this option to allow the build to continue and leave the import statement in place. Note that the inline importer does not process URL location or imports with media queries, so those will be left as-is even without enabling this option. Default is `false`.
--- /dev/null
- related:
- - functions/data/GetJSON
- - functions/resources/Get
- - functions/resources/GetRemote
- - methods/page/Resources
+---
+title: data.GetCSV
+description: Returns an array of arrays from a local or remote CSV file, or an error if the file does not exist.
+categories: []
+keywords: []
+action:
+ aliases: [getCSV]
- expiryDate: 2025-02-19 # deprecated 2024-02-19
++ related: []
+ returnType: '[][]string'
+ signatures: ['data.GetCSV SEPARATOR INPUT... [OPTIONS]']
+toc: true
++expiryDate: 2026-02-19 # deprecated 2024-02-19 in v0.123.0
+---
+
+{{% deprecated-in 0.123.0 %}}
+Instead, use [`transform.Unmarshal`] with a [global resource](g), [page resource](g), or [remote resource](g).
+
+See the [remote data example].
+
+[`transform.Unmarshal`]: /functions/transform/unmarshal/
+[remote data example]: /functions/resources/getremote/#remote-data
+{{% /deprecated-in %}}
+
+Given the following directory structure:
+
+```text
+my-project/
+└── other-files/
+ └── pets.csv
+```
+
+Access the data with either of the following:
+
+```go-html-template
+{{ $data := getCSV "," "other-files/pets.csv" }}
+{{ $data := getCSV "," "other-files/" "pets.csv" }}
+```
+
+{{% note %}}
+When working with local data, the file path is relative to the working directory.
+
+You must not place CSV files in the project's `data` directory.
+{{% /note %}}
+
+Access remote data with either of the following:
+
+```go-html-template
+{{ $data := getCSV "," "https://example.org/pets.csv" }}
+{{ $data := getCSV "," "https://example.org/" "pets.csv" }}
+```
+
+The resulting data structure is an array of arrays:
+
+```json
+[
+ ["name","type","breed","age"],
+ ["Spot","dog","Collie","3"],
+ ["Felix","cat","Malicious","7"]
+]
+```
+
+## Options
+
+Add headers to the request by providing an options map:
+
+```go-html-template
+{{ $opts := dict "Authorization" "Bearer abcd" }}
+{{ $data := getCSV "," "https://example.org/pets.csv" $opts }}
+```
+
+Add multiple headers using a slice:
+
+```go-html-template
+{{ $opts := dict "X-List" (slice "a" "b" "c") }}
+{{ $data := getCSV "," "https://example.org/pets.csv" $opts }}
+```
+
+## Global resource alternative
+
+Consider using the [`resources.Get`] function with [`transform.Unmarshal`] when accessing a global resource.
+
+```text
+my-project/
+└── assets/
+ └── data/
+ └── pets.csv
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $p := "data/pets.csv" }}
+{{ with resources.Get $p }}
+ {{ $opts := dict "delimiter" "," }}
+ {{ $data = . | transform.Unmarshal $opts }}
+{{ else }}
+ {{ errorf "Unable to get resource %q" $p }}
+{{ end }}
+```
+
+## Page resource alternative
+
+Consider using the [`Resources.Get`] method with [`transform.Unmarshal`] when accessing a page resource.
+
+```text
+my-project/
+└── content/
+ └── posts/
+ └── my-pets/
+ ├── index.md
+ └── pets.csv
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $p := "pets.csv" }}
+{{ with .Resources.Get $p }}
+ {{ $opts := dict "delimiter" "," }}
+ {{ $data = . | transform.Unmarshal $opts }}
+{{ else }}
+ {{ errorf "Unable to get resource %q" $p }}
+{{ end }}
+```
+
+## Remote resource alternative
+
+Consider using the [`resources.GetRemote`] function with [`transform.Unmarshal`] when accessing a remote resource to improve error handling and cache control.
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/pets.csv" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $opts := dict "delimiter" "," }}
+ {{ $data = . | transform.Unmarshal $opts }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+[`Resources.Get`]: /methods/page/resources/
+[`resources.GetRemote`]: /functions/resources/getremote/
+[`resources.Get`]: /functions/resources/get/
+[`transform.Unmarshal`]: /functions/transform/unmarshal/
--- /dev/null
- related:
- - functions/data/GetCSV
- - functions/resources/Get
- - functions/resources/GetRemote
- - methods/page/Resources
+---
+title: data.GetJSON
+description: Returns a JSON object from a local or remote JSON file, or an error if the file does not exist.
+categories: []
+keywords: []
+action:
+ aliases: [getJSON]
- expiryDate: 2025-02-19 # deprecated 2024-02-19
++ related: []
+ returnType: any
+ signatures: ['data.GetJSON INPUT... [OPTIONS]']
+toc: true
++expiryDate: 2026-02-19 # deprecated 2024-02-19 in v0.123.0
+---
+
+{{% deprecated-in 0.123.0 %}}
+Instead, use [`transform.Unmarshal`] with a [global resource](g), [page resource](g), or [remote resource](g).
+
+See the [remote data example].
+
+[`transform.Unmarshal`]: /functions/transform/unmarshal/
+[remote data example]: /functions/resources/getremote/#remote-data
+{{% /deprecated-in %}}
+
+Given the following directory structure:
+
+```text
+my-project/
+└── other-files/
+ └── books.json
+```
+
+Access the data with either of the following:
+
+```go-html-template
+{{ $data := getJSON "other-files/books.json" }}
+{{ $data := getJSON "other-files/" "books.json" }}
+```
+
+{{% note %}}
+When working with local data, the file path is relative to the working directory.
+{{% /note %}}
+
+Access remote data with either of the following:
+
+```go-html-template
+{{ $data := getJSON "https://example.org/books.json" }}
+{{ $data := getJSON "https://example.org/" "books.json" }}
+```
+
+The resulting data structure is a JSON object:
+
+```json
+[
+ {
+ "author": "Victor Hugo",
+ "rating": 5,
+ "title": "Les Misérables"
+ },
+ {
+ "author": "Victor Hugo",
+ "rating": 4,
+ "title": "The Hunchback of Notre Dame"
+ }
+]
+```
+
+## Options
+
+Add headers to the request by providing an options map:
+
+```go-html-template
+{{ $opts := dict "Authorization" "Bearer abcd" }}
+{{ $data := getJSON "https://example.org/books.json" $opts }}
+```
+
+Add multiple headers using a slice:
+
+```go-html-template
+{{ $opts := dict "X-List" (slice "a" "b" "c") }}
+{{ $data := getJSON "https://example.org/books.json" $opts }}
+```
+
+## Global resource alternative
+
+Consider using the [`resources.Get`] function with [`transform.Unmarshal`] when accessing a global resource.
+
+```text
+my-project/
+└── assets/
+ └── data/
+ └── books.json
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $p := "data/books.json" }}
+{{ with resources.Get $p }}
+ {{ $data = . | transform.Unmarshal }}
+{{ else }}
+ {{ errorf "Unable to get resource %q" $p }}
+{{ end }}
+```
+
+## Page resource alternative
+
+Consider using the [`Resources.Get`] method with [`transform.Unmarshal`] when accessing a page resource.
+
+```text
+my-project/
+└── content/
+ └── posts/
+ └── reading-list/
+ ├── books.json
+ └── index.md
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $p := "books.json" }}
+{{ with .Resources.Get $p }}
+ {{ $data = . | transform.Unmarshal }}
+{{ else }}
+ {{ errorf "Unable to get resource %q" $p }}
+{{ end }}
+```
+
+## Remote resource alternative
+
+Consider using the [`resources.GetRemote`] function with [`transform.Unmarshal`] when accessing a remote resource to improve error handling and cache control.
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books.json" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+[`Resources.Get`]: /methods/page/resources/
+[`resources.GetRemote`]: /functions/resources/getremote/
+[`resources.Get`]: /functions/resources/get/
+[`transform.Unmarshal`]: /functions/transform/unmarshal/
--- /dev/null
- {{< new-in 0.120.0 >}}
+---
+title: debug.Timer
+description: Creates a named timer that reports elapsed time to the console.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: debug.Timer
+ signatures: [debug.Timer NAME]
+---
+
++{{< new-in 0.120.0 />}}
+
+Use the `debug.Timer` function to determine execution time for a block of code, useful for finding performance bottlenecks in templates.
+
+The timer starts when you instantiate it, and stops when you call its `Stop` method.
+
+```go-html-template
+{{ $t := debug.Timer "TestSqrt" }}
+{{ range seq 2000 }}
+ {{ $f := math.Sqrt . }}
+{{ end }}
+{{ $t.Stop }}
+```
+
+Use the `--logLevel info` command line flag when you build the site.
+
+```sh
+hugo --logLevel info
+```
+
+The results are displayed in the console at the end of the build. You can have as many timers as you want and if you don't stop them, they will be stopped at the end of build.
+
+```text
+INFO timer: name TestSqrt count 1002 duration 2.496017496s average 2.491035ms median 2.282291ms
+```
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: fmt.Warnidf
+description: Log a suppressible WARNING from a template.
+categories: []
+keywords: []
+action:
+ aliases: [warnidf]
+ related:
+ - functions/fmt/Errorf
+ - functions/fmt/Erroridf
+ - functions/fmt/Warnf
+ returnType: string
+ signatures: ['fmt.Warnidf ID FORMAT [INPUT]']
+aliases: [/functions/warnidf]
+---
+
++{{< new-in 0.123.0 />}}
+
+{{% include "functions/fmt/_common/fmt-layout.md" %}}
+
+The `warnidf` function evaluates the format string, then prints the result to the WARNING log. Unlike the [`warnf`] function, you may suppress warnings logged by the `warnidf` function by adding the message ID to the `ignoreLogs` array in your site configuration.
+
+This template code:
+
+```go-html-template
+{{ warnidf "warning-42" "You should consider fixing this." }}
+```
+
+Produces this console log:
+
+```text
+WARN You should consider fixing this.
+You can suppress this warning by adding the following to your site configuration:
+ignoreLogs = ['warning-42']
+```
+
+To suppress this message:
+
+{{< code-toggle file=hugo >}}
+ignoreLogs = ["warning-42"]
+{{< /code-toggle >}}
+
+[`warnf`]: /functions/fmt/warnf/
--- /dev/null
- {{< new-in 0.141.0 >}}
+---
+title: try
+description: Returns a TryValue object after evaluating the given expression.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: TryValue
+ signatures: ['try EXPRESSION']
+toc: true
+---
+
++{{< new-in 0.141.0 />}}
+
+The `try` statement is a non-standard extension to Go's [text/template] package. It introduces a mechanism for handling errors within templates, mimicking the `try-catch` constructs found in other programming languages.
+
+[text/template]: https://pkg.go.dev/text/template
+
+## Methods
+
+The `TryValue` object encapsulates the result of evaluating the expression, and provides two methods:
+
+Err
+: (`string`) Returns a string representation of the error thrown by the expression, if an error occurred, or returns `nil` if the expression evaluated without errors.
+
+Value
+: (`any`) Returns the result of the expression if the evaluation was successful, or returns `nil` if an error occurred while evaluating the expression.
+
+## Explanation
+
+By way of example, let's divide a number by zero:
+
+```go-html-template
+{{ $x := 1 }}
+{{ $y := 0 }}
+{{ $result := div $x $y }}
+{{ printf "%v divided by %v equals %v" $x $y .Value }}
+```
+
+As expected, the example above throws an error and fails the build:
+
+```terminfo
+Error: error calling div: can't divide the value by 0
+```
+
+Instead of failing the build, we can catch the error and emit a warning:
+
+```go-html-template
+{{ $x := 1 }}
+{{ $y := 0 }}
+{{ with try (div $x $y) }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else }}
+ {{ printf "%v divided by %v equals %v" $x $y .Value }}
+ {{ end }}
+{{ end }}
+```
+
+The error thrown by the expression is logged to the console as a warning:
+
+```terminfo
+WARN error calling div: can't divide the value by 0
+```
+
+Now let's change the arguments to avoid dividing by zero:
+
+```go-html-template
+{{ $x := 42 }}
+{{ $y := 6 }}
+{{ with try (div $x $y) }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else }}
+ {{ printf "%v divided by %v equals %v" $x $y .Value }}
+ {{ end }}
+{{ end }}
+```
+
+Hugo renders the above to:
+
+```html
+42 divided by 6 equals 7
+```
+
+## Example
+
+Error handling is essential when using the [`resources.GetRemote`] function to capture remote resources such as data or images. When calling this function, if the HTTP request fails, Hugo will fail the build.
+
+[`resources.GetRemote`]: /functions/resources/getremote/
+
+Instead of failing the build, we can catch the error and emit a warning:
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else with .Value }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ else }}
+ {{ warnf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+In the above, note that the [context](g) within the last conditional block is the `TryValue` object returned by the `try` statement. At this point neither the `Err` nor `Value` methods returned anything, so the current context is not useful. Use the `$` to access the [template context] if needed.
+
+[template context]: /templates/introduction/#template-context
+
+{{% note %}}
+Hugo does not classify an HTTP response with status code 404 as an error. In this case `resources.GetRemote` returns nil.
+{{% /note %}}
--- /dev/null
- {{< new-in 0.120.0 >}}
+---
+title: hugo.IsDevelopment
+description: Reports whether the current running environment is "development".
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/hugo/IsProduction
+ - functions/hugo/Environment
+ returnType: bool
+ signatures: [hugo.IsDevelopment]
+---
+
++{{< new-in 0.120.0 />}}
+
+```go-html-template
+{{ hugo.IsDevelopment }} → true/false
+```
--- /dev/null
- description: Reports whether the Hugo binary is the extended version.
+---
+title: hugo.IsExtended
++description: Reports whether the Hugo binary is either the extended or extended/deploy edition.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: bool
+ signatures: [hugo.IsExtended]
+---
+
+```go-html-template
+{{ hugo.IsExtended }} → true/false
+```
--- /dev/null
- {{< new-in v0.124.0 >}}
+---
+title: hugo.IsMultihost
+description: Reports whether each configured language has a unique base URL.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - /functions/hugo/IsMultilingual
+ returnType: bool
+ signatures: [hugo.IsMultihost]
+---
+
++{{< new-in 0.124.0 />}}
+
+Site configuration:
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'de'
+defaultContentLanguageInSubdir = true
+[languages]
+ [languages.de]
+ baseURL = 'https://de.example.org/'
+ languageCode = 'de-DE'
+ languageName = 'Deutsch'
+ title = 'Projekt Dokumentation'
+ weight = 1
+ [languages.en]
+ baseURL = 'https://en.example.org/'
+ languageCode = 'en-US'
+ languageName = 'English'
+ title = 'Project Documentation'
+ weight = 2
+{{< /code-toggle >}}
+
+Template:
+
+```go-html-template
+{{ hugo.IsMultihost }} → true
+```
--- /dev/null
- {{< new-in v0.124.0 >}}
+---
+title: hugo.IsMultilingual
+description: Reports whether there are two or more configured languages.
+categories: []
+keywords: []
+action:
+ related:
+ - /functions/hugo/IsMultihost
+ returnType: bool
+ signatures: [hugo.IsMultilingual]
+---
+
++{{< new-in 0.124.0 />}}
+
+Site configuration:
+
+{{< code-toggle file=hugo >}}
+defaultContentLanguage = 'de'
+defaultContentLanguageInSubdir = true
+[languages]
+ [languages.de]
+ languageCode = 'de-DE'
+ languageName = 'Deutsch'
+ title = 'Projekt Dokumentation'
+ weight = 1
+ [languages.en]
+ languageCode = 'en-US'
+ languageName = 'English'
+ title = 'Project Documentation'
+ weight = 2
+{{< /code-toggle >}}
+
+Template:
+
+```go-html-template
+{{ hugo.IsMultilingual }} → true
+```
--- /dev/null
- {{< new-in 0.120.0 >}}
+---
+title: hugo.IsServer
+description: Reports whether the built-in development server is running.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: bool
+ signatures: [hugo.IsServer]
+---
+
++{{< new-in 0.120.0 />}}
+
+```go-html-template
+{{ hugo.IsServer }} → true/false
+```
--- /dev/null
- description: Returns a global, persistent "scratch pad" to store and manipulate data.
+---
+title: hugo.Store
- - methods/page/store
- - methods/site/store
- - functions/collections/NewScratch
++description: Returns a globally scoped "scratch pad" to store and manipulate data.
+categories: []
+keywords: []
+action:
+ related:
- {{< new-in 0.139.0 >}}
++ - methods/page/Store
++ - methods/site/Store
++ - methods/shortcode/Store
++ - functions/collections/NewScratch
+ returnType: maps.Scratch
+ signatures: [hugo.Store]
+toc: true
+---
+
- The global `hugo.Store` function creates a persistent [scratch pad](g) to store and manipulate data. To create a locally scoped, use the [`newScratch`] function.
-
- [`Scratch`]: /functions/hugo/scratch/
- [`newScratch`]: /functions/collections/newscratch/
++{{< new-in 0.139.0 />}}
+
- Sets the value of a given key.
++Use the `hugo.Store` function to create a globally scoped [scratch pad](g) to store and manipulate data. To create a scratch pad with a different [scope](g), refer to the [scope](#scope) section below.
+
+## Methods
+
+###### Set
+
- Gets the value of a given key.
++Sets the value of the given key.
+
+```go-html-template
+{{ hugo.Store.Set "greeting" "Hello" }}
+```
+
+###### Get
+
- Adds a given value to existing value(s) of the given key.
++Gets the value of the given key.
+
+```go-html-template
+{{ hugo.Store.Set "greeting" "Hello" }}
+{{ hugo.Store.Get "greeting" }} → Hello
+```
+
+###### Add
+
++Adds the given value to the existing value(s) of the given key.
+
+For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
+
+```go-html-template
+{{ hugo.Store.Set "greeting" "Hello" }}
+{{ hugo.Store.Add "greeting" "Welcome" }}
+{{ hugo.Store.Get "greeting" }} → HelloWelcome
+```
+
+```go-html-template
+{{ hugo.Store.Set "total" 3 }}
+{{ hugo.Store.Add "total" 7 }}
+{{ hugo.Store.Get "total" }} → 10
+```
+
+```go-html-template
+{{ hugo.Store.Set "greetings" (slice "Hello") }}
+{{ hugo.Store.Add "greetings" (slice "Welcome" "Cheers") }}
+{{ hugo.Store.Get "greetings" }} → [Hello Welcome Cheers]
+```
+
+###### SetInMap
+
+Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`.
+
+```go-html-template
+{{ hugo.Store.SetInMap "greetings" "english" "Hello" }}
+{{ hugo.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ hugo.Store.Get "greetings" }} → map[english:Hello french:Bonjour]
+```
+
+###### DeleteInMap
+
+Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`.
+
+```go-html-template
+{{ hugo.Store.SetInMap "greetings" "english" "Hello" }}
+{{ hugo.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ hugo.Store.DeleteInMap "greetings" "english" }}
+{{ hugo.Store.Get "greetings" }} → map[french:Bonjour]
+```
+
+###### GetSortedMapValues
+
+Returns an array of values from `key` sorted by `mapKey`.
+
+```go-html-template
+{{ hugo.Store.SetInMap "greetings" "english" "Hello" }}
+{{ hugo.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ hugo.Store.GetSortedMapValues "greetings" }} → [Hello Bonjour]
+```
+
+###### Delete
+
+Removes the given key.
+
+```go-html-template
+{{ hugo.Store.Set "greeting" "Hello" }}
+{{ hugo.Store.Delete "greeting" }}
+```
+
++{{% include "_common/scratch-pad-scope.md" %}}
++
+## Determinate values
+
+The `Store` method is often used to set scratch pad values within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are indeterminate until Hugo renders the page content.
+
+If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable:
+
+```go-html-template
+{{ $noop := .Content }}
+{{ hugo.Store.Get "mykey" }}
+```
+
+You can also trigger content rendering with the `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount` methods. For example:
+
+```go-html-template
+{{ $noop := .WordCount }}
+{{ hugo.Store.Get "mykey" }}
+```
--- /dev/null
- {{< new-in 0.121.2 >}}
+---
+title: images.AutoOrient
+description: Returns an image filter that rotates and flips an image as needed per its EXIF orientation tag.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: [images.AutoOrient]
+toc: true
+---
+
++{{< new-in 0.121.2 />}}
+
+## Usage
+
+Create the filter:
+
+```go-html-template
+{{ $filter := images.AutoOrient }}
+```
+
+{{% include "functions/images/_common/apply-image-filter.md" %}}
+
+{{% note %}}
+When using with other filters, specify `images.AutoOrient` first.
+{{% /note %}}
+
+```go-html-template
+{{ $filters := slice
+ images.AutoOrient
+ (images.Process "resize 200x")
+}}
+{{ with resources.Get "images/original.jpg" }}
+ {{ with images.Filter $filters . }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+## Example
+
+{{< img
+ src="images/examples/landscape-exif-orientation-5.jpg"
+ alt="Zion National Park"
+ filter="AutoOrient"
+ filterArgs=""
+ example=true
+>}}
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: images.Dither
+description: Returns an image filter that dithers an image.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - functions/images/Process
+ - methods/resource/Colors
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: ['images.Dither [OPTIONS]']
+toc: true
+---
+
++{{< new-in 0.123.0 />}}
+
+## Options
+
+colors
+: (`string array`) A slice of two or more colors that make up the dithering palette, each expressed as an RGB or RGBA [hexadecimal] value, with or without a leading hash mark. The default values are opaque black (`000000ff`) and opaque white (`ffffffff`).
+
+[hexadecimal]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
+
+method
+: (`string`) The dithering method. See the [dithering methods](#dithering-methods) section below for a list of the available methods. Default is `FloydSteinberg`.
+
+serpentine
+: (`bool`) Applicable to error diffusion dithering methods, serpentine controls whether the error diffusion matrix is applied in a serpentine manner, meaning that it goes right-to-left every other line. This greatly reduces line-type artifacts. Default is `true`.
+
+strength
+: (`float`) The strength at which to apply the dithering matrix, typically a value in the range [0, 1]. A value of `1.0` applies the dithering matrix at 100% strength (no modification of the dither matrix). The `strength` is inversely proportional to contrast; reducing the strength increases the contrast. Setting `strength` to a value such as `0.8` can be useful to reduce noise in the dithered image. Default is `1.0`.
+
+## Usage
+
+Create the options map:
+
+```go-html-template
+{{ $opts := dict
+ "colors" (slice "222222" "808080" "dddddd")
+ "method" "ClusteredDot4x4"
+ "strength" 0.85
+}}
+```
+
+Create the filter:
+
+```go-html-template
+{{ $filter := images.Dither $opts }}
+```
+
+Or create the filter using the default settings:
+
+```go-html-template
+{{ $filter := images.Dither }}
+```
+
+{{% include "functions/images/_common/apply-image-filter.md" %}}
+
+## Dithering methods
+
+See the [Go documentation] for descriptions of each of the dithering methods below.
+
+[Go documentation]: https://pkg.go.dev/github.com/makeworld-the-better-one/dither/v2#pkg-variables
+
+Error diffusion dithering methods:
+
+- Atkinson
+- Burkes
+- FalseFloydSteinberg
+- FloydSteinberg
+- JarvisJudiceNinke
+- Sierra
+- Sierra2
+- Sierra2_4A
+- Sierra3
+- SierraLite
+- Simple2D
+- StevenPigeon
+- Stucki
+- TwoRowSierra
+
+Ordered dithering methods:
+
+- ClusteredDot4x4
+- ClusteredDot6x6
+- ClusteredDot6x6_2
+- ClusteredDot6x6_3
+- ClusteredDot8x8
+- ClusteredDotDiagonal16x16
+- ClusteredDotDiagonal6x6
+- ClusteredDotDiagonal8x8
+- ClusteredDotDiagonal8x8_2
+- ClusteredDotDiagonal8x8_3
+- ClusteredDotHorizontalLine
+- ClusteredDotSpiral5x5
+- ClusteredDotVerticalLine
+- Horizontal3x5
+- Vertical5x3
+
+## Example
+
+This example uses the default dithering options.
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="Dither"
+ filterArgs=""
+ example=true
+>}}
+
+## Recommendations
+
+Regardless of dithering method, do both of the following to obtain the best results:
+
+1. Scale the image _before_ dithering
+1. Output the image to a lossless format such as GIF or PNG
+
+The example below does both of these, and it sets the dithering palette to the three most dominant colors in the image.
+
+```go-html-template
+{{ with resources.Get "original.jpg" }}
+ {{ $opts := dict
+ "method" "ClusteredDotSpiral5x5"
+ "colors" (first 3 .Colors)
+ }}
+ {{ $filters := slice
+ (images.Process "resize 800x")
+ (images.Dither $opts)
+ (images.Process "png")
+ }}
+ {{ with . | images.Filter $filters }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+For best results, if the dithering palette is grayscale, convert the image to grayscale before dithering.
+
+```go-html-template
+{{ $opts := dict "colors" (slice "222" "808080" "ddd") }}
+{{ $filters := slice
+ (images.Process "resize 800x")
+ (images.Grayscale)
+ (images.Dither $opts)
+ (images.Process "png")
+}}
+{{ with images.Filter $filters . }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
+The example above:
+
+1. Resizes the image to be 800 px wide
+1. Converts the image to grayscale
+1. Dithers the image using the default (`FloydSteinberg`) dithering method with a grayscale palette
+1. Converts the image to the PNG format
--- /dev/null
- {{< new-in 0.141.0 >}}
+---
+title: images.Mask
+description: Returns an image filter that applies a mask to the source image.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: [images.Mask RESOURCE]
+toc: true
+---
+
++{{< new-in 0.141.0 />}}
+
+The `images.Mask` filter applies a mask to an image. Black pixels in the mask make the corresponding areas of the base image transparent, while white pixels keep them opaque. Color images are converted to grayscale for masking purposes. The mask is automatically resized to match the dimensions of the base image.
+
+{{% note %}}
+Of the formats supported by Hugo's imaging pipelie, only PNG and WebP have an alpha channel to support transparency. If your source image has a different format and you require transparent masked areas, convert it to either PNG or WebP as shown in the example below.
+{{% /note %}}
+
+When applying a mask to a non-transparent image format such as JPEG, the masked areas will be filled with the color specified by the `bgColor` parameter in your [site configuration]. You can override that color with a `Process` image filter:
+
+```go-html-template
+{{ $filter := images.Process "#00ff00" }}
+```
+
+[site configuration]: /content-management/image-processing/#imaging-configuration
+
+## Usage
+
+Create a slice of filters, one for WebP conversion and the other for mask application:
+
+```go-html-template
+{{ $filter1 := images.Process "webp" }}
+{{ $filter2 := images.Mask (resources.Get "images/mask.png") }}
+{{ $filters := slice $filter1 $filter2 }}
+```
+
+Apply the filters using the [`images.Filter`] function:
+
+```go-html-template
+{{ with resources.Get "images/original.jpg" }}
+ {{ with . | images.Filter $filters }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+You can also apply the filter using the [`Filter`] method on a 'Resource' object:
+
+```go-html-template
+{{ with resources.Get "images/original.jpg" }}
+ {{ with .Filter $filters }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+[`images.Filter`]: /functions/images/filter/
+[`Filter`]: /methods/resource/filter/
+
+## Example
+
+Mask
+
+{{< img
+ src="images/examples/mask.png"
+ example=false
+>}}
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="mask"
+ filterArgs="images/examples/mask.png"
+ example=true
+>}}
--- /dev/null
- {{< new-in 0.119.0 >}}
+---
+title: images.Opacity
+description: Returns an image filter that changes the opacity of an image.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: [images.Opacity OPACITY]
+toc: true
+---
+
++{{< new-in 0.119.0 />}}
+
+The opacity value must be in the range [0, 1]. A value of `0` produces a transparent image, and a value of `1` produces an opaque image (no transparency).
+
+## Usage
+
+Create the filter:
+
+```go-html-template
+{{ $filter := images.Opacity 0.65 }}
+```
+
+{{% include "functions/images/_common/apply-image-filter.md" %}}
+
+The `images.Opacity` filter is most useful for target formats such as PNG and WebP that support transparency. If the source image does not support transparency, combine this filter with the `images.Process` filter:
+
+```go-html-template
+{{ with resources.Get "images/original.jpg" }}
+ {{ $filters := slice
+ (images.Opacity 0.65)
+ (images.Process "png")
+ }}
+ {{ with . | images.Filter $filters }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+## Example
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="Opacity"
+ filterArgs="0.65"
+ example=true
+>}}
--- /dev/null
- {{< new-in 0.120.0 >}}
+---
+title: images.Padding
+description: Returns an image filter that resizes the image canvas without resizing the image.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: ['images.Padding V1 [V2] [V3] [V4] [COLOR]']
+toc: true
+---
+
++{{< new-in 0.120.0 />}}
+
+The last argument is the canvas color, expressed as an RGB or RGBA [hexadecimal color]. The default value is `ffffffff` (opaque white). The preceding arguments are the padding values, in pixels, using the CSS [shorthand property] syntax. Negative padding values will crop the image.
+
+[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
+[shorthand property]: https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties#edges_of_a_box
+
+## Usage
+
+Create the filter:
+
+```go-html-template
+{{ $filter := images.Padding 20 40 "#976941" }}
+```
+
+{{% include "functions/images/_common/apply-image-filter.md" %}}
+
+Combine with the [`Colors`] method to create a border with one of the image's most dominant colors:
+
+[`Colors`]: /methods/resource/colors/
+
+```go-html-template
+{{ with resources.Get "images/original.jpg" }}
+ {{ $filter := images.Padding 20 40 (index .Colors 2) }}
+ {{ with . | images.Filter $filter }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+## Example
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="Padding"
+ filterArgs="20,40,20,40,#976941"
+ example=true
+>}}
+
+## Other recipes
+
+This example resizes an image to 300px wide, converts it to the WebP format, adds 20px vertical padding and 50px horizontal padding, then sets the canvas color to dark green with 33% opacity.
+
+Conversion to WebP is required to support transparency. PNG and WebP images have an alpha channel; JPEG and GIF do not.
+
+```go-html-template
+{{ $img := resources.Get "images/a.jpg" }}
+{{ $filters := slice
+ (images.Process "resize 300x webp")
+ (images.Padding 20 50 "#0705")
+}}
+{{ $img = $img.Filter $filters }}
+```
+
+To add a 2px gray border to an image:
+
+```go-html-template
+{{ $img = $img.Filter (images.Padding 2 "#777") }}
+```
--- /dev/null
- {{< new-in 0.119.0 >}}
+---
+title: images.Process
+description: Returns an image filter that processes the given image using the given specification.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ - methods/resource/Process
+ returnType: images.filter
+ signatures: [images.Process SPEC]
+toc: true
+---
+
++{{< new-in 0.119.0 />}}
+
+This filter has the same options as the [`Process`] method on a `Resource` object, but using it as a filter may be more effective if you need to apply multiple filters to an image.
+
+[`Process`]: /methods/resource/process/
+
+The process specification is a space-delimited, case-insensitive list of one or more of the following in any sequence:
+
+action
+: Specify zero or one of `crop`, `fill`, `fit`, or `resize`. If you specify an action you must also provide dimensions. See [details](content-management/image-processing/#image-processing-methods).
+
+```go-html-template
+{{ $filter := images.Process "resize 300x" }}
+```
+
+dimensions
+: Required if you specify an action. Provide width _or_ height when using `resize`, else provide both width _and_ height. See [details](/content-management/image-processing/#dimensions).
+
+```go-html-template
+{{ $filter := images.Process "crop 200x200" }}
+```
+
+anchor
+: Use with the `crop` or `fill` action. Specify zero or one of `TopLeft`, `Top`, `TopRight`, `Left`, `Center`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`, or `Smart`. Default is `Smart`. See [details](/content-management/image-processing/#anchor).
+
+```go-html-template
+{{ $filter := images.Process "crop 200x200 center" }}
+```
+
+rotation
+: Typically specify zero or one of `r90`, `r180`, or `r270`. Also supports arbitrary rotation angles. See [details](/content-management/image-processing/#rotation).
+
+```go-html-template
+{{ $filter := images.Process "r90" }}
+{{ $filter := images.Process "crop 200x200 center r90" }}
+```
+
+target format
+: Specify zero or one of `gif`, `jpeg`, `png`, `tiff`, or `webp`. See [details](/content-management/image-processing/#target-format).
+
+```go-html-template
+{{ $filter := images.Process "webp" }}
+{{ $filter := images.Process "crop 200x200 center r90 webp" }}
+```
+
+quality
+: Applicable to JPEG and WebP images. Optionally specify `qN` where `N` is an integer in the range [0, 100]. Default is `75`. See [details](/content-management/image-processing/#quality).
+
+```go-html-template
+{{ $filter := images.Process "q50" }}
+{{ $filter := images.Process "crop 200x200 center r90 webp q50" }}
+```
+
+hint
+: Applicable to WebP images and equivalent to the `-preset` flag for the [`cwebp`] encoder. Specify zero or one of `drawing`, `icon`, `photo`, `picture`, or `text`. Default is `photo`. See [details](/content-management/image-processing/#hint).
+
+[`cwebp`]: https://developers.google.com/speed/webp/docs/cwebp
+
+```go-html-template
+{{ $filter := images.Process "webp" "icon" }}
+{{ $filter := images.Process "crop 200x200 center r90 webp q50 icon" }}
+```
+
+background color
+: When converting a PNG or WebP with transparency to a format that does not support transparency, optionally specify a background color using a 3-digit or a 6-digit hexadecimal color code. Default is `#ffffff` (white). See [details](/content-management/image-processing/#background-color).
+
+```go-html-template
+{{ $filter := images.Process "jpeg #000" }}
+{{ $filter := images.Process "crop 200x200 center r90 q50 jpeg #000" }}
+```
+
+resampling filter
+: Typically specify zero or one of `Box`, `Lanczos`, `CatmullRom`, `MitchellNetravali`, `Linear`, or `NearestNeighbor`. Other resampling filters are available. See [details](/content-management/image-processing/#resampling-filter).
+
+```go-html-template
+{{ $filter := images.Process "resize 300x lanczos" }}
+{{ $filter := images.Process "resize 300x r90 q50 jpeg #000 lanczos" }}
+```
+
+## Usage
+
+Create a filter:
+
+```go-html-template
+{{ $filter := images.Process "resize 256x q40 webp" }}
+```
+
+{{% include "functions/images/_common/apply-image-filter.md" %}}
+
+## Example
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="Process"
+ filterArgs="resize 256x q40 webp"
+ example=true
+>}}
--- /dev/null
- signatures: ['images.QR TEXT OPTIONS']
+---
+title: images.QR
+description: Encodes the given text into a QR code using the specified options, returning an image resource.
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: images.ImageResource
- {{< new-in 0.141.0 >}}
++ signatures: ['images.QR TEXT [OPTIONS]']
+toc: true
+math: true
+---
+
- {{< qr text="https://gohugo.io" class="qrcode" />}}
++{{< new-in 0.141.0 />}}
+
+The `images.QR` function encodes the given text into a [QR code] using the specified options, returning an image resource. The size of the generated image depends on three factors:
+
+- Data length: Longer text necessitates a larger image to accommodate the increased information density.
+- Error correction level: Higher error correction levels enhance the QR code's resistance to damage, but this typically results in a slightly larger image size to maintain readability.
+- Pixels per module: The number of image pixels assigned to each individual module (the smallest unit of the QR code) directly impacts the overall image size. A higher pixel count per module leads to a larger, higher-resolution image.
+
+Although the default option values are sufficient for most applications, you should test the rendered QR code both on-screen and in print.
+
+[QR code]: https://en.wikipedia.org/wiki/QR_code
+
+## Options
+
+level
+: (`string`) The error correction level to use when encoding the text, one of `low`, `medium`, `quartile`, or `high`. Default is `medium`.
+
+Error correction level|Redundancy
+:--|:--|:--
+low|20%
+medium|38%
+quartile|55%
+high|65%
+
+scale
+: (`int`) The number of image pixels per QR code module. Must be greater than or equal to `2`. Default is `4`.
+
+targetDir
+: (`string`) The subdirectory within the [`publishDir`] where Hugo will place the generated image. Use Unix-style slashes (`/`) to separarate path segments. If empty or not provided, the image is placed directly in the `publishDir` root. Hugo automatically creates the necessary subdirectories if they don't exist.
+
+[`publishDir`]: /getting-started/configuration/#publishdir
+
+## Examples
+
+To create a QR code using the default values for `level` and `scale`:
+
+```go-html-template
+{{ $text := "https://gohugo.io" }}
+{{ with images.QR $text }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
- "targetDir" "codes"
++{{< qr text="https://gohugo.io" class="qrcode" targetDir="images/qr" />}}
+
+Specify `level`, `scale`, and `targetDir` as needed to achieve the desired result:
+
+```go-html-template
+{{ $text := "https://gohugo.io" }}
+{{ $opts := dict
+ "level" "high"
+ "scale" 3
- {{< qr text="https://gohugo.io" level="high" scale=3 targetDir="codes" class="qrcode" />}}
++ "targetDir" "images/qr"
+}}
+{{ with images.QR $text $opts }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
++{{< qr text="https://gohugo.io" level="high" scale=3 targetDir="codes" class="qrcode" targetDir="images/qr" />}}
++
++To include a QR code that points to the `Permalink` of the current page:
++
++{{< code file=layouts/_default/single.html >}}
++{{ with images.QR .Permalink }}
++ <img
++ src="{{ .RelPermalink }}"
++ width="{{ .Width }}"
++ height="{{ .Height }}"
++ alt="QR code linking to {{ $.Permalink }}"
++ class="qr-code"
++ loading="lazy"
++ >
++{{ end }}
++{{< /code >}}
++
++Then hide the QR code with CSS unless printing the page:
++
++```css
++/* Hide QR code by default */
++.qr-code {
++ display: none;
++}
++
++/* Show QR code when printing */
++@media print {
++ .qr-code {
++ display: block;
++ }
++}
++```
+
+## Scale
+
+As you decrease the size of a QR code, the maximum distance at which it can be reliably scanned by a device also decreases.
+
+In the example above, we set the `scale` to `2`, resulting in a QR code where each module consists of 2x2 pixels. While this might be sufficient for on-screen display, it's likely to be problematic when printed at 600 dpi.
+
+\[ \frac{2\:px}{module} \times \frac{1\:inch}{600\:px} \times \frac{25.4\:mm}{1\:inch} = \frac{0.085\:mm}{module} \]
+
+This module size is half of the commonly recommended minimum of 0.170 mm.\
+If the QR code will be printed, use the default `scale` value of `4` pixels per module.
+
+Avoid using Hugo's image processing methods to resize QR codes. Resizing can introduce blurring due to anti-aliasing when a QR code module occupies a fractional number of pixels.
+
+{{% note %}}
+Always test the rendered QR code both on-screen and in print.
+{{% /note %}}
+
+## Shortcode
+
+Call the `qr` shortcode to insert a QR code into your content.
+
+Use the self-closing syntax to pass the text as an argument:
+
+```text
+{{</* qr text="https://gohugo.io" /*/>}}
+```
+
+Or insert the text between the opening and closing tags:
+
+```text
+{{</* qr */>}}
+https://gohugo.io
+{{</* /qr */>}}
+```
+
+The `qr` shortcode accepts several arguments including `level` and `scale`. See the [related documentation] for details.
+
+[related documentation]: /shortcodes/qr/
--- /dev/null
- {{< new-in 0.141.0 >}}
+---
+title: images.Text
+description: Returns an image filter that adds text to an image.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/images/Filter
+ - methods/resource/Filter
+ returnType: images.filter
+ signatures: ['images.Text TEXT [OPTIONS]']
+toc: true
+---
+
+## Options
+
+Although none of the options are required, at a minimum you will want to set the `size` to be some reasonable percentage of the image height.
+
+alignx
++ {{< new-in 0.141.0 />}}
+: (`string`) The horizontal alignment of the text relative to the horizontal offset, one of `left`, `center`, or `right`. Default is `left`.
+
+color
+: (`string`) The font color, either a 3-digit or 6-digit hexadecimal color code. Default is `#ffffff` (white).
+
+font
+: (`resource.Resource`) The font can be a [global resource](g), a [page resource](g), or a [remote resource](g). Default is [Go Regular], a proportional sans-serif TrueType font.
+
+[Go Regular]: https://go.dev/blog/go-fonts#sans-serif
+
+linespacing
+: (`int`) The number of pixels between each line. For a line height of 1.4, set the `linespacing` to 0.4 multiplied by the `size`. Default is `2`.
+
+size
+: (`int`) The font size in pixels. Default is `20`.
+
+x
+: (`int`) The horizontal offset, in pixels, relative to the left of the image. Default is `10`.
+
+y
+: (`int`) The vertical offset, in pixels, relative to the top of the image. Default is `10`.
+
+## Usage
+
+Set the text and paths:
+
+```go-html-template
+{{ $text := "Zion National Park" }}
+{{ $fontPath := "https://github.com/google/fonts/raw/main/ofl/lato/Lato-Regular.ttf" }}
+{{ $imagePath := "images/original.jpg" }}
+```
+
+Capture the font as a resource:
+
+```go-html-template
+{{ $font := "" }}
+{{ with try (resources.GetRemote $fontPath) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $font = . }}
+ {{ else }}
+ {{ errorf "Unable to get resource %s" $fontPath }}
+ {{ end }}
+{{ end }}
+```
+
+Create the filter, centering the text horizontally and vertically:
+
+```go-html-template
+{{ $r := "" }}
+{{ $filter := "" }}
+{{ with $r = resources.Get $imagePath }}
+ {{ $opts := dict
+ "alignx" "center"
+ "color" "#fbfaf5"
+ "font" $font
+ "linespacing" 8
+ "size" 60
+ "x" (mul .Width 0.5 | int)
+ "y" (mul .Height 0.5 | int)
+ }}
+ {{ $filter = images.Text $text $opts }}
+{{ else }}
+ {{ errorf "Unable to get resource %s" $imagePath }}
+{{ end }}
+```
+
+Apply the filter using the [`images.Filter`] function:
+
+```go-html-template
+{{ with $r }}
+ {{ with . | images.Filter $filter }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+You can also apply the filter using the [`Filter`] method on a `Resource` object:
+
+```go-html-template
+{{ with $r }}
+ {{ with .Filter $filter }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+[`images.Filter`]: /functions/images/filter/
+[`Filter`]: /methods/resource/filter/
+
+## Example
+
+{{< img
+ src="images/examples/zion-national-park.jpg"
+ alt="Zion National Park"
+ filter="Text"
+ filterArgs="Zion National Park,25,190,40,1.2,#fbfaf5"
+ example=true
+>}}
--- /dev/null
- description: Compiles the given JavaScript resource with Babel.
+---
+title: js.Babel
- weight: 100
++description: Compile the given JavaScript resource with Babel.
+categories: []
+keywords: []
- aliases: [babel,/hugo-pipes/babel/]
+action:
- {{< new-in 0.128.0 >}}
-
++ aliases: [babel]
+ related:
++ - functions/js/Batch
+ - functions/js/Build
+ - functions/resources/Fingerprint
+ - functions/resources/Minify
+ returnType: resource.Resource
+ signatures: ['js.Babel [OPTIONS] RESOURCE']
++weight: 30
+toc: true
+---
+
- {{ if hugo.IsDevelopment }}
- {{ with . | babel }}
+```go-html-template
+{{ with resources.Get "js/main.js" }}
- {{ else }}
- {{ $opts := dict "minified" true }}
- {{ with . | babel $opts | fingerprint }}
- <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
- {{ end }}
++ {{ $opts := dict
++ "minified" hugo.IsProduction
++ "noComments" hugo.IsProduction
++ "sourceMap" (cond hugo.IsProduction "none" "external")
++ }}
++ {{ with . | js.Babel $opts }}
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
++ <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
++ {{ end }}
++ {{ else }}
+ <script src="{{ .RelPermalink }}"></script>
+ {{ end }}
- config
- : (`string`) Path to the Babel configuration file. Hugo will, by default, look for a `babel.config.js` in your project. More information on these configuration files can be found here: [babel configuration](https://babeljs.io/docs/en/configuration).
+ {{ end }}
+{{ end }}
+```
+
+## Setup
+
+Step 1
+: Install [Node.js](https://nodejs.org/en/download)
+
+Step 2
+: Install the required Node.js packages in the root of your project.
+
+```sh
+npm install --save-dev @babel/core @babel/cli
+```
+
+Step 3
+: Add the babel executable to Hugo's `security.exec.allow` list in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[security.exec]
+ allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^npx$', '^postcss$', '^babel$']
+{{< /code-toggle >}}
+
+## Configuration
+
+We add the main project's `node_modules` to `NODE_PATH` when running Babel and similar tools. There are some known [issues](https://github.com/babel/babel/issues/5618) with Babel in this area, so if you have a `babel.config.js` living in a Hugo Module (and not in the project itself), we recommend using `require` to load the presets/plugins, e.g.:
+
+```js
+module.exports = {
+ presets: [
+ [
+ require("@babel/preset-env"),
+ {
+ useBuiltIns: "entry",
+ corejs: 3,
+ },
+ ],
+ ],
+};
+```
+
+## Options
+
- minified
- : (`bool`) Save as many bytes as possible when printing
++###### compact
++
++(`bool`) Whether to remove optional newlines and whitespace. Enabled when `minified` is `true`. Default is `false`
++
++###### config
++
++(`string`) Path to the Babel configuration file. Hugo will, by default, look for a `babel.config.js` file in the root of your project. See [details](https://babeljs.io/docs/en/configuration).
++
++###### minified
++
++(`bool`) Whether to minify the compiled code. Enables the `compact` option. Default is `false`.
++
++###### noBabelrc
++
++(`string`) Whether to ignore `.babelrc` and `.babelignore` files. Default is `false`.
++
++###### noComments
++
++(`bool`) Whether to remove comments. Default is `false`.
+
- noComments
- : (`bool`) Write comments to generated output (true by default)
++###### sourceMap
+
- compact
- : (`bool`) Do not include superfluous whitespace characters and line terminators. Defaults to `auto` if not set.
++(`string`) Whether to generate source maps, one of `external`, `inline`, or `none`. Default is `none`.
+
- verbose
- : (`bool`) Log everything
++<!-- In the above, technically "none" is not one of the enumerated values, but it has the same effect and is easier to document than an empty string. -->
+
- sourceMap
- : (`string`) Output `inline` or `external` sourcemap from the babel compile. External sourcemaps will be written to the target with the output file name + ".map". Input sourcemaps can be read from js.Build and node modules and combined into the output sourcemaps.
++###### verbose
+
++(`bool`) Whether to enable verbose logging. Default is `false`
--- /dev/null
- weight: 50
+---
+title: js.Batch
+description: Build JavaScript bundle groups with global code splitting and flexible hooks/runners setup.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/js/Build
+ - functions/js/Babel
+ - functions/resources/Fingerprint
+ - functions/resources/Minify
+ returnType: js.Batcher
+ signatures: ['js.Batch [ID]']
++weight: 20
+toc: true
+---
+
+{{% note %}}
+For a runnable example of this feature, see [this test and demo repo](https://github.com/bep/hugojsbatchdemo/).
+{{% /note %}}
+
+The Batch `ID` is used to create the base directory for this batch. Forward slashes are allowed. `js.Batch` returns an object with an API with this structure:
+
+* [Group]
+ * [Script]
+ * [SetOptions]
+ * [Instance]
+ * [SetOptions]
+ * [Runner]
+ * [SetOptions]
+ * [Config]
+ * [SetOptions]
+
+## Group
+
+The `Group` method take an `ID` (`string`) as argument. No slashes. It returns an object with these methods:
+
+#### Script
+
+The `Script` method takes an `ID` (`string`) as argument. No slashes. It returns an [OptionsSetter] that can be used to set [script options] for this script.
+
+```go-html-template
+{{ with js.Batch "js/mybatch" }}
+ {{ with .Group "mygroup" }}
+ {{ with .Script "myscript" }}
+ {{ .SetOptions (dict "resource" (resources.Get "myscript.js")) }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+`SetOptions` takes a [script options] map. Note that if you want the script to be handled by a [runner], you need to set the `export` option to match what you want to pass on to the runner (default is `*`).
+
+#### Instance
+
+The `Instance` method takes two `string` arguments `SCRIPT_ID` and `INSTANCE_ID`. No slashes. It returns an [OptionsSetter] that can be used to set [params options] for this instance.
+
+```go-html-template
+{{ with js.Batch "js/mybatch" }}
+ {{ with .Group "mygroup" }}
+ {{ with .Instance "myscript" "myinstance" }}
+ {{ .SetOptions (dict "params" (dict "param1" "value1")) }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+`SetOptions` takes a [params options] map. The instance options will be passed to any [runner] script in the same group, as JSON.
+
+#### Runner
+
+The `Runner` method takes an `ID` (`string`) as argument. No slashes. It returns an [OptionsSetter] that can be used to set [script options] for this runner.
+
+```go-html-template
+{{ with js.Batch "js/mybatch" }}
+ {{ with .Group "mygroup" }}
+ {{ with .Runner "myrunner" }}
+ {{ .SetOptions (dict "resource" (resources.Get "myrunner.js")) }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+`SetOptions` takes a [script options] map.
+
+The runner will receive a data structure with all instances for that group with a live binding of the [JavaScript import] of the defined `export`.
+
+The runner script's export must be a function that takes one argument, the group data structure. An example of a group data structure as JSON is:
+
+```json
+{
+ "id": "leaflet",
+ "scripts": [
+ {
+ "id": "mapjsx",
+ "binding": JAVASCRIPT_BINDING,
+ "instances": [
+ {
+ "id": "0",
+ "params": {
+ "c": "h-64",
+ "lat": 48.8533173846729,
+ "lon": 2.3497416090232535,
+ "r": "map.jsx",
+ "title": "Cathédrale Notre-Dame de Paris",
+ "zoom": 23
+ }
+ },
+ {
+ "id": "1",
+ "params": {
+ "c": "h-64",
+ "lat": 59.96300872062237,
+ "lon": 10.663529183196863,
+ "r": "map.jsx",
+ "title": "Holmenkollen",
+ "zoom": 3
+ }
+ }
+ ]
+ }
+ ]
+}
+```
+
+Below is an example of a runner script that uses React to render elements. Note that the export (`default`) must match the `export` option in the [script options] (`default` is the default value for runner scripts) (runnable versions of examples on this page can be found at [js.Batch Demo Repo]):
+
+```js
+import * as ReactDOM from 'react-dom/client';
+import * as React from 'react';
+
+export default function Run(group) {
+ console.log('Running react-create-elements.js', group);
+ const scripts = group.scripts;
+ for (const script of scripts) {
+ for (const instance of script.instances) {
+ /* This is a convention in this project. */
+ let elId = `${script.id}-${instance.id}`;
+ let el = document.getElementById(elId);
+ if (!el) {
+ console.warn(`Element with id ${elId} not found`);
+ continue;
+ }
+ const root = ReactDOM.createRoot(el);
+ const reactEl = React.createElement(script.binding, instance.params);
+ root.render(reactEl);
+ }
+ }
+}
+```
+
+#### Config
+
+Returns an [OptionsSetter] that can be used to set [build options] for the batch.
+
+These are mostly the same as for `js.Build`, but note that:
+
+* `targetPath` is set automatically (there may be multiple outputs).
+* `format` must be `esm`, currently the only format supporting [code splitting].
+* `params` will be available in the `@params/config` namespace in the scripts. This way you can import both the [script] or [runner] params and the [config] params with:
+
+```js
+import * as params from "@params";
+import * as config from "@params/config";
+```
+
+Setting the `Config` for a batch can be done from any template (including shortcode templates), but will only be set once (the first will win):
+
+```go-html-template
+{{ with js.Batch "js/mybatch" }}
+ {{ with .Config }}
+ {{ .SetOptions (dict
+ "target" "es2023"
+ "format" "esm"
+ "jsx" "automatic"
+ "loaders" (dict ".png" "dataurl")
+ "minify" true
+ "params" (dict "param1" "value1")
+ )
+ }}
+ {{ end }}
+{{ end }}
+```
+
+## Options
+
+### Build Options
+
+format
+: (`string`) Currently only `esm` is supported in [ESBuild's code splitting].
+
+{{% include "./_common/options.md" %}}
+
+### Script Options
+
+resource
+: The resource to build. This can be a file resource or a virtual resource.
+
+export
+: The export to bind the runner to. Set it to `*` to export the [entire namespace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#namespace_import). Default is `default` for [runner] scripts and `*` for other [scripts](#script).
+
+importContext
+: An additional context for resolving imports. Hugo will always check this one first before falling back to `assets` and `node_modules`. A common use of this is to resolve imports inside a page bundle. See [import context](#import-context).
+
+params
+: A map of parameters that will be passed to the script as JSON. These gets bound to the `@params` namespace:
+```js
+import * as params from '@params';
+```
+
+### Script Options
+
+### Params Options
+
+params
+: A map of parameters that will be passed to the script as JSON.
+
+### Import Context
+
+Hugo will, by default, first try to resolve any import in [assets](/hugo-pipes/introduction/#asset-directory) and, if not found, let [ESBuild] resolve it (e.g. from `node_modules`). The `importContext` option can be used to set the first context for resolving imports. A common use of this is to resolve imports inside a [page bundle](/content-management/page-bundles/).
+
+```go-html-template
+{{ $common := resources.Match "/js/headlessui/*.*" }}
+{{ $importContext := (slice $.Page ($common.Mount "/js/headlessui" ".")) }}
+```
+
+You can pass any object that implements [Resource.Get](/methods/page/resources/#get). Pass a slice to set multiple contexts.
+
+The example above uses [`Resources.Mount`] to resolve a directory inside `assets` relative to the page bundle.
+
+### OptionsSetter
+
+An `OptionsSetter` is a special object that is returned once only. This means that you should wrap it with [with]:
+
+```go-html-template
+{{ with .Script "myscript" }}
+ {{ .SetOptions (dict "resource" (resources.Get "myscript.js"))}}
+{{ end }}
+```
+
+## Build
+
+The `Build` method returns an object with the following structure:
+
+* Groups (map)
+ * [`Resources`]
+
+Eeach [`Resource`] will be of media type `application/javascript` or `text/css`.
+
+ In a template you would typically handle one group with a given `ID` (e.g. scripts for the current section). Because of the concurrent build, this needs to be done in a [`templates.Defer`] block:
+
+{{% note %}}
+The [`templates.Defer`] acts as a synchronisation point to handle scripts added concurrently by different templates. If you have a setup with where the batch is created in one go (in one template), you don't need it.
+
+See [this discussion](https://discourse.gohugo.io/t/js-batch-with-simple-global-script/53002/5?u=bep) for more.
+
+[`templates.Defer`]: /functions/templates/defer/
+{{% /note %}}
+
+```go-html-template
+{{ $group := .group }}
+{{ with (templates.Defer (dict "key" $group "data" $group )) }}
+ {{ with (js.Batch "js/mybatch") }}
+ {{ with .Build }}
+ {{ with index .Groups $ }}
+ {{ range . }}
+ {{ $s := . }}
+ {{ if eq $s.MediaType.SubType "css" }}
+ <link href="{{ $s.RelPermalink }}" rel="stylesheet" />
+ {{ else }}
+ <script src="{{ $s.RelPermalink }}" type="module"></script>
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+## Known Issues
+
+In the official documentation for [ESBuild's code splitting], there's a warning note in the header. The two issues are:
+
+* `esm` is currently the only implemented output format. This means that it will not work for very old browsers. See [caniuse](https://caniuse.com/?search=ESM).
+* There's a known import ordering issue.
+
+We have not seen the ordering issue as a problem during our [extensive testing](https://github.com/bep/hugojsbatchdemo) of this new feature with different libraries. There are two main cases:
+
+1. Undefined execution order of imports, see [this comment](https://github.com/evanw/esbuild/issues/399#issuecomment-1458680887)
+1. Only one execution order of imports, see [this comment](https://github.com/evanw/esbuild/issues/399#issuecomment-735355932)
+
+Many would say that both of the above are [code smells](https://en.wikipedia.org/wiki/Code_smell). The first one has a simple workaround in Hugo. Define the import order in its own script and make sure it gets passed early to ESBuild, e.g. by putting it in a script group with a name that comes early in the alphabet.
+
+```js
+import './lib2.js';
+import './lib1.js';
+
+console.log('entrypoints-workaround.js');
+
+```
+
+[build options]: #build-options
+[`Resource`]: /methods/resource/
+[`Resources`]: /methods/page/resources/
+[`Resources.Mount`]: /methods/page/resources/#mount
+[`templates.Defer`]: /functions/templates/defer/
+[code splitting]: https://esbuild.github.io/api/#splitting
+[config]: #config
+[ESBuild's code splitting]: https://esbuild.github.io/api/#splitting
+[ESBuild]: https://github.com/evanw/esbuild
+[group]: #group
+[instance]: #instance
+[JavaScript import]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
+[js.Batch Demo Repo]: https://github.com/bep/hugojsbatchdemo/
+[map]: /functions/collections/dictionary/
+[OptionsSetter]: #optionssetter
+[page bundles]: /content-management/page-bundles/
+[params options]: #params-options
+[runner]: #runner
+[script options]: #script-options
+[script]: #script
+[SetOptions]: #optionssetter
+[with]: /functions/go-template/with/
--- /dev/null
- description: Bundles, transpiles, tree shakes, and minifies JavaScript resources.
- weight: 30
+---
+title: js.Build
- {{ if hugo.IsDevelopment }}
- {{ with . | js.Build }}
++description: Bundle, transpile, tree shake, and minify JavaScript resources.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
++ - functions/js/Batch
+ - functions/js/Babel
+ - functions/resources/Fingerprint
+ - functions/resources/Minify
+ returnType: resource.Resource
+ signatures: ['js.Build [OPTIONS] RESOURCE']
++weight: 10
+toc: true
+---
+
+The `js.Build` function uses the [evanw/esbuild] package to:
+
+- Bundle
+- Transpile (TypeScript and JSX)
+- Tree shake
+- Minify
+- Create source maps
+
+[evanw/esbuild]: https://github.com/evanw/esbuild
+
+```go-html-template
+{{ with resources.Get "js/main.js" }}
- {{ else }}
- {{ $opts := dict "minify" true }}
- {{ with . | js.Build $opts | fingerprint }}
- <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
- {{ end }}
++ {{ $opts := dict
++ "minify" hugo.IsProduction
++ "sourceMap" (cond hugo.IsProduction "" "external")
++ "targetPath" "js/main.js"
++ }}
++ {{ with . | js.Build $opts }}
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
++ <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
++ {{ end }}
++ {{ else }}
+ <script src="{{ .RelPermalink }}"></script>
+ {{ end }}
- targetPath
- : (`string`) If not set, the source path will be used as the base target path.
+ {{ end }}
+{{ end }}
+```
+
+## Options
+
- format
- : (`string`) The output format. One of: `iife`, `cjs`, `esm`. Default is `iife`, a self-executing function, suitable for inclusion as a `<script>` tag.
++###### targetPath
++
++(`string`) If not set, the source path will be used as the base target path.
+Note that the target path's extension may change if the target MIME type is different, e.g. when the source is TypeScript.
+
- ### Import JS code from the assets directory
++###### format
++
++(`string`) The output format. One of: `iife`, `cjs`, `esm`. Default is `iife`, a self-executing function, suitable for inclusion as a `<script>` tag.
+
+{{% include "./_common/options.md" %}}
+
- Any imports starting with `.` is resolved relative to the current file:
++## Import JS code from the assets directory
+
+`js.Build` has full support for the virtual union file system in [Hugo Modules](/hugo-modules/). You can see some simple examples in this [test project](https://github.com/gohugoio/hugoTestProjectJSModImports), but in short this means that you can do this:
+
+```js
+import { hello } from 'my/module';
+```
+
+And it will resolve to the top-most `index.{js,ts,tsx,jsx}` inside `assets/my/module` in the layered file system.
+
+```js
+import { hello3 } from 'my/module/hello3';
+```
+
+Will resolve to `hello3.{js,ts,tsx,jsx}` inside `assets/my/module`.
+
++Any imports starting with `.` are resolved relative to the current file:
+
+```js
+import { hello4 } from './lib';
+```
+
+For other files (e.g. `JSON`, `CSS`) you need to use the relative path including any extension, e.g:
+
+```js
+import * as data from 'my/module/data.json';
+```
+
+Any imports in a file outside `assets` or that does not resolve to a component inside `assets` will be resolved by [ESBuild](https://esbuild.github.io/) with the **project directory** as the resolve directory (used as the starting point when looking for `node_modules` etc.). Also see [hugo mod npm pack](/commands/hugo_mod_npm_pack/). If you have any imported npm dependencies in your project, you need to make sure to run `npm install` before you run `hugo`.
+
+Also note the new `params` option that can be passed from template to your JS files, e.g.:
+
+```go-html-template
+{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}
+```
+And then in your JS file:
+
+```js
+import * as params from '@params';
+```
+
+Hugo will, by default, generate a `assets/jsconfig.json` file that maps the imports. This is useful for navigation/intellisense help inside code editors, but if you don't need/want it, you can [turn it off](/getting-started/configuration/#configure-build).
+
+## Node.js dependencies
+
+Use the `js.Build` function to include Node.js dependencies.
+
+Any imports in a file outside `assets` or that does not resolve to a component inside `assets` will be resolved by [esbuild](https://esbuild.github.io/) with the **project directory** as the resolve directory (used as the starting point when looking for `node_modules` etc.). Also see [hugo mod npm pack](/commands/hugo_mod_npm_pack/). If you have any imported npm dependencies in your project, you need to make sure to run `npm install` before you run `hugo`.
+
+The start directory for resolving npm packages (aka. packages that live inside a `node_modules` directory) is always the main project directory.
+
+{{% note %}}
+If you're developing a theme/component that is supposed to be imported and depends on dependencies inside `package.json`, we recommend reading about [hugo mod npm pack](/commands/hugo_mod_npm_pack/), a tool to consolidate all the npm dependencies in a project.
+{{% /note %}}
+
+## Examples
+
+```go-html-template
+{{ $built := resources.Get "js/index.js" | js.Build "main.js" }}
+```
+
+Or with options:
+
+```go-html-template
+{{ $externals := slice "react" "react-dom" }}
+{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
+
+{{ $opts := dict "targetPath" "main.js" "externals" $externals "defines" $defines }}
+{{ $built := resources.Get "scripts/main.js" | js.Build $opts }}
+<script src="{{ $built.RelPermalink }}" defer></script>
+```
--- /dev/null
- params
- : (`map` or `slice`) Params that can be imported as JSON in your JS files, e.g.
+---
+_comment: Do not remove front matter.
+---
+
- minify
- : (`bool`)Let `js.Build` handle the minification.
++###### params
++
++(`map` or `slice`) Params that can be imported as JSON in your JS files, e.g.
+
+```go-html-template
+{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}
+```
+And then in your JS file:
+
+```js
+import * as params from '@params';
+```
+
+Note that this is meant for small data sets, e.g. configuration settings. For larger data, please put/mount the files into `assets` and import them directly.
+
- loaders
- : (`map`) {{< new-in "0.140.0" >}} Configuring a loader for a given file type lets you load that file type with an import statement or a require call. For example configuring the .png file extension to use the data URL loader means importing a .png file gives you a data URLcontaining the contents of that image. Loaders available are `none`, `base64`, `binary`, `copy`, `css`, `dataurl`, `default`, `empty`, `file`, `global-css`, `js`, `json`, `jsx`, `local-css`, `text`, `ts`, `tsx`. See https://esbuild.github.io/api/#loader
++###### minify
++
++(`bool`) Let `js.Build` handle the minification.
++
++###### loaders
++
++{{< new-in 0.140.0 />}}
++
++(`map`) Configuring a loader for a given file type lets you load that file type with an import statement or a require call. For example configuring the .png file extension to use the data URL loader means importing a .png file gives you a data URLcontaining the contents of that image. Loaders available are `none`, `base64`, `binary`, `copy`, `css`, `dataurl`, `default`, `empty`, `file`, `global-css`, `js`, `json`, `jsx`, `local-css`, `text`, `ts`, `tsx`. See https://esbuild.github.io/api/#loader.
+
- inject
- : (`slice`) This option allows you to automatically replace a global variable with an import from another file. The path names must be relative to `assets`. See https://esbuild.github.io/api/#inject
++###### inject
+
- shims
- : (`map`) This option allows swapping out a component with another. A common use case is to load dependencies like React from a CDN (with _shims_) when in production, but running with the full bundled `node_modules` dependency during development:
++(`slice`) This option allows you to automatically replace a global variable with an import from another file. The path names must be relative to `assets`. See https://esbuild.github.io/api/#inject.
+
- target
- : (`string`) The language target. One of: `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`. Default is `esnext`.
++###### shims
++
++(`map`) This option allows swapping out a component with another. A common use case is to load dependencies like React from a CDN (with _shims_) when in production, but running with the full bundled `node_modules` dependency during development:
+
+```go-html-template
+{{ $shims := dict "react" "js/shims/react.js" "react-dom" "js/shims/react-dom.js" }}
+{{ $js = $js | js.Build dict "shims" $shims }}
+```
+
+The _shim_ files may look like these:
+
+```js
+// js/shims/react.js
+module.exports = window.React;
+```
+
+```js
+// js/shims/react-dom.js
+module.exports = window.ReactDOM;
+```
+
+With the above, these imports should work in both scenarios:
+
+```js
+import * as React from 'react';
+import * as ReactDOM from 'react-dom/client';
+```
+
- platform {{< new-in 0.140.0 >}}
- : (`string`) One of `browser`, `node`, `neutral`. Default is `browser`. See https://esbuild.github.io/api/#platform
++###### target
++
++(`string`) The language target. One of: `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020` or `esnext`. Default is `esnext`.
++
++###### platform
++
++{{< new-in 0.140.0 />}}
+
- externals
- : (`slice`) External dependencies. Use this to trim dependencies you know will never be executed. See https://esbuild.github.io/api/#external
++(`string`) One of `browser`, `node`, `neutral`. Default is `browser`. See https://esbuild.github.io/api/#platform.
+
- defines
- : (`map`) Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
++###### externals
+
- sourceMap
- : (`string`) Whether to generate `inline`, `linked` or `external` source maps from esbuild. Linked and external source maps will be written to the target with the output file name + ".map". When `linked` a `sourceMappingURL` will also be written to the output file. By default, source maps are not created. Note that the `linked` option was added in Hugo 0.140.0.
++(`slice`) External dependencies. Use this to trim dependencies you know will never be executed. See https://esbuild.github.io/api/#external.
++
++###### defines
++
++(`map`) Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
+
+```go-html-template
+{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
+```
+
- sourcesContent {{< new-in 0.140.0 >}}
- : (`bool`) Whether to include the content of the source files in the source map. By default, this is `true`.
++###### sourceMap
++
++(`string`) Whether to generate `inline`, `linked` or `external` source maps from esbuild. Linked and external source maps will be written to the target with the output file name + ".map". When `linked` a `sourceMappingURL` will also be written to the output file. By default, source maps are not created. Note that the `linked` option was added in Hugo 0.140.0.
++
++###### sourcesContent
++
++{{< new-in 0.140.0 />}}
++
++(`bool`) Whether to include the content of the source files in the source map. By default, this is `true`.
++
++###### JSX
++
++{{< new-in 0.124.0 />}}
++
++(`string`) How to handle/transform JSX syntax. One of: `transform`, `preserve`, `automatic`. Default is `transform`. Notably, the `automatic` transform was introduced in React 17+ and will cause the necessary JSX helper functions to be imported automatically. See https://esbuild.github.io/api/#jsx.
+
- JSX {{< new-in 0.124.0 >}}
- : (`string`) How to handle/transform JSX syntax. One of: `transform`, `preserve`, `automatic`. Default is `transform`. Notably, the `automatic` transform was introduced in React 17+ and will cause the necessary JSX helper functions to be imported automatically. See https://esbuild.github.io/api/#jsx
++###### JSXImportSource
+
- JSXImportSource {{< new-in 0.124.0 >}}
- : (`string`) Which library to use to automatically import its JSX helper functions from. This only works if `JSX` is set to `automatic`. The specified library needs to be installed through npm and expose certain exports. See https://esbuild.github.io/api/#jsx-import-source
++{{< new-in 0.124.0 />}}
+
++(`string`) Which library to use to automatically import its JSX helper functions from. This only works if `JSX` is set to `automatic`. The specified library needs to be installed through npm and expose certain exports. See https://esbuild.github.io/api/#jsx-import-source.
+
+The combination of `JSX` and `JSXImportSource` is helpful if you want to use a non-React JSX library like Preact, e.g.:
+
+```go-html-template
+{{ $js := resources.Get "js/main.jsx" | js.Build (dict "JSX" "automatic" "JSXImportSource" "preact") }}
+```
+
+With the above, you can use Preact components and JSX without having to manually import `h` and `Fragment` every time:
+
+```jsx
+import { render } from 'preact';
+
+const App = () => <>Hello world!</>;
+
+const container = document.getElementById('app');
+if (container) render(<App />, container);
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Acos
+description: Returns the arccosine, in radians, of the given number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Asin
+ - functions/math/Atan
+ - functions/math/Atan2
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Tan
+ returnType: float64
+ signatures: [math.Acos VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Acos 1 }} → 0
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Asin
+description: Returns the arcsine, in radians, of the given number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Acos
+ - functions/math/Atan
+ - functions/math/Atan2
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Tan
+ returnType: float64
+ signatures: [math.Asin VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Asin 1 }} → 1.5707963267948966
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Atan
+description: Returns the arctangent, in radians, of the given number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Atan2
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Tan
+ returnType: float64
+ signatures: [math.Atan VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Atan 1 }} → 0.7853981633974483
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Atan2
+description: Returns the arctangent, in radians, of the given number pair, determining the correct quadrant from their signs.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Atan
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Tan
+ returnType: float64
+ signatures: [math.Atan2 VALUE VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Atan2 1 2 }} → 0.4636476090008061
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Cos
+description: Returns the cosine of the given radian number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Tan
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Atan
+ - functions/math/Atan2
+ returnType: float64
+ signatures: [math.Cos VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Cos 1 }} → 0.5403023058681398
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Pi
+description: Returns the mathematical constant pi.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Tan
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Atan
+ - functions/math/Atan2
+ returnType: float64
+ signatures: [math.Pi]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Pi }} → 3.141592653589793
+```
--- /dev/null
- {{< new-in 0.114.0 >}}
+---
+title: math.Product
+description: Returns the product of all numbers. Accepts scalars, slices, or both.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Add
+ - functions/math/Div
+ - functions/math/Mul
+ - functions/math/Sub
+ - functions/math/Sum
+ returnType: float64
+ signatures: [math.Product VALUE...]
+---
+
++{{< new-in 0.114.0 />}}
+
+```go-html-template
+{{ math.Product 1 (slice 2 3) 4 }} → 24
+```
--- /dev/null
- {{< new-in 0.121.2 >}}
+---
+title: math.Rand
+description: Returns a pseudo-random number in the half-open interval [0.0, 1.0).
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: float64
+ signatures: [math.Rand]
+---
+
++{{< new-in 0.121.2 />}}
+
+The `math.Rand` function returns a pseudo-random number in the half-open [interval](g) [0.0, 1.0).
+
+```go-html-template
+{{ math.Rand }} → 0.6312770459590062
+```
+
+To generate a random integer in the closed interval [0, 5]:
+
+```go-html-template
+{{ math.Rand | mul 6 | math.Floor }}
+```
+
+To generate a random integer in the closed interval [1, 6]:
+
+```go-html-template
+{{ math.Rand | mul 6 | math.Ceil }}
+```
+
+To generate a random float, with one digit after the decimal point, in the closed interval [0, 4.9]:
+
+```go-html-template
+{{ div (math.Rand | mul 50 | math.Floor) 10 }}
+```
+
+To generate a random float, with one digit after the decimal point, in the closed interval [0.1, 5.0]:
+
+```go-html-template
+{{ div (math.Rand | mul 50 | math.Ceil) 10 }}
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Sin
+description: Returns the sine of the given radian number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Pi
+ - functions/math/Cos
+ - functions/math/Tan
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Atan
+ - functions/math/Atan2
+ returnType: float64
+ signatures: [math.Sin VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Sin 1 }} → 0.8414709848078965
+```
--- /dev/null
- {{< new-in 0.114.0 >}}
+---
+title: math.Sum
+description: Returns the sum of all numbers. Accepts scalars, slices, or both.
+categories: []
+action:
+ aliases: []
+ related:
+ - functions/math/Add
+ - functions/math/Div
+ - functions/math/Mul
+ - functions/math/Product
+ - functions/math/Sub
+ returnType: float64
+ signatures: [math.Sum VALUE...]
+---
+
++{{< new-in 0.114.0 />}}
+
+```go-html-template
+{{ math.Sum 1 (slice 2 3) 4 }} → 10
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.Tan
+description: Returns the tangent of the given radian number.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/Pi
+ - functions/math/Sin
+ - functions/math/Cos
+ - functions/math/Asin
+ - functions/math/Acos
+ - functions/math/Atan
+ - functions/math/Atan2
+ returnType: float64
+ signatures: [math.Tan VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.Tan 1 }} → 1.557407724654902
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.ToDegrees
+description: ToDegrees converts radians into degrees.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/ToRadians
+ - functions/math/Pi
+ returnType: float64
+ signatures: [math.ToDegrees VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.ToDegrees 1.5707963267948966 }} → 90
+```
--- /dev/null
- {{< new-in 0.130.0 >}}
+---
+title: math.ToRadians
+description: ToRadians converts degrees into radians.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/math/ToDegrees
+ - functions/math/Pi
+ returnType: float64
+ signatures: [math.ToRadians VALUE]
+---
+
++{{< new-in 0.130.0 />}}
+
+```go-html-template
+{{ math.ToRadians 90 }} → 1.5707963267948966
+```
--- /dev/null
- related:
- - functions/js/Build
- - functions/resources/Fingerprint
- - functions/resources/Minify
+---
+title: resources.Babel
+description: Compiles the given JavaScript resource with Babel.
+categories: []
+keywords: []
+action:
- toc: true
- expiryDate: 2025-06-24 # deprecated 2024-06-24
++ related: []
+ returnType: resource.Resource
+ signatures: ['resources.Babel [OPTIONS] RESOURCE']
-
- ```go-html-template
- {{ with resources.Get "js/main.js" }}
- {{ if hugo.IsDevelopment }}
- {{ with . | babel }}
- <script src="{{ .RelPermalink }}"></script>
- {{ end }}
- {{ else }}
- {{ $opts := dict "minified" true }}
- {{ with . | babel $opts | fingerprint }}
- <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
- {{ end }}
- {{ end }}
- {{ end }}
- ```
-
- ## Setup
-
- Step 1
- : Install [Node.js](https://nodejs.org/en/download)
-
- Step 2
- : Install the required Node.js packages in the root of your project.
-
- ```sh
- npm install --save-dev @babel/core @babel/cli
- ```
-
- Step 3
- : Add the babel executable to Hugo's `security.exec.allow` list in your site configuration:
-
- {{< code-toggle file=hugo >}}
- [security.exec]
- allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^npx$', '^postcss$', '^babel$']
- {{< /code-toggle >}}
-
- ## Configuration
-
- We add the main project's `node_modules` to `NODE_PATH` when running Babel and similar tools. There are some known [issues](https://github.com/babel/babel/issues/5618) with Babel in this area, so if you have a `babel.config.js` living in a Hugo Module (and not in the project itself), we recommend using `require` to load the presets/plugins, e.g.:
-
- ```js
- module.exports = {
- presets: [
- [
- require("@babel/preset-env"),
- {
- useBuiltIns: "entry",
- corejs: 3,
- },
- ],
- ],
- };
- ```
-
- ## Options
-
- config
- : (`string`) Path to the Babel configuration file. Hugo will, by default, look for a `babel.config.js` in your project. More information on these configuration files can be found here: [babel configuration](https://babeljs.io/docs/en/configuration).
-
- minified
- : (`bool`) Save as many bytes as possible when printing
-
- noComments
- : (`bool`) Write comments to generated output (true by default)
-
- compact
- : (`bool`) Do not include superfluous whitespace characters and line terminators. Defaults to `auto` if not set.
-
- verbose
- : (`bool`) Log everything
-
- sourceMap
- : (`string`) Output `inline` or `external` sourcemap from the babel compile. External sourcemaps will be written to the target with the output file name + ".map". Input sourcemaps can be read from js.Build and node modules and combined into the output sourcemaps.
++expiryDate: 2026-06-24 # deprecated 2024-06-24 in v0.128.0
+---
+
+{{% deprecated-in 0.128.0 %}}
+Use [`js.Babel`] instead.
+
+[`js.Babel`]: /functions/js/babel/
+{{% /deprecated-in %}}
--- /dev/null
- Hugo publishes the resource to the target path when you call its [`Publish`], [`Permalink`], or [`RelPermalink`] method.
+---
+title: resources.Concat
+description: Returns a concatenated slice of resources.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: resource.Resource
+ signatures: ['resources.Concat TARGETPATH [RESOURCE...]']
+---
+
+The `resources.Concat` function returns a concatenated slice of resources, caching the result using the target path as its cache key. Each resource must have the same [media type].
+
++Hugo publishes the resource to the target path when you call its [`Publish`], [`Permalink`], or [`RelPermalink`] method.
+
+[media type]: https://en.wikipedia.org/wiki/Media_type
+[`publish`]: /methods/resource/publish/
+[`permalink`]: /methods/resource/permalink/
+[`relpermalink`]: /methods/resource/relpermalink/
+
+```go-html-template
+{{ $plugins := resources.Get "js/plugins.js" }}
+{{ $global := resources.Get "js/global.js" }}
+{{ $js := slice $plugins $global | resources.Concat "js/bundle.js" }}
+```
--- /dev/null
- If you need multiple values for the same header key, use a slice:
+---
+title: resources.GetRemote
+description: Returns a remote resource from the given URL, or nil if none found.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/data/GetCSV
+ - functions/data/GetJSON
+ - functions/resources/ByType
+ - functions/resources/Get
+ - functions/resources/GetMatch
+ - functions/resources/Match
+ - methods/page/Resources
+ returnType: resource.Resource
+ signatures: ['resources.GetRemote URL [OPTIONS]']
+toc: true
+---
+
++{{< new-in 0.141.0 >}}
++The `Err` method on the returned resource was removed in v0.141.0.
++
++Use the [`try`] statement instead, as shown in the [error handling] example below.
++
++[`try`]: /functions/go-template/try
++[error handling]: #error-handling
++{{< /new-in >}}
++
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+## Options
+
+The `resources.GetRemote` function takes an optional map of options.
+
++###### body
++
++(`string`) The data you want to transmit to the server.
++
++###### headers
++
++(`map[string][]string`) The collection of key-value pairs that provide additional information about the request.
++
++###### key
++
++(`string`) The cache key. Hugo derives the default value from the URL and options map. See [caching](#caching).
++
++###### method
++
++(`string`) The action to perform on the requested resource, typically one of `GET`, `POST`, or `HEAD`.
++
++###### responseHeaders
++{{< new-in 0.143.0 />}}
++
++(`[]string`) The headers to extract from the server's response, accessible through the resource's [`Data.Headers`] method. Header name matching is case-insensitive.
++
++[`Data.Headers`]: /methods/resource/data/#headers
++
++## Options examples
++
++{{% note %}}
++For brevity, the examples below do not include [error handling].
++
++[error handling]: #error-handling
++{{% /note %}}
++
++To include a header:
++
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "headers" (dict "Authorization" "Bearer abcd")
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
- You can also change the request method and set the request body:
++To specify more than one value for the same header key, use a slice:
+
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "headers" (dict "X-List" (slice "a" "b" "c"))
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
- ```go-html-template
- {{ $url := "https://example.org/images/a.jpg" }}
- {{ with try (resources.GetRemote $url) }}
- {{ with .Err }}
- {{ errorf "%s" . }}
- {{ else with .Value }}
- {{ with .Data }}
- {{ .ContentLength }} → 42764
- {{ .ContentType }} → image/jpeg
- {{ .Status }} → 200 OK
- {{ .StatusCode }} → 200
- {{ .TransferEncoding }} → []
- {{ end }}
- {{ else }}
- {{ errorf "Unable to get remote resource %q" $url }}
- {{ end }}
- {{ end }}
- ```
-
- ContentLength
- : (`int`) The content length in bytes.
-
- ContentType
- : (`string`) The content type.
-
- Status
- : (`string`) The HTTP status text.
-
- StatusCode
- : (`int`) The HTTP status code.
-
- TransferEncoding
- : (`string`) The transfer encoding.
-
++To post data:
+
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "method" "post"
+ "body" `{"complete": true}`
+ "headers" (dict "Content-Type" "application/json")
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
++To override the default cache key:
++
++```go-html-template
++{{ $url := "https://example.org/images/a.jpg" }}
++{{ $opts := dict
++ "key" (print $url (now.Format "2006-01-02"))
++}}
++{{ $resource := resources.GetRemote $url $opts }}
++```
++
++To extract specific headers from the server's response:
++
++```go-html-template
++{{ $url := "https://example.org/images/a.jpg" }}
++{{ $opts := dict
++ "method" "HEAD"
++ "responseHeaders" (slice "X-Frame-Options" "Server")
++}}
++{{ $resource := resources.GetRemote $url $opts }}
++```
++
+## Remote data
+
+When retrieving remote data, use the [`transform.Unmarshal`] function to [unmarshal](g) the response.
+
+[`transform.Unmarshal`]: /functions/transform/unmarshal/
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books.json" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+{{% note %}}
+When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`.
+
+In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead:
+
+`{{ $data = .Content | transform.Unmarshal }}`
+
+[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
+{{% /note %}}
+
+## Error handling
+
+Use the [`try`] statement to capture HTTP request errors. If you do not handle the error yourself, Hugo will fail the build.
+
+[`try`]: /functions/go-template/try
+
+{{% note %}}
+Hugo does not classify an HTTP response with status code 404 as an error. In this case `resources.GetRemote` returns nil.
+{{% /note %}}
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+To log an error as a warning instead of an error:
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else with .Value }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ else }}
+ {{ warnf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+## HTTP response
+
+The [`Data`] method on a resource returned by the `resources.GetRemote` function returns information from the HTTP response.
+
+[`Data`]: /methods/resource/data/
+
- {{ $resource := resources.GetRemote $url (dict "key" $cacheKey) }}
+## Caching
+
+Resources returned from `resources.GetRemote` are cached to disk. See [configure file caches] for details.
+
+By default, Hugo derives the cache key from the arguments passed to the function, the URL and the options map, if any.
+
+Override the cache key by setting a `key` in the options map. Use this approach to have more control over how often Hugo fetches a remote resource.
+
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
+{{ $cacheKey := print $url (now.Format "2006-01-02") }}
++{{ $opts := dict "key" $cacheKey }}
++{{ $resource := resources.GetRemote $url $opts }}
+```
+
+[configure file caches]: /getting-started/configuration/#configure-file-caches
+
+## Security
+
+To protect against malicious intent, the `resources.GetRemote` function inspects the server response including:
+
+- The [Content-Type] in the response header
+- The file extension, if any
+- The content itself
+
+If Hugo is unable to resolve the media type to an entry in its [allowlist], the function throws an error:
+
+```text
+ERROR error calling resources.GetRemote: failed to resolve media type...
+```
+
+For example, you will see the error above if you attempt to download an executable.
+
+Although the allowlist contains entries for common media types, you may encounter situations where Hugo is unable to resolve the media type of a file that you know to be safe. In these situations, edit your site configuration to add the media type to the allowlist. For example:
+
+{{< code-toggle file=hugo >}}
+[security.http]
+mediaTypes = ['^image/avif$','^application/vnd\.api\+json$']
+{{< /code-toggle >}}
+
+Note that the entry above is:
+
+- An _addition_ to the allowlist; it does not _replace_ the allowlist
+- An array of regular expressions
+
+[allowlist]: https://en.wikipedia.org/wiki/Whitelist
+[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
--- /dev/null
- related:
- - functions/resources/Fingerprint
- - functions/resources/Minify
- - functions/resources/PostProcess
- - functions/css/Sass
+---
+title: resources.PostCSS
+description: Processes the given resource with PostCSS using any PostCSS plugin.
+categories: []
+keywords: []
+action:
- toc: true
- expiryDate: 2025-06-24 # deprecated 2024-06-24
++ related: []
+ returnType: resource.Resource
+ signatures: ['resources.PostCSS [OPTIONS] RESOURCE']
-
- ```go-html-template
- {{ with resources.Get "css/main.css" | postCSS }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- ```
-
- ## Setup
-
- Follow the steps below to transform CSS using any of the available [PostCSS plugins].
-
- Step 1
- : Install [Node.js].
-
- Step 2
- : Install the required Node.js packages in the root of your project. For example, to add vendor prefixes to your CSS rules:
-
- ```sh
- npm i -D postcss postcss-cli autoprefixer
- ```
-
- Step 3
- : Create a PostCSS configuration file in the root of your project. You must name this file `postcss.config.js` or another [supported file name]. For example:
-
- ```js
- module.exports = {
- plugins: [
- require('autoprefixer')
- ]
- };
- ```
-
- {{% note %}}
- {{% include "functions/resources/_common/postcss-windows-warning.md" %}}
- {{% /note %}}
-
- Step 4
- : Place your CSS file within the `assets/css` directory.
-
- Step 5
- : Process the resource with PostCSS:
-
- ```go-html-template
- {{ with resources.Get "css/main.css" | postCSS }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- ```
-
- ## Options
-
- The `resources.PostCSS` method takes an optional map of options.
-
- config
- : (`string`) The directory that contains the PostCSS configuration file. Default is the root of the project directory.
-
- noMap
- : (`bool`) Default is `false`. If `true`, disables inline sourcemaps.
-
- inlineImports
- : (`bool`) Default is `false`. Enable inlining of @import statements. It does so recursively, but will only import a file once. URL imports (e.g. `@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');`) and imports with media queries will be ignored. Note that this import routine does not care about the CSS spec, so you can have @import anywhere in the file. Hugo will look for imports relative to the module mount and will respect theme overrides.
-
- skipInlineImportsNotFound
- : (`bool`) Default is `false`. Before Hugo 0.99.0 when `inlineImports` was enabled and we failed to resolve an import, we logged it as a warning. We now fail the build. If you have regular CSS imports in your CSS that you want to preserve, you can either use imports with URL or media queries (Hugo does not try to resolve those) or set `skipInlineImportsNotFound` to true.
-
- ```go-html-template
- {{ $opts := dict "config" "config-directory" "noMap" true }}
- {{ with resources.Get "css/main.css" | postCSS $opts }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- ```
-
- ## No configuration file
-
- To avoid using a PostCSS configuration file, you can specify a minimal configuration using the options map.
-
- use
- : (`string`) A space-delimited list of PostCSS plugins to use.
-
- parser
- : (`string`) A custom PostCSS parser.
-
- stringifier
- : (`string`) A custom PostCSS stringifier.
-
- syntax
- : (`string`) Custom postcss syntax.
-
- ```go-html-template
- {{ $opts := dict "use" "autoprefixer postcss-color-alpha" }}
- {{ with resources.Get "css/main.css" | postCSS $opts }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- ```
-
- ## Check environment
-
- The current Hugo environment name (set by `--environment` or in configuration or OS environment) is available in the Node context, which allows constructs like this:
-
- ```js
- const autoprefixer = require('autoprefixer');
- const purgecss = require('@fullhuman/postcss-purgecss');
- module.exports = {
- plugins: [
- autoprefixer,
- process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null
- ]
- }
- ```
-
- [node.js]: https://nodejs.org/en/download
- [postcss plugins]: https://www.postcss.parts/
- [supported file name]: https://github.com/postcss/postcss-load-config#usage
- [transpile to CSS]: /functions/css/sass/
++expiryDate: 2026-06-24 # deprecated 2024-06-24 in v0.128.0
+---
+
+{{% deprecated-in 0.128.0 %}}
+Use [`css.PostCSS`] instead.
+
+[`css.PostCSS`]: /functions/css/postcss/
+{{% /deprecated-in %}}
--- /dev/null
- ```go-html-template
- {{ with resources.Get "css/main.css" }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | postCSS | minify | fingerprint | resources.PostProcess }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- {{ end }}
- {{ end }}
- ```
+---
+title: resources.PostProcess
+description: Processes the given resource after the build.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/css/PostCSS
+ - functions/css/Sass
+ returnType: postpub.PostPublishedResource
+ signatures: [resources.PostProcess RESOURCE]
+toc: true
+---
+
- Marking a resource with `resources.PostProcess` postpones transformations until the build has finished.
++The `resources.PostProcess` function delays resource transformation steps until the build is complete, primarily for tasks like removing unused CSS rules.
+
- Call `resources.PostProcess` when one or more of the steps in the transformation chain depends on the result of the build.
++## Example
+
- A prime use case for this is purging unused CSS rules using the [PurgeCSS] plugin for the PostCSS Node.js package.
++In this example, after the build is complete, Hugo will:
+
- ## CSS Purging
-
- {{% note %}}
- There are several ways to set up CSS purging with PostCSS in Hugo. If you have a simple project, you should consider going the simpler route and drop the use of `resources.PostProcess` and just extract keywords from the templates. See the [Tailwind documentation](https://tailwindcss.com/docs/controlling-file-size/#app) for examples.
- {{% /note %}}
++1. Purge unused CSS using the [PurgeCSS] plugin for [PostCSS]
++2. Add vendor prefixes to CSS rules using the [Autoprefixer] plugin for PostCSS
++3. [Minify] the CSS
++4. [Fingerprint] the CSS
+
- : Create a PostCSS configuration file in the root of your project. You must name this file `postcss.config.js` or another [supported file name]. For example:
++[autoprefixer]: https://github.com/postcss/autoprefixer
++[fingerprint]: /functions/resources/fingerprint/
++[minify]: /functions/resources/minify/
++[postcss]: /functions/css/postcss/
++[purgecss]: https://purgecss.com/plugins/postcss.html
+
+Step 1
+: Install [Node.js].
+
++[node.js]: https://nodejs.org/en/download
++
+Step 2
+: Install the required Node.js packages in the root of your project:
+
+```sh
+npm i -D postcss postcss-cli autoprefixer @fullhuman/postcss-purgecss
+```
+
+Step 3
- ```js
++: Enable creation of the `hugo_stats.json` file when building the site. If you are only using this for the production build, consider placing it below [`config/production`].
+
- const purgecss = require('@fullhuman/postcss-purgecss')({
++[`config/production`]: /getting-started/configuration/#configuration-directory
++
++{{< code-toggle file=hugo >}}
++[build.buildStats]
++enable = true
++{{< /code-toggle >}}
++
++See the [configure build] documentation for details and options.
++
++[configure build]: /getting-started/configuration/#configure-build
++
++Step 4
++: Create a PostCSS configuration file in the root of your project.
++
++{{< code file="postcss.config.js" copy=true >}}
+const autoprefixer = require('autoprefixer');
- process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null
++const purgeCSSPlugin = require('@fullhuman/postcss-purgecss').default;
++
++const purgecss = purgeCSSPlugin({
+ content: ['./hugo_stats.json'],
+ defaultExtractor: content => {
+ const els = JSON.parse(content).htmlElements;
+ return [
+ ...(els.tags || []),
+ ...(els.classes || []),
+ ...(els.ids || []),
+ ];
+ },
+ // https://purgecss.com/safelisting.html
+ safelist: []
+});
+
+module.exports = {
+ plugins: [
++ process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null,
+ autoprefixer,
- ```
+ ]
+};
- Step 4
- : Enable creation of the `hugo_stats.json` file when building the site. If you are only using this for the production build, consider placing it below [`config/production`].
-
- {{< code-toggle file=hugo >}}
- [build.buildStats]
- enable = true
- {{< /code-toggle >}}
-
- See the [configure build] documentation for details and options.
-
++{{< /code >}}
+
+{{% note %}}
+{{% include "functions/resources/_common/postcss-windows-warning.md" %}}
+{{% /note %}}
+
- Hugo passes these environment variables to PostCSS, which allows you to do something like:
+Step 5
+: Place your CSS file within the `assets/css` directory.
+
+Step 6
+: If the current environment is not `development`, process the resource with PostCSS:
+
+```go-html-template
+{{ with resources.Get "css/main.css" }}
+ {{ if hugo.IsDevelopment }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}">
+ {{ else }}
+ {{ with . | postCSS | minify | fingerprint | resources.PostProcess }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
+ {{ end }}
+ {{ end }}
+{{ end }}
+```
+
+## Environment variables
+
- process.env.HUGO_ENVIRONMENT === 'production' ? [autoprefixer] : []
++Hugo passes the environment variables below to PostCSS, allowing you to do something like:
+
+```js
- : The absolute path to the publish directory (the `public` directory). Note that the value will always point to a directory on disk even when running `hugo server` in memory mode. If you write to this directory from PostCSS when running the server, you could run the server with one of these flags:
++process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null,
+```
+
+PWD
+: The absolute path to the project working directory.
+
+HUGO_ENVIRONMENT
+: The current Hugo environment, set with the `--environment` command line flag.
+Default is `production` for `hugo` and `development` for `hugo server`.
+
+HUGO_PUBLISHDIR
- ```sh
- hugo server --renderToDisk
- hugo server --renderStaticToDisk
- ```
++: The absolute path to the publish directory, typically `public`. This value points to a directory on disk, even when rendering to memory with the `--renderToMemory` command line flag.
+
- Also, Hugo will add environment variables for all files mounted below `assets/_jsconfig`. A default mount will be set up with files in the project root matching this regexp: `(babel|postcss|tailwind)\.config\.js`.
++HUGO_FILE_X
++: Hugo automatically mounts the following files from your project's root directory under `assets/_jsconfig`:
+
- These will get environment variables named on the form `HUGO_FILE_:filename:` where `:filename:` is all upper case with periods replaced with underscore. This allows you to do something like:
++- `babel.config.js`
++- `postcss.config.js`
++- `tailwind.config.js`
+
-
- [node.js]: https://nodejs.org/en/download
- [supported file name]: https://github.com/postcss/postcss-load-config#usage
- [`config/production`]: /getting-started/configuration/#configuration-directory
- [configure build]: /getting-started/configuration/#configure-build
- [purgecss]: https://github.com/FullHuman/purgecss#readme
++For each file, Hugo creates a corresponding environment variable named `HUGO_FILE_:filename:`, where `:filename:` is the uppercase version of the filename with periods replaced by underscores. This allows you to access these files within your JavaScript, for example:
+
+```js
+let tailwindConfig = process.env.HUGO_FILE_TAILWIND_CONFIG_JS || './tailwind.config.js';
+```
+
+## Limitations
+
+Do not use `resources.PostProcess` when running Hugo's built-in development server. The examples above specifically prevent this by verifying that the current environment is not "development".
+
+The `resources.PostProcess` function only works within templates that produce HTML files.
+
+You cannot manipulate the values returned from the resource’s methods. For example, the `strings.ToUpper` function in this example will not work as expected:
+
+```go-html-template
+{{ $css := resources.Get "css/main.css" }}
+{{ $css = $css | css.PostCSS | minify | fingerprint | resources.PostProcess }}
+{{ $css.RelPermalink | strings.ToUpper }}
+```
--- /dev/null
- related:
- - functions/resources/Fingerprint
- - functions/resources/Minify
- - functions/css/PostCSS
- - functions/resources/PostProcess
+---
+title: resources.ToCSS
+description: Transpiles Sass to CSS.
+categories: []
+keywords: []
+action:
- toc: true
- expiryDate: 2025-06-24 # deprecated 2024-06-24
++ related: []
+ returnType: resource.Resource
+ signatures: ['resources.ToCSS [OPTIONS] RESOURCE']
-
- ```go-html-template
- {{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict "transpiler" "libsass" "targetPath" "css/style.css" }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- {{ end }}
- {{ end }}
- {{ end }}
- ```
-
- Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language.
-
- Sass has two forms of syntax: [SCSS] and [indented]. Hugo supports both.
-
- [scss]: https://sass-lang.com/documentation/syntax#scss
- [indented]: https://sass-lang.com/documentation/syntax#the-indented-syntax
-
- ## Options
-
- transpiler
- : (`string`) The transpiler to use, either `libsass` (default) or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass) below.
-
- targetPath
- : (`string`) If not set, the transformed resource's target path will be the original path of the asset file with its extension replaced by `.css`.
-
- vars
- : (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
-
- ```scss
- // LibSass
- @import "hugo:vars";
-
- // Dart Sass
- @use "hugo:vars" as v;
- ```
-
- outputStyle
- : (`string`) Output styles available to LibSass include `nested` (default), `expanded`, `compact`, and `compressed`. Output styles available to Dart Sass include `expanded` (default) and `compressed`.
-
- precision
- : (`int`) Precision of floating point math. Not applicable to Dart Sass.
-
- enableSourceMap
- : (`bool`) If `true`, generates a source map.
-
- sourceMapIncludeSources
- : (`bool`) If `true`, embeds sources in the generated source map. Not applicable to LibSass.
-
- includePaths
- : (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
-
- ```go-html-template
- {{ $opts := dict
- "transpiler" "dartsass"
- "targetPath" "css/style.css"
- "vars" site.Params.styles
- "enableSourceMap" (not hugo.IsProduction)
- "includePaths" (slice "node_modules/bootstrap/scss")
- }}
- {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- ```
-
- ## Dart Sass
-
- The extended version of Hugo includes [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass].
-
- Use the latest features of the Sass language by installing Dart Sass in your development and production environments.
-
- ### Installation overview
-
- Dart Sass is compatible with Hugo v0.114.0 and later.
-
- If you have been using Embedded Dart Sass[^1] with Hugo v0.113.0 and earlier, uninstall Embedded Dart Sass, then install Dart Sass. If you have installed both, Hugo will use Dart Sass.
-
- If you install Hugo as a [Snap package] there is no need to install Dart Sass. The Hugo Snap package includes Dart Sass.
-
- [^1]: In 2023, the Sass team deprecated Embedded Dart Sass in favor of Dart Sass.
-
- ### Installing in a development environment
-
- When you install Dart Sass somewhere in your PATH, Hugo will find it.
-
- OS|Package manager|Site|Installation
- :--|:--|:--|:--
- Linux|Homebrew|[brew.sh]|`brew install sass/sass/sass`
- Linux|Snap|[snapcraft.io]|`sudo snap install dart-sass`
- macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass`
- Windows|Chocolatey|[chocolatey.org]|`choco install sass`
- Windows|Scoop|[scoop.sh]|`scoop install sass`
-
- You may also install [prebuilt binaries] for Linux, macOS, and Windows.
-
- Run `hugo env` to list the active transpilers.
-
- ### Installing in a production environment
-
- For [CI/CD] deployments (e.g., GitHub Pages, GitLab Pages, Netlify, etc.) you must edit the workflow to install Dart Sass before Hugo builds the site[^2]. Some providers allow you to use one of the package managers above, or you can download and extract one of the prebuilt binaries.
-
- [^2]: You do not have to do this if (a) you have not modified the assets cache location, and (b) you have not set `useResourceCacheWhen` to `never` in your [site configuration], and (c) you add and commit your `resources` directory to your repository.
-
- #### GitHub Pages
-
- To install Dart Sass for your builds on GitHub Pages, add this step to the GitHub Pages workflow file:
-
- ```yaml
- - name: Install Dart Sass
- run: sudo snap install dart-sass
- ```
-
- If you are using GitHub Pages for the first time with your repository, GitHub provides a [starter workflow] for Hugo that includes Dart Sass. This is the simplest way to get started.
-
- #### GitLab Pages
-
- To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file should look something like this:
-
- ```yaml
- variables:
- HUGO_VERSION: 0.141.0
- DART_SASS_VERSION: 1.83.4
- GIT_DEPTH: 0
- GIT_STRATEGY: clone
- GIT_SUBMODULE_STRATEGY: recursive
- TZ: America/Los_Angeles
- image:
- name: golang:1.20-buster
- pages:
- script:
- # Install Dart Sass
- - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
- - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
- - cp -r dart-sass/* /usr/local/bin
- - rm -rf dart-sass*
- # Install Hugo
- - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- - apt install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- # Build
- - hugo --gc --minify
- artifacts:
- paths:
- - public
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- ```
-
- #### Netlify
-
- To install Dart Sass for your builds on Netlify, the `netlify.toml` file should look something like this:
-
- ```toml
- [build.environment]
- HUGO_VERSION = "0.141.0"
- DART_SASS_VERSION = "1.83.4"
- NODE_VERSION = "22"
- TZ = "America/Los_Angeles"
-
- [build]
- publish = "public"
- command = """\
- curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- export PATH=/opt/build/repo/dart-sass:$PATH && \
- hugo --gc --minify \
- """
- ```
-
- ### Example
-
- To transpile with Dart Sass, set `transpiler` to `dartsass` in the options map passed to `resources.ToCSS`. For example:
-
- ```go-html-template
- {{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict "transpiler" "dartsass" "targetPath" "css/style.css" }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsDevelopment }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ else }}
- {{ with . | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- {{ end }}
- {{ end }}
- {{ end }}
- ```
-
- ### Miscellaneous
-
- If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model.
-
- [brew.sh]: https://brew.sh/
- [chocolatey.org]: https://community.chocolatey.org/packages/sass
- [ci/cd]: https://en.wikipedia.org/wiki/CI/CD
- [dart sass]: https://sass-lang.com/dart-sass
- [libsass]: https://sass-lang.com/libsass
- [prebuilt binaries]: https://github.com/sass/dart-sass/releases/latest
- [scoop.sh]: https://scoop.sh/#/apps?q=sass
- [site configuration]: /getting-started/configuration/#configure-build
- [snap package]: /installation/linux/#snap
- [snapcraft.io]: https://snapcraft.io/dart-sass
- [starter workflow]: https://github.com/actions/starter-workflows/blob/main/pages/hugo.yml
++expiryDate: 2026-06-24 # deprecated 2024-06-24 in v0.128.0
+---
+
+{{% deprecated-in 0.128.0 %}}
+Use [`css.Sass`] instead.
+
+[`css.Sass`]: /functions/css/sass/
+{{% /deprecated-in %}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: strings.Diff
+description: Returns an anchored diff of the two texts OLD and NEW in the unified diff format. If OLD and NEW are identical, returns an empty string.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: string
+ signatures: [strings.Diff OLDNAME OLD NEWNAME NEW]
+---
+
++{{< new-in 0.125.0 />}}
+
+Use `strings.Diff` to compare two strings and render a highlighted diff:
+
+```go-html-template
+{{ $want := `
+<p>The product of 6 and 7 is 42.</p>
+<p>The product of 7 and 6 is 42.</p>
+`}}
+
+{{ $got := `
+<p>The product of 6 and 7 is 42.</p>
+<p>The product of 7 and 6 is 13.</p>
+`}}
+
+{{ $diff := strings.Diff "want" $want "got" $got }}
+{{ transform.Highlight $diff "diff" }}
+```
+
+Rendered:
+
+
--- /dev/null
- {{< new-in 0.136.3 >}}
+---
+title: strings.TrimSpace
+description: Returns the given string, removing leading and trailing whitespace as defined by Unicode.
+categories: []
+keywords: []
+action:
+ related:
+ - functions/strings/Chomp
+ - functions/strings/Trim
+ - functions/strings/TrimLeft
+ - functions/strings/TrimPrefix
+ - functions/strings/TrimRight
+ - functions/strings/TrimSuffix
+ returnType: string
+ signatures: [strings.TrimSpace INPUT]
+---
+
++{{< new-in 0.136.3 />}}
+
+Whitespace characters include `\t`, `\n`, `\v`, `\f`, `\r`, and characters in the [Unicode Space Separator] category.
+
+[Unicode Space Separator]: https://www.compart.com/en/unicode/category/Zs
+
+```go-html-template
+{{ strings.TrimSpace "\n\r\t foo \n\r\t" }} → foo
+```
--- /dev/null
- {{< new-in "0.128.0" >}}
+---
+title: templates.Defer
+description: Defer execution of a template until after all sites and output formats have been rendered.
+categories: []
+keywords: []
+toc: true
+action:
+ aliases: []
+ related: []
+ returnType: string
+ signatures: [templates.Defer OPTIONS]
+aliases: [/functions/templates.defer]
+---
+
++{{< new-in 0.128.0 />}}
+
+In some rare use cases, you may need to defer the execution of a template until after all sites and output formats have been rendered. One such example could be [TailwindCSS](/functions/css/tailwindcss/) using the output of [hugo_stats.json](/getting-started/configuration/#configure-build) to determine which classes and other HTML identifiers are being used in the final output:
+
+```go-html-template
+{{ with (templates.Defer (dict "key" "global")) }}
+ {{ $t := debug.Timer "tailwindcss" }}
+ {{ with resources.Get "css/styles.css" }}
+ {{ $opts := dict
+ "inlineImports" true
+ "optimize" hugo.IsProduction
+ }}
+ {{ with . | css.TailwindCSS $opts }}
+ {{ if hugo.IsDevelopment }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" />
+ {{ else }}
+ {{ with . | minify | fingerprint }}
+ <link
+ rel="stylesheet"
+ href="{{ .RelPermalink }}"
+ integrity="{{ .Data.Integrity }}"
+ crossorigin="anonymous" />
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ $t.Stop }}
+{{ end }}
+```
+
+{{% note %}}
+This function only works in combination with the `with` keyword.
+{{% /note %}}
+
+{{% note %}}
+Variables defined on the outside are not visible on the inside and vice versa. To pass in data, use the `data` [option](#options).
+{{% /note %}}
+
+For the above to work well when running the server (or `hugo -w`), you want to have a configuration similar to this:
+
+{{< code-toggle file=hugo >}}
+[module]
+[[module.mounts]]
+source = "hugo_stats.json"
+target = "assets/notwatching/hugo_stats.json"
+disableWatch = true
+[build.buildStats]
+enable = true
+[[build.cachebusters]]
+source = "assets/notwatching/hugo_stats\\.json"
+target = "styles\\.css"
+[[build.cachebusters]]
+source = "(postcss|tailwind)\\.config\\.js"
+target = "css"
+{{< /code-toggle >}}
+
+## Options
+
+The `templates.Defer` function takes a single argument, a map with the following optional keys:
+
+key (`string`)
+: The key to use for the deferred template. This will, combined with a hash of the template content, be used as a cache key. If this is not set, Hugo will execute the deferred template on every render. This is not what you want for shared resources like CSS and JavaScript.
+
+data (`map`)
+: Optional map to pass as data to the deferred template. This will be available in the deferred template as `.` or `$`.
+
+```go-html-template
+Language Outside: {{ site.Language.Lang }}
+Page Outside: {{ .RelPermalink }}
+I18n Outside: {{ i18n "hello" }}
+{{ $data := (dict "page" . )}}
+{{ with (templates.Defer (dict "data" $data )) }}
+ Language Inside: {{ site.Language.Lang }}
+ Page Inside: {{ .page.RelPermalink }}
+ I18n Inside: {{ i18n "hello" }}
+{{ end }}
+```
+
+The [Output Format](/templates/output-formats/), [Site](/methods/page/site/), and [language](/methods/site/language) will be the same, even if the execution is deferred. In the example above, this means that the `site.Language.Lang` and `.RelPermalink` will be the same on the inside and the outside of the deferred template.
--- /dev/null
- {{< new-in "0.132.0" >}}
+---
+title: transform.ToMath
+description: Renders mathematical equations and expressions written in the LaTeX markup language.
+categories: []
+keywords: [katex,latex,math,typesetting]
+action:
+ aliases: []
+ related:
+ - content-management/mathematics
+ returnType: types.Result[template.HTML]
+ signatures: ['transform.ToMath INPUT [OPTIONS]']
+aliases: [/functions/tomath]
+toc: true
+---
+
++{{< new-in 0.132.0 />}}
+
+Hugo uses an embedded instance of the [KaTeX] display engine to render mathematical markup to HTML. You do not need to install the KaTeX display engine.
+
+[KaTeX]: https://katex.org/
+
+```go-html-template
+{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }}
+```
+
+{{% note %}}
+By default, Hugo renders mathematical markup to [MathML], and does not require any CSS to display the result.
+
+[MathML]: https://developer.mozilla.org/en-US/docs/Web/MathML
+
+To optimize rendering quality and accessibility, use the `htmlAndMathml` output option as described below. This approach requires an external stylesheet.
+
+{{% /note %}}
+
+```go-html-template
+{{ $opts := dict "output" "htmlAndMathml" }}
+{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" $opts }}
+```
+
+## Options
+
+Pass a map of options as the second argument to the `transform.ToMath` function. The options below are a subset of the KaTeX [rendering options].
+
+[rendering options]: https://katex.org/docs/options.html
+
+displayMode
+: (`bool`) If `true` render in display mode, else render in inline mode. Default is `false`.
+
+errorColor
+: (`string`) The color of the error messages expressed as an RGB [hexadecimal color]. Default is `#cc0000`.
+
+[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
+
+fleqn
+: (`bool`) If `true` render flush left with a 2em left margin. Default is `false`.
+
+macros
+: (`map`) A map of macros to be used in the math expression. Default is `{}`.
+
+ ```go-html-template
+ {{ $macros := dict
+ "\\addBar" "\\bar{#1}"
+ "\\bold" "\\mathbf{#1}"
+ }}
+ {{ $opts := dict "macros" $macros }}
+ {{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }}
+ ```
+
+minRuleThickness
+: (`float`) The minimum thickness of the fraction lines in `em`. Default is `0.04`.
+
+output
+: (`string`). Determines the markup language of the output, one of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`.
+
+ With `html` and `htmlAndMathml` you must include the KaTeX style sheet within the `head` element of your base template.
+
+ ```html
+ <link href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" rel="stylesheet">
+
+throwOnError
+: (`bool`) If `true` throw a `ParseError` when KaTeX encounters an unsupported command or invalid LaTeX. Default is `true`.
+
+## Error handling
+
+There are three ways to handle errors:
+
+1. Let KaTeX throw an error and fail the build. This is the default behavior.
+1. Set the `throwOnError` option to `false` to make KaTeX render the expression as an error instead of throwing an error. See [options](#options).
+1. Handle the error in your template.
+
+The example below demonstrates error handing within a template.
+
+## Example
+
+Instead of client-side JavaScript rendering of mathematical markup using MathJax or KaTeX, create a passthrough render hook which calls the `transform.ToMath` function.
+
+###### Step 1
+
+Enable and configure the Goldmark [passthrough extension] in your site configuration. The passthrough extension preserves raw Markdown within delimited snippets of text, including the delimiters themselves.
+
+[passthrough extension]: /getting-started/configuration-markup/#passthrough
+
+{{< code-toggle file=hugo copy=true >}}
+[markup.goldmark.extensions.passthrough]
+enable = true
+
+[markup.goldmark.extensions.passthrough.delimiters]
+block = [['\[', '\]'], ['$$', '$$']]
+inline = [['\(', '\)']]
+{{< /code-toggle >}}
+
+{{% note %}}
+The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration, you will need to double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting.
+{{% /note %}}
+
+###### Step 2
+
+Create a [passthrough render hook] to capture and render the LaTeX markup.
+
+[passthrough render hook]: /render-hooks/passthrough/
+
+{{< code file=layouts/_default/_markup/render-passthrough.html copy=true >}}
+{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
+{{- with try (transform.ToMath .Inner $opts) }}
+ {{- with .Err }}
+ {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }}
+ {{- else }}
+ {{- .Value }}
+ {{- $.Page.Store.Set "hasMath" true }}
+ {{- end }}
+{{- end -}}
+{{< /code >}}
+
+###### Step 3
+
+In your base template, conditionally include the KaTeX CSS within the head element.
+
+{{< code file=layouts/_default/baseof.html copy=true >}}
+<head>
+ {{ $noop := .WordCount }}
+ {{ if .Page.Store.Get "hasMath" }}
+ <link href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" rel="stylesheet">
+ {{ end }}
+</head>
+{{< /code >}}
+
+In the above, note the use of a [noop](g) statement to force content rendering before we check the value of `hasMath` with the `Store.Get` method.
+
+#### Step 4
+
+Add some mathematical markup to your content, then test.
+
+{{< code file=content/example.md >}}
+This is an inline \(a^*=x-b^*\) equation.
+
+These are block equations:
+
+\[a^*=x-b^*\]
+
+$$a^*=x-b^*$$
+{{< /code >}}
--- /dev/null
- lazyQuotes {{< new-in 0.122.0 >}}
+---
+title: transform.Unmarshal
+description: Parses serialized data and returns a map or an array. Supports CSV, JSON, TOML, YAML, and XML.
+categories: []
+keywords: []
+action:
+ aliases: [unmarshal]
+ related:
+ - functions/transform/Remarshal
+ - functions/resources/Get
+ - functions/resources/GetRemote
+ - functions/encoding/Jsonify
+ returnType: any
+ signatures: ['transform.Unmarshal [OPTIONS] INPUT']
+toc: true
+aliases: [/functions/transform.unmarshal]
+---
+
+The input can be a string or a [resource](g).
+
+## Unmarshal a string
+
+```go-html-template
+{{ $string := `
+title: Les Misérables
+author: Victor Hugo
+`}}
+
+{{ $book := unmarshal $string }}
+{{ $book.title }} → Les Misérables
+{{ $book.author }} → Victor Hugo
+```
+
+## Unmarshal a resource
+
+Use the `transform.Unmarshal` function with global, page, and remote resources.
+
+### Global resource
+
+A global resource is a file within the `assets` directory, or within any directory mounted to the `assets` directory.
+
+```text
+assets/
+└── data/
+ └── books.json
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $path := "data/books.json" }}
+{{ with resources.Get $path }}
+ {{ with . | transform.Unmarshal }}
+ {{ $data = . }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get global resource %q" $path }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+### Page resource
+
+A page resource is a file within a [page bundle].
+
+```text
+content/
+├── post/
+│ └── book-reviews/
+│ ├── books.json
+│ └── index.md
+└── _index.md
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $path := "books.json" }}
+{{ with .Resources.Get $path }}
+ {{ with . | transform.Unmarshal }}
+ {{ $data = . }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get page resource %q" $path }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+### Remote resource
+
+A remote resource is a file on a remote server, accessible via HTTP or HTTPS.
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books.json" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+{{% note %}}
+When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`.
+
+In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead:
+
+`{{ $data = .Content | transform.Unmarshal }}`
+
+[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
+{{% /note %}}
+
+## Options
+
+When unmarshaling a CSV file, provide an optional map of options.
+
+delimiter
+: (`string`) The delimiter used, default is `,`.
+
+comment
+: (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.
+
++lazyQuotes {{< new-in 0.122.0 />}}
+: (`bool`) If true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field. Default is `false`.
+
+```go-html-template
+{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }}
+```
+
+## Working with XML
+
+When unmarshaling an XML file, do not include the root node when accessing data. For example, after unmarshaling the RSS feed below, access the feed title with `$data.channel.title`.
+
+```xml
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>Books on Example Site</title>
+ <link>https://example.org/books/</link>
+ <description>Recent content in Books on Example Site</description>
+ <language>en-US</language>
+ <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title>The Hunchback of Notre Dame</title>
+ <description>Written by Victor Hugo</description>
+ <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
+ <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
+ </item>
+ <item>
+ <title>Les Misérables</title>
+ <description>Written by Victor Hugo</description>
+ <link>https://example.org/books/les-miserables/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
+ <guid>https://example.org/books/les-miserables/</guid>
+ </item>
+ </channel>
+</rss>
+```
+
+Get the remote data:
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books/index.xml" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+Inspect the data structure:
+
+```go-html-template
+<pre>{{ debug.Dump $data }}</pre>
+```
+
+List the book titles:
+
+```go-html-template
+{{ with $data.channel.item }}
+ <ul>
+ {{ range . }}
+ <li>{{ .title }}</li>
+ {{ end }}
+ </ul>
+{{ end }}
+```
+
+Hugo renders this to:
+
+```html
+<ul>
+ <li>The Hunchback of Notre Dame</li>
+ <li>Les Misérables</li>
+</ul>
+```
+
+### XML attributes and namespaces
+
+Let's add a `lang` attribute to the `title` nodes of our RSS feed, and a namespaced node for the ISBN number:
+
+```xml
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:isbn="http://schemas.isbn.org/ns/1999/basic.dtd"
+>
+ <channel>
+ <title>Books on Example Site</title>
+ <link>https://example.org/books/</link>
+ <description>Recent content in Books on Example Site</description>
+ <language>en-US</language>
+ <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title lang="en">The Hunchback of Notre Dame</title>
+ <description>Written by Victor Hugo</description>
+ <isbn:number>9780140443530</isbn:number>
+ <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
+ <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
+ </item>
+ <item>
+ <title lang="fr">Les Misérables</title>
+ <description>Written by Victor Hugo</description>
+ <isbn:number>9780451419439</isbn:number>
+ <link>https://example.org/books/les-miserables/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
+ <guid>https://example.org/books/les-miserables/</guid>
+ </item>
+ </channel>
+</rss>
+```
+
+After retrieving the remote data, inspect the data structure:
+
+```go-html-template
+<pre>{{ debug.Dump $data }}</pre>
+```
+
+Each item node looks like this:
+
+```json
+{
+ "description": "Written by Victor Hugo",
+ "guid": "https://example.org/books/the-hunchback-of-notre-dame/",
+ "link": "https://example.org/books/the-hunchback-of-notre-dame/",
+ "number": "9780140443530",
+ "pubDate": "Mon, 09 Oct 2023 09:27:12 -0700",
+ "title": {
+ "#text": "The Hunchback of Notre Dame",
+ "-lang": "en"
+ }
+}
+```
+
+The title keys do not begin with an underscore or a letter---they are not valid [identifiers](g). Use the [`index`] function to access the values:
+
+```go-html-template
+{{ with $data.channel.item }}
+ <ul>
+ {{ range . }}
+ {{ $title := index .title "#text" }}
+ {{ $lang := index .title "-lang" }}
+ {{ $ISBN := .number }}
+ <li>{{ $title }} ({{ $lang }}) {{ $ISBN }}</li>
+ {{ end }}
+ </ul>
+{{ end }}
+```
+
+Hugo renders this to:
+
+```html
+<ul>
+ <li>The Hunchback of Notre Dame (en) 9780140443530</li>
+ <li>Les Misérables (fr) 9780451419439</li>
+</ul>
+```
+
+[`index`]: /functions/collections/indexfunction/
+[page bundle]: /content-management/page-bundles/
--- /dev/null
- {{< new-in 0.121.0 >}}
+---
+title: transform.XMLEscape
+description: Returns the given string, removing disallowed characters then escaping the result to its XML equivalent.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related: []
+ returnType: string
+ signatures: [transform.XMLEscape INPUT]
+---
+
++{{< new-in 0.121.0 />}}
+
+The `transform.XMLEscape` function removes [disallowed characters] as defined in the XML specification, then escapes the result by replacing the following characters with [HTML entities]:
+
+- `"` → `"`
+- `'` → `'`
+- `&` → `&`
+- `<` → `<`
+- `>` → `>`
+- `\t` → `	`
+- `\n` → `
`
+- `\r` → `
`
+
+For example:
+
+```go-html-template
+{{ transform.XMLEscape "<p>abc</p>" }} → <p>abc</p>
+```
+
+When using `transform.XMLEscape` in a template rendered by Go's [html/template] package, declare the string to be safe HTML to avoid double escaping. For example, in an RSS template:
+
+{{< code file="layouts/_default/rss.xml" >}}
+<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
+{{< /code >}}
+
+[disallowed characters]: https://www.w3.org/TR/xml/#charsets
+[html entities]: https://developer.mozilla.org/en-us/docs/glossary/entity
+[html/template]: https://pkg.go.dev/html/template
--- /dev/null
- linkTitle: In this section
- description: Quick start and guides for installing Hugo on your preferred operating system.
+---
+title: Getting started
++
++description: How to get started with Hugo.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: getting-started-in-this-section
+ parent: getting-started
+ weight: 10
+weight: 10
+aliases: [/overview/introduction/]
+---
+
+If this is your first time using Hugo and you've [already installed Hugo on your machine][installed], we recommend the [quick start]. You can also use [external learning resources] to learn Hugo.
+
+[installed]: /installation/
+[quick start]: /getting-started/quick-start/
+[external learning resources]: /getting-started/external-learning-resources/
--- /dev/null
- #### buildStats
+---
+title: Configure build
+description: Configure global build options.
+categories: [getting started,fundamentals]
+keywords: [build,buildStats,cache]
+menu:
+ docs:
+ parent: getting-started
+ weight: 70
+weight: 70
+slug: configuration-build
+toc: true
+---
+
+The `build` configuration section contains global build-related configuration options.
+
+{{< code-toggle config=build />}}
+
- #### cachebusters
++###### buildStats
+
+See [Configure buildStats](#configure-build-stats).
+
- #### noJSConfigInAssets
++###### cachebusters
+
+See [Configure Cache Busters](#configure-cache-busters).
+
- #### useResourceCacheWhen
++###### noJSConfigInAssets
+
+(`bool`) If `true`, turns off writing a `jsconfig.json` into your `assets` directory with mapping of imports from running [js.Build](/hugo-pipes/js). This file is intended to help with intellisense/navigation inside code editors such as [VS Code](https://code.visualstudio.com/). Note that if you do not use `js.Build`, no file will be written.
+
- (`string`) When to use the cached resources in `/resources/_gen` for PostCSS and ToCSS. Valid values are `never`, `always` and `fallback`. The last value means that the cache will be tried if PostCSS/extended version is not available.
++###### useResourceCacheWhen
+
- When `buildStats` {{< new-in 0.115.1 >}} is enabled, Hugo writes a `hugo_stats.json` file on each build with HTML classes etc. that's used in the rendered output. Changes to this file will trigger a rebuild of the `styles.css` file. You also need to add `hugo_stats.json` to Hugo's server watcher. See [Hugo Starter Tailwind Basic](https://github.com/bep/hugo-starter-tailwind-basic) for a running example.
++(`string`) When to use the resource file cache, one of `never`, `fallback`, or `always`. Applicable when transpiling Sass to CSS. Default is `fallback`.
+
+## Configure cache busters
+
+The `build.cachebusters` configuration option was added to support development using Tailwind 3.x's JIT compiler where a `build` configuration may look like this:
+
+{{< code-toggle file=hugo >}}
+[build]
+ [build.buildStats]
+ enable = true
+ [[build.cachebusters]]
+ source = "assets/watching/hugo_stats\\.json"
+ target = "styles\\.css"
+ [[build.cachebusters]]
+ source = "(postcss|tailwind)\\.config\\.js"
+ target = "css"
+ [[build.cachebusters]]
+ source = "assets/.*\\.(js|ts|jsx|tsx)"
+ target = "js"
+ [[build.cachebusters]]
+ source = "assets/.*\\.(.*)$"
+ target = "$1"
+{{< /code-toggle >}}
+
- {{< new-in 0.115.1 >}}
++When `buildStats` {{< new-in 0.115.1 />}} is enabled, Hugo writes a `hugo_stats.json` file on each build with HTML classes etc. that's used in the rendered output. Changes to this file will trigger a rebuild of the `styles.css` file. You also need to add `hugo_stats.json` to Hugo's server watcher. See [Hugo Starter Tailwind Basic](https://github.com/bep/hugo-starter-tailwind-basic) for a running example.
+
+source
+: A regexp matching file(s) relative to one of the virtual component directories in Hugo, typically `assets/...`.
+
+target
+: A regexp matching the keys in the resource cache that should be expired when `source` changes. You can use the matching regexp groups from `source` in the expression, e.g. `$1`.
+
+## Configure build stats
+
+{{< code-toggle config=build.buildStats />}}
+
- [removing unused CSS]: /hugo-pipes/postprocess/#css-purging-with-postcss
++{{< new-in 0.115.1 />}}
+
+If `enable` is set to `true`, creates a `hugo_stats.json` file in the root of your project. This file contains arrays of the `class` attributes, `id` attributes, and tags of every HTML element within your published site. Use this file as data source when [removing unused CSS] from your site. This process is also known as pruning, purging, or tree shaking.
+
++[removing unused CSS]: /functions/resources/postprocess/
+
+Exclude `class` attributes, `id` attributes, or tags from `hugo_stats.json` with the `disableClasses`, `disableIDs`, and `disableTags` keys.
+
+{{% note %}}
+Given that CSS purging is typically limited to production builds, place the `buildStats` object below [`config/production`].
+
+[`config/production`]: /getting-started/configuration/#configuration-directory
+
+Built for speed, there may be "false positive" detections (e.g., HTML elements that are not HTML elements) while parsing the published site. These "false positives" are infrequent and inconsequential.
+{{% /note %}}
+
+Due to the nature of partial server builds, new HTML entities are added while the server is running, but old values will not be removed until you restart the server or run a regular `hugo` build.
--- /dev/null
- {{< new-in 0.126.0 >}}
+---
+title: Configure markup
+description: Configure rendering of markup to HTML.
+categories: [getting started,fundamentals]
+keywords: [markup,markdown,goldmark,asciidoc,asciidoctor,highlighting]
+menu:
+ docs:
+ parent: getting-started
+ weight: 60
+weight: 60
+slug: configuration-markup
+toc: true
+---
+
+## Default handler
+
+Hugo uses [Goldmark] to render Markdown to HTML.
+
+{{< code-toggle file=hugo >}}
+[markup]
+defaultMarkdownHandler = 'goldmark'
+{{< /code-toggle >}}
+
+Files with a `.md`, `.mdown`, or `.markdown` extension are processed as Markdown, provided that you have not specified a different [content format] using the `markup` field in front matter.
+
+To use a different renderer for Markdown files, specify one of `asciidocext`, `org`, `pandoc`, or `rst` in your site configuration.
+
+defaultMarkdownHandler|Description
+:--|:--
+`asciidocext`|[AsciiDoc]
+`goldmark`|[Goldmark]
+`org`|[Emacs Org Mode]
+`pandoc`|[Pandoc]
+`rst`|[reStructuredText]
+
+To use AsciiDoc, Pandoc, or reStructuredText you must install the relevant renderer and update your [security policy].
+
+{{% note %}}
+Unless you need a unique capability provided by one of the alternative Markdown handlers, we strongly recommend that you use the default setting. Goldmark is fast, well maintained, conforms to the [CommonMark] specification, and is compatible with [GitHub Flavored Markdown] (GFM).
+
+[commonmark]: https://spec.commonmark.org/0.30/
+[github flavored markdown]: https://github.github.com/gfm/
+{{% /note %}}
+
+[asciidoc]: https://asciidoc.org/
+[content format]: /content-management/formats/#formats
+[emacs org mode]: https://orgmode.org/
+[goldmark]: https://github.com/yuin/goldmark/
+[pandoc]: https://pandoc.org/
+[restructuredtext]: https://docutils.sourceforge.io/rst.html
+[security policy]: /about/security/#security-policy
+
+## Goldmark
+
+This is the default configuration for the Goldmark Markdown renderer:
+
+{{< code-toggle config=markup.goldmark />}}
+
+### Goldmark extensions
+
+The extensions below, excluding Extras and Passthrough, are enabled by default.
+
+Extension|Documentation|Enabled
+:--|:--|:-:
+cjk|[Goldmark Extensions: CJK]|:heavy_check_mark:
+definitionList|[PHP Markdown Extra: Definition lists]|:heavy_check_mark:
+extras|[Hugo Goldmark Extensions: Extras]|
+footnote|[PHP Markdown Extra: Footnotes]|:heavy_check_mark:
+linkify|[GitHub Flavored Markdown: Autolinks]|:heavy_check_mark:
+passthrough|[Hugo Goldmark Extensions: Passthrough]|
+strikethrough|[GitHub Flavored Markdown: Strikethrough]|:heavy_check_mark:
+table|[GitHub Flavored Markdown: Tables]|:heavy_check_mark:
+taskList|[GitHub Flavored Markdown: Task list items]|:heavy_check_mark:
+typographer|[Goldmark Extensions: Typographer]|:heavy_check_mark:
+
+[GitHub Flavored Markdown: Autolinks]: https://github.github.com/gfm/#autolinks-extension-
+[GitHub Flavored Markdown: Strikethrough]: https://github.github.com/gfm/#strikethrough-extension-
+[GitHub Flavored Markdown: Tables]: https://github.github.com/gfm/#tables-extension-
+[GitHub Flavored Markdown: Task list items]: https://github.github.com/gfm/#task-list-items-extension-
+[Goldmark Extensions: CJK]: https://github.com/yuin/goldmark?tab=readme-ov-file#cjk-extension
+[Goldmark Extensions: Typographer]: https://github.com/yuin/goldmark?tab=readme-ov-file#typographer-extension
+[Hugo Goldmark Extensions: Extras]: https://github.com/gohugoio/hugo-goldmark-extensions?tab=readme-ov-file#extras-extension
+[Hugo Goldmark Extensions: Passthrough]: https://github.com/gohugoio/hugo-goldmark-extensions?tab=readme-ov-file#passthrough-extension
+[PHP Markdown Extra: Definition lists]: https://michelf.ca/projects/php-markdown/extra/#def-list
+[PHP Markdown Extra: Footnotes]: https://michelf.ca/projects/php-markdown/extra/#footnotes
+
+#### Extras
+
- {{< new-in 0.122.0 >}}
++{{< new-in 0.126.0 />}}
+
+Enable [deleted text], [inserted text], [mark text], [subscript], and [superscript] elements in Markdown.
+
+Element|Markdown|Rendered
+:--|:--|:--
+Deleted text|`~~foo~~`|`<del>foo</del>`
+Inserted text|`++bar++`|`<ins>bar</ins>`
+Mark text|`==baz==`|`<mark>baz</mark>`
+Subscript|`H~2~O`|`H<sub>2</sub>O`
+Superscript|`1^st^`|`1<sup>st</sup>`
+
+[deleted text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del
+[inserted text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins
+[mark text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark
+[subscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub
+[superscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup
+
+To avoid a conflict when enabling the Hugo Goldmark Extras subscript extension, if you want to render subscript and strikethrough text concurrently you must:
+
+1. Disable the Goldmark strikethrough extension
+1. Enable the Hugo Goldmark Extras delete extension
+
+For example:
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.extensions]
+strikethrough = false
+
+[markup.goldmark.extensions.extras.delete]
+enable = true
+
+[markup.goldmark.extensions.extras.subscript]
+enable = true
+{{< /code-toggle >}}
+
+#### Passthrough
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.122.0 />}}
+
+Enable the passthrough extension to include mathematical equations and expressions in Markdown using LaTeX markup. See [mathematics in Markdown] for details.
+
+[mathematics in Markdown]: content-management/mathematics/
+
+#### Typographer
+
+The Typographer extension replaces certain character combinations with HTML entities as specified below:
+
+Markdown|Replaced by|Description
+:--|:--|:--
+`...`|`…`|horizontal ellipsis
+`'`|`’`|apostrophe
+`--`|`–`|en dash
+`---`|`—`|em dash
+`«`|`«`|left angle quote
+`“`|`“`|left double quote
+`‘`|`‘`|left single quote
+`»`|`»`|right angle quote
+`”`|`”`|right double quote
+`’`|`’`|right single quote
+
+### Goldmark settings explained
+
+Most of the Goldmark settings above are self-explanatory, but some require explanation.
+
+###### duplicateResourceFiles
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.123.0 />}}
+
+(`bool`) If `true`, shared page resources on multilingual single-host sites will be duplicated for each language. See [multilingual page resources] for details. Default is `false`.
+
+[multilingual page resources]: /content-management/page-resources/#multilingual
+
+{{% note %}}
+With multilingual single-host sites, setting this parameter to `false` will enable Hugo's [embedded link render hook] and [embedded image render hook]. This is the default configuration for multilingual single-host sites.
+
+[embedded image render hook]: /render-hooks/images/#default
+[embedded link render hook]: /render-hooks/links/#default
+{{% /note %}}
+
+###### parser.wrapStandAloneImageWithinParagraph
+
+(`bool`) If `true`, image elements without adjacent content will be wrapped within a `p` element when rendered. This is the default Markdown behavior. Set to `false` when using an [image render hook] to render standalone images as `figure` elements. Default is `true`.
+
+[image render hook]: /render-hooks/images/
+
+###### parser.autoHeadingIDType
+
+(`string`) The strategy used to automatically generate heading `id` attributes, one of `github`, `github-ascii` or `blackfriday`.
+
+- `github` produces GitHub-compatible `id` attributes
+- `github-ascii` drops any non-ASCII characters after accent normalization
+- `blackfriday` produces `id` attributes compatible with the Blackfriday Markdown renderer
+
+This is also the strategy used by the [anchorize](/functions/urls/anchorize) template function. Default is `github`.
+
+###### parser.attribute.block
+
+(`bool`) If `true`, enables [Markdown attributes] for block elements. Default is `false`.
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+###### parser.attribute.title
+
+(`bool`) If `true`, enables [Markdown attributes] for headings. Default is `true`.
+
+###### renderHooks.image.enableDefault
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.123.0 />}}
+
+(`bool`) If `true`, enables Hugo's [embedded image render hook]. Default is `false`.
+
+[embedded image render hook]: /render-hooks/images/#default
+
+{{% note %}}
+The embedded image render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites.
+
+[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles
+{{% /note %}}
+
+###### renderHooks.link.enableDefault
+
++{{< new-in 0.123.0 />}}
+
+(`bool`) If `true`, enables Hugo's [embedded link render hook]. Default is `false`.
+
+[embedded link render hook]: /render-hooks/links/#default
+
+{{% note %}}
+The embedded link render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites.
+
+[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles
+{{% /note %}}
+
+###### renderer.hardWraps
+
+(`bool`) If `true`, Goldmark replaces newline characters within a paragraph with `br` elements. Default is `false`.
+
+###### renderer.unsafe
+
+(`bool`) If `true`, Goldmark renders raw HTML mixed within the Markdown. This is unsafe unless the content is under your control. Default is `false`.
+
+## AsciiDoc
+
+This is the default configuration for the AsciiDoc renderer:
+
+{{< code-toggle config=markup.asciidocExt />}}
+
+### AsciiDoc settings explained
+
+###### attributes
+
+(`map`) A map of key-value pairs, each a document attribute. See Asciidoctor’s [attributes].
+
+[attributes]: https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions
+
+###### backend
+
+(`string`) The backend output file format. Default is `html5`.
+
+###### extensions
+
+(`string array`) An array of enabled extensions, one or more of `asciidoctor-html5s`, `asciidoctor-bibtex`, `asciidoctor-diagram`, `asciidoctor-interdoc-reftext`, `asciidoctor-katex`, `asciidoctor-latex`, `asciidoctor-mathematical`, or `asciidoctor-question`.
+
+{{% note %}}
+To mitigate security risks, entries in the extension array may not contain forward slashes (`/`), backslashes (`\`), or periods. Due to this restriction, extensions must be in Ruby's `$LOAD_PATH`.
+{{% /note %}}
+
+###### failureLevel
+
+(`string`) The minimum logging level that triggers a non-zero exit code (failure). Default is `fatal`.
+
+###### noHeaderOrFooter
+
+(`bool`) If `true`, outputs an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Default is `true`.
+
+###### preserveTOC
+
+(`bool`) If `true`, preserves the table of contents (TOC) rendered by Asciidoctor. By default, to make the TOC compatible with existing themes, Hugo removes the TOC rendered by Asciidoctor. To render the TOC, use the [`TableOfContents`] method on a `Page` object in your templates. Default is `false`.
+
+[`TableOfContents`]: /methods/page/tableofcontents/
+
+###### safeMode
+
+(`string`) The safe mode level, one of `unsafe`, `safe`, `server`, or `secure`. Default is `unsafe`.
+
+###### sectionNumbers
+
+(`bool`) If `true`, numbers each section title. Default is `false`.
+
+###### trace
+
+(`bool`) If `true`, include backtrace information on errors. Default is `false`.
+
+###### verbose
+
+(`bool`)If `true`, verbosely prints processing information and configuration file checks to stderr. Default is `false`.
+
+###### workingFolderCurrent
+
+(`bool`) If `true`, sets the working directory to be the same as that of the AsciiDoc file being processed, allowing [includes] to work with relative paths. Set to `true` to render diagrams with the [asciidoctor-diagram] extension. Default is `false`.
+
+[asciidoctor-diagram]: https://asciidoctor.org/docs/asciidoctor-diagram/
+[includes]: https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/#includes
+
+### AsciiDoc configuration example
+
+{{< code-toggle file=hugo >}}
+[markup.asciidocExt]
+ extensions = ["asciidoctor-html5s", "asciidoctor-diagram"]
+ workingFolderCurrent = true
+ [markup.asciidocExt.attributes]
+ my-base-url = "https://example.com/"
+ my-attribute-name = "my value"
+{{< /code-toggle >}}
+
+### AsciiDoc syntax highlighting
+
+Follow the steps below to enable syntax highlighting.
+
+Step 1
+: Set the `source-highlighter` attribute in your site configuration. For example:
+
+{{< code-toggle file=hugo >}}
+[markup.asciidocExt.attributes]
+source-highlighter = 'rouge'
+{{< /code-toggle >}}
+
+Step 2
+: Generate the highlighter CSS. For example:
+
+```text
+rougify style monokai.sublime > assets/css/syntax.css
+```
+
+Step 3
+: In your base template add a link to the CSS file:
+
+{{< code file=layouts/_default/baseof.html >}}
+<head>
+ ...
+ {{ with resources.Get "css/syntax.css" }}
+ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
+ {{ end }}
+ ...
+</head>
+{{< /code >}}
+
+Then add the code to be highlighted to your markup:
+
+```text
+[#hello,ruby]
+----
+require 'sinatra'
+
+get '/hi' do
+ "Hello World!"
+end
+----
+```
+
+### AsciiDoc troubleshooting
+
+Run `hugo --logLevel debug` to examine Hugo's call to the Asciidoctor executable:
+
+```txt
+INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ...
+```
+
+## Highlight
+
+This is the default `highlight` configuration. Note that some of these settings can be set per code block, see [Syntax Highlighting](/content-management/syntax-highlighting/).
+
+{{< code-toggle config=markup.highlight />}}
+
+For `style`, see these galleries:
+
+* [Short snippets](https://xyproto.github.io/splash/docs/all.html)
+* [Long snippets](https://xyproto.github.io/splash/docs/longer/all.html)
+
+For CSS, see [Generate Syntax Highlighter CSS](/content-management/syntax-highlighting/#generate-syntax-highlighter-css).
+
+## Table of contents
+
+This is the default configuration for the table of contents, applicable to Goldmark and Asciidoctor:
+
+{{< code-toggle config=markup.tableOfContents />}}
+
+###### startLevel
+
+(`int`) Heading levels less than this value will be excluded from the table of contents. For example, to exclude `h1` elements from the table of contents, set this value to `2`. Default is `2`.
+
+###### endLevel
+
+(`int`) Heading levels greater than this value will be excluded from the table of contents. For example, to exclude `h4`, `h5`, and `h6` elements from the table of contents, set this value to `3`. Default is `3`.
+
+###### ordered
+
+(`bool`) If `true`, generates an ordered list instead of an unordered list. Default is `false`.
--- /dev/null
- (`bool`) See [details](/content-management/urls/#canonical-urls) before enabling this feature. Default is `false`.
+---
+title: Configure Hugo
+linkTitle: Configuration
+description: How to configure your Hugo site.
+categories: [getting started,fundamentals]
+keywords: [configuration,toml,yaml,json]
+menu:
+ docs:
+ parent: getting-started
+ weight: 50
+weight: 50
+toc: true
+aliases: [/overview/source-directory/,/overview/configuration/]
+---
+
+## Configuration file
+
+Create a site configuration file in the root of your project directory, naming it `hugo.toml`, `hugo.yaml`, or `hugo.json`, with that order of precedence.
+
+```text
+my-project/
+└── hugo.toml
+```
+
+{{% note %}}
+With v0.109.0 and earlier the basename of the site configuration file was `config` instead of `hugo`. You can use either, but should transition to the new naming convention when practical.
+{{% /note %}}
+
+A simple example:
+
+{{< code-toggle file=hugo >}}
+baseURL = 'https://example.org/'
+languageCode = 'en-us'
+title = 'ABC Widgets, Inc.'
+[params]
+subtitle = 'The Best Widgets on Earth'
+[params.contact]
+email = 'info@example.org'
+phone = '+1 202-555-1212'
+{{< /code-toggle >}}
+
+To use a different configuration file when building your site, use the `--config` flag:
+
+```sh
+hugo --config other.toml
+```
+
+Combine two or more configuration files, with left-to-right precedence:
+
+```sh
+hugo --config a.toml,b.yaml,c.json
+```
+
+{{% note %}}
+See the specifications for each file format: [TOML], [YAML], and [JSON].
+
+[TOML]: https://toml.io/en/latest
+[YAML]: https://yaml.org/spec/
+[JSON]: https://datatracker.ietf.org/doc/html/rfc7159
+{{% /note %}}
+
+## Configuration directory
+
+Instead of a single site configuration file, split your configuration by [environment](g), root configuration key, and language. For example:
+
+```text
+my-project/
+└── config/
+ ├── _default/
+ │ ├── hugo.toml
+ │ ├── menus.en.toml
+ │ ├── menus.de.toml
+ │ └── params.toml
+ └── production/
+ └── params.toml
+```
+
+The root configuration keys are `build`, `caches`, `cascade`, `deployment`, `frontmatter`, `imaging`, `languages`, `markup`, `mediatypes`, `menus`, `minify`, `module`, `outputformats`, `outputs`, `params`, `permalinks`, `privacy`, `related`, `security`, `segments`, `server`, `services`, `sitemap`, and `taxonomies`.
+
+### Omit the root key
+
+When splitting the configuration by root key, omit the root key in the given file. For example, these are equivalent:
+
+{{< code-toggle file=hugo >}}
+[params]
+foo = 'bar'
+{{< /code-toggle >}}
+
+{{< code-toggle file=params >}}
+foo = 'bar'
+{{< /code-toggle >}}
+
+### Recursive parsing
+
+Hugo parses the `config` directory recursively, allowing you to organize the files into subdirectories. For example:
+
+```text
+my-project/
+└── config/
+ └── _default/
+ ├── navigation/
+ │ ├── menus.de.toml
+ │ └── menus.en.toml
+ └── hugo.toml
+```
+
+### Example
+
+```text
+my-project/
+└── config/
+ ├── _default/
+ │ ├── hugo.toml
+ │ ├── menus.en.toml
+ │ ├── menus.de.toml
+ │ └── params.toml
+ ├── production/
+ │ ├── hugo.toml
+ │ └── params.toml
+ └── staging/
+ ├── hugo.toml
+ └── params.toml
+```
+
+Considering the structure above, when running `hugo --environment staging`, Hugo will use every setting from `config/_default` and merge `staging`'s on top of those.
+
+Let's take an example to understand this better. Let's say you are using Google Analytics for your website. This requires you to specify a [Google tag ID] in your site configuration:
+
+[Google tag ID]: https://support.google.com/tagmanager/answer/12326985?hl=en
+
+{{< code-toggle file=hugo copy=false >}}
+[services.googleAnalytics]
+ID = 'G-XXXXXXXXX'
+{{< /code-toggle >}}
+
+Now consider the following scenario:
+
+1. You don't want to load the analytics code when running `hugo server`.
+1. You want to use different Google tag IDs for your production and staging environments. For example:
+
+ - `G-PPPPPPPPP` for production
+ - `G-SSSSSSSSS` for staging
+
+To satisfy these requirements, configure your site as follows:
+
+1. `config/_default/hugo.toml`
+
+ Exclude the `services.googleAnalytics` section. This will prevent loading of the analytics code when you run `hugo server`.
+
+ By default, Hugo sets its `environment` to `development` when running `hugo server`. In the absence of a `config/development` directory, Hugo uses the `config/_default` directory.
+
+1. `config/production/hugo.toml`
+
+ Include this section only:
+
+ {{< code-toggle file=hugo copy=false >}}
+ [services.googleAnalytics]
+ ID = 'G-PPPPPPPPP'
+ {{< /code-toggle >}}
+
+ You do not need to include other parameters in this file. Include only those parameters that are specific to your production environment. Hugo will merge these parameters with the default configuration.
+
+ By default, Hugo sets its `environment` to `production` when running `hugo`. The analytics code will use the `G-PPPPPPPPP` tag ID.
+
+1. `config/staging/hugo.toml`
+
+ Include this section only:
+
+ {{< code-toggle file=hugo copy=false >}}
+ [services.googleAnalytics]
+ ID = 'G-SSSSSSSSS'
+ {{< /code-toggle >}}
+
+ You do not need to include other parameters in this file. Include only those parameters that are specific to your staging environment. Hugo will merge these parameters with the default configuration.
+
+ To build your staging site, run `hugo --environment staging`. The analytics code will use the `G-SSSSSSSSS` tag ID.
+
+## Merge configuration from themes
+
+The configuration value for `_merge` can be one of:
+
+none
+: No merge.
+
+shallow
+: Only add values for new keys.
+
+deep
+: Add values for new keys, merge existing.
+
+Note that you don't need to be so verbose as in the default setup below; a `_merge` value higher up will be inherited if not set.
+
+{{< code-toggle file=hugo dataKey="config_helpers.mergeStrategy" skipHeader=true />}}
+
+## All configuration settings
+
+###### archetypeDir
+
+(`string`) The directory where Hugo finds archetype files (content templates). Default is `archetypes`. {{% module-mounts-note %}}
+
+###### assetDir
+
+(`string`) The directory where Hugo finds asset files used in [Hugo Pipes](/hugo-pipes/). Default is `assets`. {{% module-mounts-note %}}
+
+###### baseURL
+
+(`string`) The absolute URL (protocol, host, path, and trailing slash) of your published site (e.g., `https://www.example.org/docs/`).
+
+###### build
+
+See [Configure Build](#configure-build).
+
+###### buildDrafts
+
+(`bool`) Include drafts when building. Default is `false`.
+
+###### buildExpired
+
+(`bool`) Include content already expired. Default is `false`.
+
+###### buildFuture
+
+(`bool`) Include content with a future publication date. Default is `false`.
+
+###### caches
+
+See [Configure File Caches](#configure-file-caches).
+
+###### canonifyURLs
+
- {{< new-in 0.123.3 >}}
++(`bool`) See [details](/content-management/urls/#canonical-urls) before enabling this feature. Default is `false`.
+
+###### capitalizeListTitles
+
- (`bool`) Whether to capitalize automatic list titles. Applicable to section, taxonomy, and term pages. Default is `true`. You can change the capitalization style in your site configuration to one of `ap`, `chicago`, `go`, `firstupper`, or `none`. See [details].
++{{< new-in 0.123.3 />}}
+
- {{< new-in 0.140.0 >}}
++(`bool`) Whether to capitalize automatic list titles. Applicable to section, taxonomy, and term pages. Default is `true`. You can change the capitalization style in your site configuration to one of `ap`, `chicago`, `go`, `firstupper`, or `none`. See [details].
+
+[details]: /getting-started/configuration/#configure-title-case
+
+###### cascade
+
+Pass down default configuration values (front matter) to pages in the content tree. The options in site config is the same as in page front matter, see [Front Matter Cascade](/content-management/front-matter#cascade).
+
+{{% note %}}
+For a website in a single language, define the `[[cascade]]` in [Front Matter](/content-management/front-matter#cascade). For a multilingual website, define the `[[cascade]]` in [Site Config](/getting-started/configuration/#cascade).
+
+To remain consistent and prevent unexpected behavior, do not mix these strategies.
+{{% /note %}}
+
+###### cleanDestinationDir
+
+(`bool`) When building, removes files from destination not found in static directories. Default is `false`.
+
+###### contentDir
+
+(`string`) The directory from where Hugo reads content files. Default is `content`. {{% module-mounts-note %}}
+
+###### copyright
+
+(`string`) Copyright notice for your site, typically displayed in the footer.
+
+###### dataDir
+
+(`string`) The directory from where Hugo reads data files. Default is `data`. {{% module-mounts-note %}}
+
+###### defaultOutputFormat
+(`string`) The default output format for the site. If unspecified, the first available format in the defined order (by weight, then alphabetically) will be used.
+
+###### defaultContentLanguage
+
+(`string`) Content without language indicator will default to this language. Default is `en`.
+
+###### defaultContentLanguageInSubdir
+
+(`bool`) Render the default content language in subdir, e.g. `content/en/`. The site root `/` will then redirect to `/en/`. Default is `false`.
+
+###### disableAliases
+
+(`bool`) Will disable generation of alias redirects. Note that even if `disableAliases` is set, the aliases themselves are preserved on the page. The motivation with this is to be able to generate 301 redirects in an `.htaccess`, a Netlify `_redirects` file or similar using a custom output format. Default is `false`.
+
+###### disableDefaultLanguageRedirect
+
- (`string slice`) Disable rendering of the specified page [kinds](g), any of `404`, `home`, `page`, `robotstxt`, `rss`, `section`, `sitemap`, `taxonomy`, or `term`.
++{{< new-in 0.140.0 />}}
+
+(`bool`) Disables generation of redirect to the default language when DefaultContentLanguageInSubdir is `true`. Default is `false`.
+
+###### disableHugoGeneratorInject
+
+(`bool`) Hugo will, by default, inject a generator meta tag in the HTML head on the _home page only_. You can turn it off, but we would really appreciate if you don't, as this is a good way to watch Hugo's popularity on the rise. Default is `false`.
+
+###### disableKinds
+
- (`string slice`) A slice of message identifiers corresponding to warnings and errors you wish to suppress. See [`erroridf`] and [`warnidf`].
++(`[]string`) Disable rendering of the specified page [kinds](g), any of `404`, `home`, `page`, `robotstxt`, `rss`, `section`, `sitemap`, `taxonomy`, or `term`.
+
+###### disableLanguages
+
+See [disable a language](/content-management/multilingual/#disable-a-language).
+
+###### disableLiveReload
+
+(`bool`) Disable automatic live reloading of browser window. Default is `false`.
+
+###### disablePathToLower
+
+(`bool`) Do not convert the url/path to lowercase. Default is `false`.
+
+###### enableEmoji
+
+(`bool`) Enable Emoji emoticons support for page content; see the [emoji shortcode quick reference guide](/quick-reference/emojis/). Default is `false`.
+
+###### enableGitInfo
+
+(`bool`) Enable `.GitInfo` object for each page (if the Hugo site is versioned by Git). This will then update the `Lastmod` parameter for each page using the last git commit date for that content file. Default is `false`.
+
+###### enableMissingTranslationPlaceholders
+
+(`bool`) Show a placeholder instead of the default value or an empty string if a translation is missing. Default is `false`.
+
+###### enableRobotsTXT
+
+(`bool`) Enable generation of `robots.txt` file. Default is `false`.
+
+###### environment
+
+(`string`) Build environment. Default is `production` when running `hugo` and `development` when running `hugo server`. See [Configuration directory](https://gohugo.io/getting-started/configuration/#configuration-directory).
+###### frontmatter
+
+See [Front matter Configuration](#configure-front-matter).
+
+###### hasCJKLanguage
+
+(`bool`) If true, auto-detect Chinese/Japanese/Korean Languages in the content. This will make `.Summary` and `.WordCount` behave correctly for CJK languages. Default is `false`.
+
+###### ignoreCache
+
+(`bool`) Ignore the cache directory. Default is `false`.
+
+###### ignoreLogs
- (`bool`) See [details](/content-management/urls/#relative-urls) before enabling this feature. Default is `false`.
++(`[]string`) A slice of message identifiers corresponding to warnings and errors you wish to suppress. See [`erroridf`] and [`warnidf`].
+
+[`erroridf`]: /functions/fmt/erroridf/
+[`warnidf`]: /functions/fmt/warnidf/
+
+###### ignoreVendorPaths
+
+(`string`) Ignore vendored modules that match the given [Glob] pattern within the `_vendor` directory.
+
+[Glob]: https://github.com/gobwas/glob?tab=readme-ov-file#example]
+
+###### imaging
+
+See [image processing configuration](/content-management/image-processing/#imaging-configuration).
+
+###### languageCode
+
+(`string`) A language tag as defined by [RFC 5646](https://datatracker.ietf.org/doc/html/rfc5646). This value is used to populate:
+
+- The `<language>` element in the embedded [RSS template]({{% eturl rss %}})
+- The `lang` attribute of the `<html>` element in the embedded [alias template]({{% eturl alias %}})
+- The `og:locale` `meta` element in the embedded [Open Graph template]({{% eturl opengraph %}})
+
+When present in the root of the configuration, this value is ignored if one or more language keys exists. Please specify this value independently for each language key.
+
+###### languages
+
+See [Configure Languages](/content-management/multilingual/#configure-languages).
+
+###### layoutDir
+
+(`string`) The directory that contains templates. Default is `layouts`.
+
+###### markup
+
+See [Configure Markup](/getting-started/configuration-markup).
+
+###### mediaTypes
+
+See [Configure Media Types](/templates/output-formats/#media-types).
+
+###### menus
+
+See [Menus](/content-management/menus/#define-in-site-configuration).
+
+###### minify
+
+See [Configure Minify](#configure-minify).
+
+###### module
+
+Module configuration see [module configuration](/hugo-modules/configuration/).
+
+###### newContentEditor
+
+(`string`) The editor to use when creating new content.
+
+###### noBuildLock
+
+(`bool`) Don't create `.hugo_build.lock` file. Default is `false`.
+
+###### noChmod
+
+(`bool`) Don't sync permission mode of files. Default is `false`.
+
+###### noTimes
+
+(`bool`) Don't sync modification time of files. Default is `false`.
+
+###### outputFormats
+
+See [custom output formats].
+
+###### page
+
+See [configure page](#configure-page).
+
+###### pagination
+
+See [configure pagination](/templates/pagination/#configuration).
+
+###### panicOnWarning
+
+(`bool`) Whether to panic on first WARNING. Default is `false`.
+
+###### permalinks
+
+See [Content Management](/content-management/urls/#permalinks).
+
+###### pluralizeListTitles
+
+(`bool`) Whether to pluralize automatic list titles. Applicable to section pages. Default is `true`.
+
+###### printI18nWarnings
+
+(`bool`) Whether to log WARNINGs for each missing translation. Default is `false`.
+
+###### printPathWarnings
+
+(`bool`) Whether to log WARNINGs when Hugo publishes two or more files to the same path. Default is `false`.
+
+###### printUnusedTemplates
+
+(`bool`) Whether to log WARNINGs for each unused template. Default is `false`.
+
+###### publishDir
+
+(`string`) The directory where Hugo will write the final static site (the HTML files etc.). Default is `public`.
+
+###### refLinksErrorLevel
+
+(`string`) When using `ref` or `relref` to resolve page links and a link cannot be resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`). Default is `ERROR`.
+
+###### refLinksNotFoundURL
+
+(`string`) URL to be used as a placeholder when a page reference cannot be found in `ref` or `relref`. Is used as-is.
+
+###### related
+
+See [Related Content](/content-management/related/#configure-related-content).
+
+###### relativeURLs
+
- {{< new-in 0.124.0 >}}
++(`bool`) See [details](/content-management/urls/#relative-urls) before enabling this feature. Default is `false`.
+
+###### removePathAccents
+
+(`bool`) Removes [non-spacing marks](https://www.compart.com/en/unicode/category/Mn) from [composite characters](https://en.wikipedia.org/wiki/Precomposed_character) in content paths. Default is `false`.
+
+```text
+content/post/hügó.md → https://example.org/post/hugo/
+```
+
+###### renderSegments
+
- (`string slice`) A list of segments to render. If not set, everything will be rendered. This is more commonly set in a CLI flag, e.g. `hugo --renderSegments segment1,segment2`. The segment names must match the names in the [segments](#configure-segments) configuration.
++{{< new-in 0.124.0 />}}
+
- (`bool` or `map`) Whether to generate uglyURLs. Default is `false`. See [details](/content-management/urls/#appearance).
++(`[]string`) A list of segments to render. If not set, everything will be rendered. This is more commonly set in a CLI flag, e.g. `hugo --renderSegments segment1,segment2`. The segment names must match the names in the [segments](#configure-segments) configuration.
+
+###### sectionPagesMenu
+
+See [Menus](/content-management/menus/#define-automatically).
+
+###### security
+
+See [Security Policy](/about/security/#security-policy).
+
+###### segments
+
+See [Segments](#configure-segments).
+
+###### sitemap
+
+Default [sitemap configuration](/templates/sitemap/#configuration).
+
+###### summaryLength
+
+(`int`) Applicable to [automatic summaries], the minimum number of words to render when calling the [`Summary`] method on a `Page` object. In this case the `Summary` method returns the content, truncated to the paragraph closest to the `summaryLength`.
+
+[automatic summaries]: /content-management/summaries/#automatic-summary
+[`Summary`]: /methods/page/summary/
+
+###### taxonomies
+
+See [Configure Taxonomies](/content-management/taxonomies#configure-taxonomies).
+
+###### templateMetrics
+
+(`bool`) Whether to print template execution metrics to the console. Default is `false`. See [Template metrics](/troubleshooting/performance/#template-metrics).
+
+###### templateMetricsHints
+
+(`bool`) Whether to print template execution improvement hints to the console. Applicable when `templateMetrics` is `true`. Default is `false`. See [Template metrics](/troubleshooting/performance/#template-metrics).
+
+###### theme
+
+See [module configuration](/hugo-modules/configuration/#module-configuration-imports) for how to import a theme.
+
+###### themesDir
+
+(`string`) The directory where Hugo reads the themes from. Default is `themes`.
+
+###### timeout
+
+(`string`) Timeout for generating page contents, specified as a [duration](https://pkg.go.dev/time#Duration) or in seconds. *Note:* this is used to bail out of recursive content generation. You might need to raise this limit if your pages are slow to generate (e.g., because they require large image processing or depend on remote contents). Default is `30s`.
+
+###### timeZone
+
+(`string`) The time zone used to parse dates without time zone offsets, including front matter date fields and values passed to the [`time.AsTime`] and [`time.Format`] template functions. The list of valid values may be system dependent, but should include `UTC`, `Local`, and any location in the [IANA Time Zone Database]. For example, `America/Los_Angeles` and `Europe/Oslo` are valid time zones.
+
+[`time.AsTime`]: /functions/time/astime/
+[`time.Format`]: /functions/time/format/
+[IANA Time Zone Database]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
+
+###### title
+
+(`string`) Site title.
+
+###### titleCaseStyle
+
+(`string`) Default is `ap`. See [Configure Title Case](#configure-title-case).
+
+###### uglyURLs
+
- {{< new-in 0.133.0 >}}
++(`bool` or `map`) Whether to generate uglyURLs. Default is `false`. See [details](/content-management/urls/#appearance).
+
+###### watch
+
+(`bool`) Watch filesystem for changes and recreate as needed. Default is `false`.
+
+{{% note %}}
+If you are developing your site on a \*nix machine, here is a handy shortcut for finding a configuration option from the command line:
+```txt
+cd ~/sites/yourhugosite
+hugo config | grep emoji
+```
+
+which shows output like
+
+```txt
+enableemoji: true
+```
+{{% /note %}}
+
+## Configure page
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.133.0 />}}
+
+These methods on a `Page` object navigate to the next or previous page within a page collection, relative to the current page:
+
+- [Next](/methods/page/next/)
+- [NextInSection](/methods/page/nextinsection/)
+- [Prev](/methods/page/prev/)
+- [PrevInSection](/methods/page/previnsection/)
+
+Hugo determines the _next_ and _previous_ page by sorting a page collection according to this sorting hierarchy:
+
+Field|Precedence|Sort direction
+:--|:--|:--
+[`weight`]|1|descending
+[`date`]|2|descending
+[`linkTitle`]|3|descending
+[`path`]|4|descending
+
+[`date`]: /methods/page/date/
+[`weight`]: /methods/page/weight/
+[`linkTitle`]: /methods/page/linktitle/
+[`path`]: /methods/page/path/
+
+The sort direction in the table above corresponds to these default site configuration values:
+
+{{< code-toggle config=page />}}
+
+To sort all fields in ascending order:
+
+{{< code-toggle file=hugo >}}
+[page]
+ nextPrevInSectionSortOrder = 'asc'
+ nextPrevSortOrder = 'asc'
+{{< /code-toggle >}}
+
+{{% note %}}
+These settings do not apply to the [`Next`] or [`Prev`] methods on a `Pages` object.
+
+[`Next`]: /methods/pages/next
+[`Prev`]: /methods/pages/next
+{{% /note %}}
+
+## Configure build
+
+See [Configure Build](/getting-started/configuration-build/).
+
+## Configure server
+
+This is only relevant when running `hugo server`, and it allows to set HTTP headers during development, which allows you to test out your Content Security Policy and similar. The configuration format matches [Netlify's](https://docs.netlify.com/routing/headers/#syntax-for-the-netlify-configuration-file) with slightly more powerful [Glob matching](https://github.com/gobwas/glob):
+
+{{< code-toggle file=hugo >}}
+[server]
+[[server.headers]]
+for = "/**"
+
+[server.headers.values]
+X-Frame-Options = "DENY"
+X-XSS-Protection = "1; mode=block"
+X-Content-Type-Options = "nosniff"
+Referrer-Policy = "strict-origin-when-cross-origin"
+Content-Security-Policy = "script-src localhost:1313"
+{{< /code-toggle >}}
+
+Since this is "development only", it may make sense to put it below the `development` environment:
+
+{{< code-toggle file=config/development/server >}}
+[[headers]]
+for = "/**"
+
+[headers.values]
+X-Frame-Options = "DENY"
+X-XSS-Protection = "1; mode=block"
+X-Content-Type-Options = "nosniff"
+Referrer-Policy = "strict-origin-when-cross-origin"
+Content-Security-Policy = "script-src localhost:1313"
+{{< /code-toggle >}}
+
+You can also specify simple redirects rules for the server. The syntax is again similar to Netlify's.
+
+Note that a `status` code of 200 will trigger a [URL rewrite](https://docs.netlify.com/routing/redirects/rewrites-proxies/), which is what you want in SPA situations, e.g:
+
+{{< code-toggle file=config/development/server >}}
+[[redirects]]
+from = "/myspa/**"
+to = "/myspa/"
+status = 200
+force = false
+{{< /code-toggle >}}
+
+Setting `force=true` will make a redirect even if there is existing content in the path. Note that before Hugo 0.76 `force` was the default behavior, but this is inline with how Netlify does it.
+
+## 404 server error page {#_404-server-error-page}
+
+Hugo will, by default, render all 404 errors when running `hugo server` with the `404.html` template. Note that if you have already added one or more redirects to your [server configuration](#configure-server), you need to add the 404 redirect explicitly, e.g:
+
+{{< code-toggle file=config/development/server >}}
+[[redirects]]
+from = "/**"
+to = "/404.html"
+status = 404
+{{< /code-toggle >}}
+
+With a multilingual site, define the redirect for the default content language last:
+
+{{< code-toggle file=config/development/server >}}
+defaultContentLanguage = 'en'
+defaultContentLanguageInSubdir = false
+[[redirects]]
+from = '/fr/**'
+to = '/fr/404.html'
+status = 404
+
+[[redirects]] # Default language must be last.
+from = '/**'
+to = '/404.html'
+status = 404
+{{< /code-toggle >}}
+
+If you are serving the default content language from a subdirectory:
+
+{{< code-toggle file=config/development/server >}}
+defaultContentLanguage = 'en'
+defaultContentLanguageInSubdir = true
+[[redirects]]
+from = '/fr/**'
+to = '/fr/404.html'
+status = 404
+
+[[redirects]] # Default language must be last.
+from = '/**'
+to = '/en/404.html'
+status = 404
+{{< /code-toggle >}}
+
+## Configure title case
+
+By default, Hugo follows the capitalization rules published in the [Associated Press Stylebook] when creating automatic section titles, and when transforming strings with the [`strings.Title`] function.
+
+Change this behavior by setting `titleCaseStyle` in your site configuration to any of the values below:
+
+ap
+: Use the capitalization rules published in the [Associated Press Stylebook].
+
+chicago
+: Use the capitalization rules published in the [Chicago Manual of Style].
+
+go
+: Capitalize the first letter of every word.
+
+firstupper
+: Capitalize the first letter of the first word.
+
+none
+: Disable transformation of automatic section titles, and disable the transformation performed by the `strings.Title` function. This is useful if you would prefer to manually capitalize section titles as needed, and to bypass opinionated theme usage of the `strings.Title` function.
+
+[`strings.Title`]: /functions/strings/title/
+[Associated Press Stylebook]: https://www.apstylebook.com/
+[Chicago Manual of Style]: https://www.chicagomanualofstyle.org/home.html
+[site configuration]: /getting-started/configuration/#configure-title-case
+
+## Configuration environment variables
+
+DART_SASS_BINARY
+: (`string`) The absolute path to the Dart Sass executable. By default, Hugo searches for the executable in each of the paths in the `PATH` environment variable.
+
+HUGO_ENVIRONMENT
+: (`string`) Overrides the default [environment](g), typically one of `development`, `staging`, or `production`.
+
+HUGO_FILE_LOG_FORMAT
+: (`string`) A format string for the file path, line number, and column number displayed when reporting errors, or when calling the `Position` method from a shortcode or Markdown render hook. Valid tokens are `:file`, `:line`, and `:col`. Default is `:file::line::col`.
+
- 1. In a `hugo_cache` directory below the OS user cache directory as defined by Go's [os.UserCacheDir](https://pkg.go.dev/os#UserCacheDir). On Unix systems, this is `$XDG_CACHE_HOME` as specified by [basedir-spec-latest](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) if non-empty, else `$HOME/.cache`. On MacOS, this is `$HOME/Library/Caches`. On Windows, this is`%LocalAppData%`. On Plan 9, this is `$home/lib/cache`. {{< new-in 0.116.0 >}}
++{{< new-in 0.123.0 />}}
+
+HUGO_MEMORYLIMIT
+: (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory.
+
+HUGO_NUMWORKERMULTIPLIER
+: (`int`) The number of workers used in parallel processing. Default is the number of logical CPUs.
+
+## Configure with environment variables
+
+Configuration key-values can be defined through operating system environment variables.
+
+For example, the following command will effectively set a website's title on Unix-like systems:
+
+```txt
+$ env HUGO_TITLE="Some Title" hugo
+```
+
+This is really useful if you use a service such as Netlify to deploy your site. Look at the Hugo docs [Netlify configuration file](https://github.com/gohugoio/hugoDocs/blob/master/netlify.toml) for an example.
+
+{{% note %}}
+Names must be prefixed with `HUGO_` and the configuration key must be set in uppercase when setting operating system environment variables.
+
+To set configuration parameters, prefix the name with `HUGO_PARAMS_`
+{{% /note %}}
+
+If you are using snake_cased variable names, the above will not work. Hugo determines the delimiter to use by the first character after `HUGO`. This allows you to define environment variables on the form `HUGOxPARAMSxAPI_KEY=abcdefgh`, using any [allowed](https://stackoverflow.com/questions/2821043/allowed-characters-in-linux-environment-variable-names#:~:text=So%20names%20may%20contain%20any,not%20begin%20with%20a%20digit.) delimiter.
+
+## Ignore content and data files when rendering
+
+{{% note %}}
+This works, but we recommend you use the newer and more powerful [includeFiles and excludeFiles](/hugo-modules/configuration/#module-configuration-mounts) mount options.
+{{% /note %}}
+
+To exclude specific files from the `content`, `data`, and `i18n` directories when rendering your site, set `ignoreFiles` to one or more regular expressions to match against the absolute file path.
+
+To ignore files ending with `.foo` or `.boo`:
+
+{{< code-toggle file=hugo >}}
+ignoreFiles = ['\.foo$', '\.boo$']
+{{< /code-toggle >}}
+
+To ignore a file using the absolute file path:
+
+{{< code-toggle file=hugo >}}
+ignoreFiles = ['^/home/user/project/content/test\.md$']
+{{< /code-toggle >}}
+
+## Configure front matter
+
+### Configure dates
+
+Dates are important in Hugo, and you can configure how Hugo assigns dates to your content pages. You do this by adding a `frontmatter` section to your `hugo.toml`.
+
+The default configuration is:
+
+{{< code-toggle config=frontmatter />}}
+
+If you, as an example, have a non-standard date parameter in some of your content, you can override the setting for `date`:
+
+{{< code-toggle file=hugo >}}
+[frontmatter]
+date = ["myDate", ":default"]
+{{< /code-toggle >}}
+
+The `:default` is a shortcut to the default settings. The above will set `.Date` to the date value in `myDate` if present, if not we will look in `date`,`publishDate`, `lastmod` and pick the first valid date.
+
+In the list to the right, values starting with ":" are date handlers with a special meaning (see below). The others are just names of date parameters (case insensitive) in your front matter configuration. Also note that Hugo have some built-in aliases to the above: `lastmod` => `modified`, `publishDate` => `pubdate`, `published` and `expiryDate` => `unpublishdate`. With that, as an example, using `pubDate` as a date in front matter, will, by default, be assigned to `.PublishDate`.
+
+The special date handlers are:
+
+`:fileModTime`
+: Fetches the date from the content file's last modification timestamp.
+
+An example:
+
+{{< code-toggle file=hugo >}}
+[frontmatter]
+lastmod = ["lastmod", ":fileModTime", ":default"]
+{{< /code-toggle >}}
+
+The above will try first to extract the value for `.Lastmod` starting with the `lastmod` front matter parameter, then the content file's modification timestamp. The last, `:default` should not be needed here, but Hugo will finally look for a valid date in `:git`, `date` and then `publishDate`.
+
+`:filename`
+: Fetches the date from the content file's file name. For example, `2018-02-22-mypage.md` will extract the date `2018-02-22`. Also, if `slug` is not set, `mypage` will be used as the value for `.Slug`.
+
+An example:
+
+{{< code-toggle file=hugo >}}
+[frontmatter]
+date = [":filename", ":default"]
+{{< /code-toggle >}}
+
+The above will try first to extract the value for `.Date` from the file name, then it will look in front matter parameters `date`, `publishDate` and lastly `lastmod`.
+
+`:git`
+: This is the Git author date for the last revision of this content file. This will only be set if `--enableGitInfo` is set or `enableGitInfo = true` is set in site configuration.
+
+## Configure minify
+
+See the [tdewolff/minify] project page for details.
+
+[tdewolff/minify]: https://github.com/tdewolff/minify
+
+Default configuration:
+
+{{< code-toggle config=minify />}}
+
+## Configure file caches
+
+Since Hugo 0.52 you can configure more than just the `cacheDir`. This is the default configuration:
+
+{{< code-toggle config=caches />}}
+
+You can override any of these cache settings in your own `hugo.toml`.
+
+### The keywords explained
+
+cacheDir
+: (`string`) See [Configure cacheDir](#configure-cachedir).
+
+project
+: (`string`) The base directory name of the current Hugo project. This means that, in its default setting, every project will have separated file caches, which means that when you do `hugo --gc` you will not touch files related to other Hugo projects running on the same PC.
+
+resourceDir
+: (`string`) This is the value of the `resourceDir` configuration option.
+
+maxAge
+: (`string`) This is the duration before a cache entry will be evicted, -1 means forever and 0 effectively turns that particular cache off. Uses Go's `time.Duration`, so valid values are `"10s"` (10 seconds), `"10m"` (10 minutes) and `"10h"` (10 hours).
+
+dir
+: (`string`) The absolute path to where the files for this cache will be stored. Allowed starting placeholders are `:cacheDir` and `:resourceDir` (see above).
+
+## Configure cacheDir
+
+This is the directory where Hugo by default will store its file caches. See [Configure File Caches](#configure-file-caches).
+
+This can be set using the `cacheDir` config option or via the OS environment variable `HUGO_CACHEDIR`.
+
+If this is not set, Hugo will use, in order of preference:
+
+1. If running on Netlify: `/opt/build/cache/hugo_cache/`. This means that if you run your builds on Netlify, all caches configured with `:cacheDir` will be saved and restored on the next build. For other CI vendors, please read their documentation. For an CircleCI example, see [this configuration](https://github.com/bep/hugo-sass-test/blob/6c3960a8f4b90e8938228688bc49bdcdd6b2d99e/.circleci/config.yml).
- {{< new-in 0.127.0 >}}
++1. In a `hugo_cache` directory below the OS user cache directory as defined by Go's [os.UserCacheDir](https://pkg.go.dev/os#UserCacheDir). On Unix systems, this is `$XDG_CACHE_HOME` as specified by [basedir-spec-latest](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) if non-empty, else `$HOME/.cache`. On MacOS, this is `$HOME/Library/Caches`. On Windows, this is`%LocalAppData%`. On Plan 9, this is `$home/lib/cache`. {{< new-in 0.116.0 />}}
+1. In a `hugo_cache_$USER` directory below the OS temp dir.
+
+If you want to know the current value of `cacheDir`, you can run `hugo config`, e.g: `hugo config | grep cachedir`.
+
+[`.Site.Params`]: /method/site/params/
+[directory structure]: /getting-started/directory-structure/
+[lookup order]: /templates/lookup-order/
+[custom output formats]: /templates/output-formats/
+[templates]: /templates/
+[static-files]: /content-management/static-files/
+
+## Configure HTTP cache
+
- {{< new-in 0.124.0 >}}
++{{< new-in 0.127.0 />}}
+
+Note that this configuration is currently only relevant when using the [resources.GetRemote] function.
+
+The caching in Hugo is layered:
+
+```goat {.w-40}
+ .-----------.
+| dynacache |
+ '-----+-----'
+ |
+ v
+ .----------.
+| HTTP cache |
+ '-----+----'
+ |
+ v
+ .----------.
+| file cache |
+ '-----+----'
+```
+
+Dynacache
+: A in memory LRU cache that gets evicted on changes, [Cache Buster](/getting-started/configuration-build/#configure-cache-busters) matches and in low memory situations.
+
+HTTP Cache
+: Enables HTTP cache behavior (RFC 9111) for remote resources. This works best for resources with properly set up HTTP cache headers. The HTTP cache uses the [file cache] to store and serve cached resources.
+
+File Cache
+: See [file cache].
+
+The default HTTP cache disables everything:
+
+{{< code-toggle config=HTTPCache />}}
+
+caching
+: Enabled RFC 9111 cache behavior _for_ a configured set of resources. Stale resources will be refreshed from the [file cache] even if their configured TTL isn't reached.
+
+polling
+: Enables polling _for_ a set of resources. Note that you can enable polling for resources even if HTTP caching is disabled. This setting is only used when in watch mode (e.g. `hugo server`). When a changed resource is detected, that change triggers a rebuild of pages using that resource.
+
+[resources.GetRemote]: /functions/resources/getremote/
+[file cache]: #configure-file-caches
+
+## Configure segments
+
++{{< new-in 0.124.0 />}}
+
+{{% note %}}
+The `segments` configuration is currently only used to configure partitioned rendering.
+This feature is only about what gets rendered when, Hugo's entire object graph (sites and pages) is
+always available.
+{{% /note %}}
+
+* Each segment consists of zero or more `exclude` filters and zero or more `include` filters.
+* Each filter consists of one or more field Glob matchers.
+* Each filter in a section (`exclude` or `include`) is ORed together, each matcher in a filter is ANDed together.
+
+The fields that can be used in the filters are:
+
+path
+: The logical page [path].
+
+lang
+: The [page language].
+
+kind
+: The [kind](g) of the page.
+
+output
+: The [output format](g) of the page.
+
+It is recommended to put coarse grained filters (e.g. for language and output format) in the excludes section, e.g.:
+
+{{< code-toggle file=hugo >}}
+[segments.segment1]
+ [[segments.segment1.excludes]]
+ lang = "n*"
+ [[segments.segment1.excludes]]
+ lang = "en"
+ output = "rss"
+ [[segments.segment1.includes]]
+ kind = "{home,term,taxonomy}"
+ [[segments.segment1.includes]]
+ path = "{/docs,/docs/**}"
+{{< /code-toggle >}}
+
+With the above you can render only the pages in `segment1` by configuring the [renderSegments](#rendersegments) or setting the `--renderSegments` flag:
+
+```bash
+hugo --renderSegments segment1
+```
+
+Multiple segments can be configured, and the `--renderSegments` flag can take a comma separated list of segments.
+
+Some use cases for this feature:
+
+* Splitting builds of big sites.
+* Enable faster builds during development by only rendering a subset of the site.
+* Partial rebuilds, e.g. render the home page and the "news section" every hour, render the entire site once a week.
+* Render only e.g. the JSON output format to push to e.g. a search index.
+
+[path]: /methods/page/path/
+[page language]: /methods/page/language/
--- /dev/null
+---
+title: External learning resources
++linkTitle: External resources
+description: Use these third-party resources to learn Hugo.
+categories: [getting started]
+keywords: [books, tutorials, learning, usage]
+menu:
+ docs:
+ parent: getting-started
+ weight: 90
+weight: 90
+toc: true
+---
+
+## Books
+
+### Hugo In Action
+
+Hugo in Action is a step-by-step guide to using Hugo to create static websites. Working with a complete example website and source code samples, you'll learn how to build and host a low-maintenance, high-performance site that will wow your users and stay stable without relying on a third-party server.
+
+[{{< img src="hugo-in-action.png" alt="Book cover: Hugo in Action" filter="process" filterArgs="resize x350 webp">}}](https://www.manning.com/books/hugo-in-action/)
+
+Author: Atishay Jain\
+Publisher: [Manning Publications](https://www.manning.com/books/hugo-in-action/)\
+Publication date: March 2022\
+Length: 488 pages\
+ISBN: 9781617297007
+
+### Build Websites with Hugo
+
+In this book, you'll use Hugo to build a personal portfolio site that you can use to showcase your skills and thoughts to the world. You'll build the basic skeleton, develop a custom theme, and use content templates to generate new pages quickly. You'll use internal and external data sources to embed content into your site, and render some of your content in JSON and RSS. You'll add a blog section with posts and integrate Disqus with your site, and then make your site searchable.
+
+[{{< img src="build-websites-with-hugo.png" alt="Book cover: Build Websites with Hugo" filter="process" filterArgs="resize x350 webp">}}](https://pragprog.com/titles/bhhugo/build-websites-with-hugo/)
+
+Author: Brian P. Hogan\
+Publisher: [Pragmatic Bookshelf](https://pragprog.com/titles/bhhugo/build-websites-with-hugo/)\
+Publication date: May 2020\
+Length: 154 pages\
+ISBN: 9781680507263
+
+## Videos
+
+### Hugo Beginner Tutorial Series
+
+Welcome to this introduction to Hugo tutorial. The goal of this series is to take you from a lion cub with basic web design knowledge to creating your first Hugo website. In this series you’ll learn how to set up a Hugo site, the basics of usingHugo layouts, partials, and templating, set up a blog, and finally use data files. By the end of this series you’ll have the foundational knowledge to build your own Hugo sites.
+
+1. [Getting set up in Hugo](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/)
+1. [Layouts in Hugo](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/layouts-in-hugo/)
+1. [Hugo Partials](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/hugo-partials/)
+1. [Hugo templating basics](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/hugo-templating-basics/)
+1. [Blogging in Hugo](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/blogging-in-hugo/)
+1. [Using Data in Hugo](https://cloudcannon.com/tutorials/hugo-beginner-tutorial/using-data-in-hugo/)
+
+Creator: Mike Neumegen\
+Affiliation: [CloudCannon](https://cloudcannon.com/)\
+Creation date: April 2022
+
+#### Hugo Static Site Generator
+
+This course covers the basics of using the Hugo static site generator. Work your way through the articles and we'll teach you everything you need to know to create a professional and scalable website or blog!
+
+1. [Introduction](https://www.giraffeacademy.com/static-site-generators/hugo/)
+1. [Windows Installation](https://www.giraffeacademy.com/static-site-generators/hugo/installing-hugo-on-windows/)
+1. [Mac Installation](https://www.giraffeacademy.com/static-site-generators/hugo/installing-hugo-on-mac/)
+1. [Creating A New Site](https://www.giraffeacademy.com/static-site-generators/hugo/hugo-directory-structure/)
+1. [Installing & Using Themes](https://www.giraffeacademy.com/static-site-generators/hugo/installing-using-themes/)
+1. [Content Organization](https://www.giraffeacademy.com/static-site-generators/hugo/content-organization/)
+1. [Front Matter](https://www.giraffeacademy.com/static-site-generators/hugo/front-matter/)
+1. [Archetypes](https://www.giraffeacademy.com/static-site-generators/hugo/archetypes/)
+1. [Shortcodes](https://www.giraffeacademy.com/static-site-generators/hugo/archetypes/)
+1. [Taxonomies](https://www.giraffeacademy.com/static-site-generators/hugo/taxonomies/)
+1. [Template Basics](https://www.giraffeacademy.com/static-site-generators/hugo/introduction-to-templates/)
+1. [List Page Templates](https://www.giraffeacademy.com/static-site-generators/hugo/list-page-templates/)
+1. [Single Page Templates](https://www.giraffeacademy.com/static-site-generators/hugo/single-page-templates/)
+1. [Home Page Templates](https://www.giraffeacademy.com/static-site-generators/hugo/home-page-templates/)
+1. [Section Templates](https://www.giraffeacademy.com/static-site-generators/hugo/section-templates/)
+1. [Block Templates](https://www.giraffeacademy.com/static-site-generators/hugo/block-templates/)
+1. [Variables](https://www.giraffeacademy.com/static-site-generators/hugo/variables/)
+1. [Functions](https://www.giraffeacademy.com/static-site-generators/hugo/functions/)
+1. [Conditionals](https://www.giraffeacademy.com/static-site-generators/hugo/conditionals/)
+1. [Data Templates](https://www.giraffeacademy.com/static-site-generators/hugo/data-templates/)
+1. [Partial Templates](https://www.giraffeacademy.com/static-site-generators/hugo/partial-templates/)
+1. [Shortcode Templates](https://www.giraffeacademy.com/static-site-generators/hugo/shortcode-templates/)
+1. [Building & Hosting](https://www.giraffeacademy.com/static-site-generators/hugo/building-&-hosting/)
+
+Creator: Mike Dane\
+Affiliation: [Giraffe Academy](https://www.giraffeacademy.com/)\
+Creation date: September 2017
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: Basic usage
+description: Hugo's command line interface (CLI) is fully featured but simple to use, even for those with limited experience working from the command line.
+categories: [getting started]
+keywords: [usage,livereload,command,flags]
+menu:
+ docs:
+ parent: getting-started
+ weight: 30
+weight: 30
+toc: true
+aliases: [/overview/usage/,/extras/livereload/,/doc/usage/,/usage/]
+---
+
+## Test your installation
+
+After [installing] Hugo, test your installation by running:
+
+```sh
+hugo version
+```
+
+You should see something like:
+
+```text
+hugo v0.123.0-3c8a4713908e48e6523f058ca126710397aa4ed5+extended linux/amd64 BuildDate=2024-02-19T16:32:38Z VendorInfo=gohugoio
+```
+
+## Display available commands
+
+To see a list of the available commands and flags:
+
+```sh
+hugo help
+```
+
+To get help with a subcommand, use the `--help` flag. For example:
+
+```sh
+hugo server --help
+```
+
+## Build your site
+
+To build your site, `cd` into your project directory and run:
+
+```sh
+hugo
+```
+
+The [`hugo`] command builds your site, publishing the files to the `public` directory. To publish your site to a different directory, use the [`--destination`] flag or set [`publishDir`] in your site configuration.
+
+{{% note %}}
+Hugo does not clear the `public` directory before building your site. Existing files are overwritten, but not deleted. This behavior is intentional to prevent the inadvertent removal of files that you may have added to the `public` directory after the build.
+
+Depending on your needs, you may wish to manually clear the contents of the `public` directory before every build.
+{{% /note %}}
+
+## Draft, future, and expired content
+
+Hugo allows you to set `draft`, `date`, `publishDate`, and `expiryDate` in the [front matter] of your content. By default, Hugo will not publish content when:
+
+- The `draft` value is `true`
+- The `date` is in the future
+- The `publishDate` is in the future
+- The `expiryDate` is in the past
+
++{{< new-in 0.123.0 />}}
+
+{{% note %}}
+Hugo publishes descendants of draft, future, and expired [node](g) pages. To prevent publication of these descendants, use the [`cascade`] front matter field to cascade [build options] to the descendant pages.
+
+[build options]: /content-management/build-options/
+[`cascade`]: /content-management/front-matter/#cascade-field
+{{% /note %}}
+
+You can override the default behavior when running `hugo` or `hugo server` with command line flags:
+
+```sh
+hugo --buildDrafts # or -D
+hugo --buildExpired # or -E
+hugo --buildFuture # or -F
+```
+
+Although you can also set these values in your site configuration, it can lead to unwanted results unless all content authors are aware of, and understand, the settings.
+
+{{% note %}}
+As noted above, Hugo does not clear the `public` directory before building your site. Depending on the _current_ evaluation of the four conditions above, after the build your `public` directory may contain extraneous files from a previous build.
+
+A common practice is to manually clear the contents of the `public` directory before each build to remove draft, expired, and future content.
+{{% /note %}}
+
+## Develop and test your site
+
+To view your site while developing layouts or creating content, `cd` into your project directory and run:
+
+```sh
+hugo server
+```
+
+The [`hugo server`] command builds your site and serves your pages using a minimal HTTP server. When you run `hugo server` it will display the URL of your local site:
+
+```text
+Web Server is available at http://localhost:1313/
+```
+
+While the server is running, it watches your project directory for changes to assets, configuration, content, data, layouts, translations, and static files. When it detects a change, the server rebuilds your site and refreshes your browser using [LiveReload].
+
+Most Hugo builds are so fast that you may not notice the change unless you are looking directly at your browser.
+
+### LiveReload
+
+While the server is running, Hugo injects JavaScript into the generated HTML pages. The LiveReload script creates a connection from the browser to the server via web sockets. You do not need to install any software or browser plugins, nor is any configuration required.
+
+### Automatic redirection
+
+When editing content, if you want your browser to automatically redirect to the page you last modified, run:
+
+```sh
+hugo server --navigateToChanged
+```
+
+## Deploy your site
+
+{{% note %}}
+As noted above, Hugo does not clear the `public` directory before building your site. Manually clear the contents of the `public` directory before each build to remove draft, expired, and future content.
+{{% /note %}}
+
+When you are ready to deploy your site, run:
+
+```sh
+hugo
+```
+
+This builds your site, publishing the files to the `public` directory. The directory structure will look something like this:
+
+```text
+public/
+├── categories/
+│ ├── index.html
+│ └── index.xml <-- RSS feed for this section
+├── posts/
+│ ├── my-first-post/
+│ │ └── index.html
+│ ├── index.html
+│ └── index.xml <-- RSS feed for this section
+├── tags/
+│ ├── index.html
+│ └── index.xml <-- RSS feed for this section
+├── index.html
+├── index.xml <-- RSS feed for the site
+└── sitemap.xml
+```
+
+In a simple hosting environment, where you typically `ftp`, `rsync`, or `scp` your files to the root of a virtual host, the contents of the `public` directory are all that you need.
+
+Most of our users deploy their sites using a CI/CD workflow, where a push[^1] to their GitHub or GitLab repository triggers a build and deployment. Popular providers include [AWS Amplify], [CloudCannon], [Cloudflare Pages], [GitHub Pages], [GitLab Pages], and [Netlify].
+
+Learn more in the [hosting and deployment] section.
+
+[^1]: The Git repository contains the entire project directory, typically excluding the `public` directory because the site is built _after_ the push.
+
+[`--destination`]: /commands/hugo/#options
+[`hugo server`]: /commands/hugo_server/
+[`hugo`]: /commands/hugo/
+[`publishDir`]: /getting-started/configuration/#publishdir
+[AWS Amplify]: https://aws.amazon.com/amplify/
+[CloudCannon]: https://cloudcannon.com/
+[Cloudflare Pages]: https://pages.cloudflare.com/
+[commands]: /commands/
+[front matter]: /content-management/front-matter/
+[GitHub Pages]: https://pages.github.com/
+[GitLab Pages]: https://docs.gitlab.com/ee/user/project/pages/
+[hosting and deployment]: /hosting-and-deployment/
+[hosting]: /hosting-and-deployment/
+[installing]: /installation/
+[LiveReload]: https://github.com/livereload/livereload-js
+[Netlify]: https://www.netlify.com/
--- /dev/null
- linkTitle: In this section
- description: Site builds, automated deployments, and popular hosting solutions.
+---
+title: Hosting and deployment
- weight: 1
++
++description: Services and tools to host and deploy your site.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: hosting-and-deployment-in-this-section
+ parent: hosting-and-deployment
+ weight: 1
++weight: 10
+---
+
+Because Hugo renders *static* websites, you can host your new Hugo website virtually anywhere. The following represent only a few of the more popular hosting and automated deployment solutions used by the Hugo community.
--- /dev/null
- [Dart Sass]: /hugo-pipes/transpile-sass-to-css/#dart-sass
+---
+title: Host on GitHub Pages
+description: Host your site on GitHub Pages with continuous deployment using project, user, or organization pages.
+categories: [hosting and deployment]
+keywords: [hosting]
+menu:
+ docs:
+ parent: hosting-and-deployment
+toc: true
+aliases: [/tutorials/github-pages-blog/]
+---
+
+## Prerequisites
+
+Please complete the following tasks before continuing:
+
+1. [Create a GitHub account]
+1. [Install Git]
+1. [Create a Hugo site] and test it locally with `hugo server`.
+
+[Create a GitHub account]: https://github.com/signup
+[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+[Create a Hugo site]: /getting-started/quick-start/
+
+## Types of sites
+
+There are three types of GitHub Pages sites: project, user, and organization. Project sites are connected to a specific project hosted on GitHub. User and organization sites are connected to a specific account on GitHub.com.
+
+{{% note %}}
+See the [GitHub Pages documentation] to understand the requirements for repository ownership and naming.
+
+[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites
+{{% /note %}}
+
+[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites
+
+## Procedure
+
+Step 1
+: Create a GitHub repository.
+
+Step 2
+: Push your local repository to GitHub.
+
+Step 3
+: Visit your GitHub repository. From the main menu choose **Settings** > **Pages**. In the center of your screen you will see this:
+
+
+{style="max-width: 280px"}
+
+Step 4
+: Change the **Source** to `GitHub Actions`. The change is immediate; you do not have to press a Save button.
+
+
+{style="max-width: 280px"}
+
+Step 5
+: Create a file named `hugo.yaml` in a directory named `.github/workflows`.
+
+```text
+mkdir -p .github/workflows
+touch hugo.yaml
+```
+
+Step 6
+: Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed.
+
+{{< code file=.github/workflows/hugo.yaml copy=true >}}
+# Sample workflow for building and deploying a Hugo site to GitHub Pages
+name: Deploy Hugo site to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches:
+ - main
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+# Default to bash
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ env:
+ HUGO_VERSION: 0.141.0
+ steps:
+ - name: Install Hugo CLI
+ run: |
+ wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
+ && sudo dpkg -i ${{ runner.temp }}/hugo.deb
+ - name: Install Dart Sass
+ run: sudo snap install dart-sass
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v5
+ - name: Install Node.js dependencies
+ run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
+ - name: Build with Hugo
+ env:
+ HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache
+ HUGO_ENVIRONMENT: production
+ TZ: America/Los_Angeles
+ run: |
+ hugo \
+ --gc \
+ --minify \
+ --baseURL "${{ steps.pages.outputs.base_url }}/"
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+{{< /code >}}
+
+Step 7
+: Commit and push the change to your GitHub repository.
+
+```sh
+git add -A
+git commit -m "Create hugo.yaml"
+git push
+```
+
+Step 8
+: From GitHub's main menu, choose **Actions**. You will see something like this:
+
+
+{style="max-width: 350px"}
+
+Step 9
+: When GitHub has finished building and deploying your site, the color of the status indicator will change to green.
+
+
+{style="max-width: 350px"}
+
+Step 10
+: Click on the commit message as shown above. You will see this:
+
+
+{style="max-width: 611px"}
+
+Under the deploy step, you will see a link to your live site.
+
+In the future, whenever you push a change from your local repository, GitHub will rebuild your site and deploy the changes.
+
+## Customize the workflow
+
+The example workflow above includes this step, which typically takes 10‑15 seconds:
+
+```yaml
+- name: Install Dart Sass
+ run: sudo snap install dart-sass
+```
+
+You may remove this step if your site, themes, and modules do not transpile Sass to CSS using the [Dart Sass] transpiler.
+
++[Dart Sass]: /functions/css/sass/#dart-sass
+
+## Other resources
+
+- [Learn more about GitHub Actions](https://docs.github.com/en/actions)
+- [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
+- [Manage a custom domain for your GitHub Pages site](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages)
--- /dev/null
--- /dev/null
++---
++title: Host on KeyCDN
++description: "Accelerate your Hugo site globally with a KeyCDN integration. This tutorial shows you how to set up your static site as a GitLab page behind a KeyCDN pull zone."
++categories: [hosting and deployment]
++keywords: [hosting,keycdn]
++menu:
++ docs:
++ parent: hosting-and-deployment
++---
++
++[KeyCDN](https://www.keycdn.com/) provides a multitude of features to help accelerate and secure your Hugo site globally including Brotli compression, Let's Encrypt support, Origin Shield, and more.
++
++## Assumptions
++
++- You already have a Hugo page configured
++- You have a GitLab account
++- You have a KeyCDN account
++
++## Create a KeyCDN Pull Zone
++
++The first step will be to log in to your KeyCDN account and create a new zone. Name this whatever you like and select the [Pull Zone](https://www.keycdn.com/support/create-a-pull-zone/) option. As for the origin URL, your site will be running on [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html) with a URL of `https://youruser.gitlab.io/reponame/`. Use this as the Origin URL.
++
++
++
++While the origin location doesn’t exist yet, you will need to use your new Zone URL address (or [Zone Alias](https://www.keycdn.com/support/create-a-zone-alias/)) in the `.gitlab-ci.yml` file that will be uploaded to your GitLab project.
++
++Ensure that you use your Zone URL or Zone alias as the `BASEURL` variable in the example below. This will be the user-visible website address.
++
++## Configure Your .gitlab-ci.yml File
++
++Your `.gitlab-ci.yml` file should look similar to the example below. Be sure to modify any variables that are specific to your setup.
++
++```yml
++image: alpine:latest
++
++variables:
++ BASEURL: "https://cipull-7bb7.kxcdn.com/"
++ HUGO_VERSION: "0.26"
++ HUGO_CHECKSUM: "67e4ba5ec2a02c8164b6846e30a17cc765b0165a5b183d5e480149baf54e1a50"
++ KEYCDN_ZONE_ID: "75544"
++
++before_script:
++ - apk update
++ - apk add curl
++
++pages:
++ stage: deploy
++ script:
++ - apk add git
++ - git submodule update --init
++ - curl -sSL https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz -o /tmp/hugo.tar.gz
++ - echo "${HUGO_CHECKSUM} /tmp/hugo.tar.gz" | sha256sum -c
++ - tar xf /tmp/hugo.tar.gz hugo -C /tmp/ && cp /tmp/hugo /usr/bin
++ - hugo --baseURL ${BASEURL}
++ - curl "https://api.keycdn.com/zones/purge/${KEYCDN_ZONE_ID}.json" -u "${KEYCDN_API_KEY}:"
++ artifacts:
++ paths:
++ - public
++ only:
++ - master
++```
++
++Using this integration method, you will have to specify the Zone ID and your [KeyCDN API](https://www.keycdn.com/api) key as secret variables. To do this, navigate to the top-left menu bar in GitLab and select Projects. Then, select your project and click on the Settings page. Finally, select Pipelines from the sub-menu and scroll down to the Secret Variable section.
++
++The Secret Variable for your Zone ID should look similar to:
++
++
++
++While the Secret Variable for your API Key will look similar to:
++
++
++
++The Zone ID and API key are used to purge your zone – it’s not strictly needed but otherwise, the CDN might deliver older versions of your assets for quite a while.
++
++## Push your changes to GitLab
++
++Now it's time to push the newly created repository to GitLab:
++
++```sh
++git remote add origin git@gitlab.com:youruser/ci-example.git
++git push -u origin master
++```
++
++You can watch the progress and CI job output in your GitLab project under “Pipelines”.
++
++After verifying your CI job ran without issues, first check that your GitLab page shows up under `https://youruser.gitlab.io/reponame/` (it might look broken depending on your browser settings as all links point to your KeyCDN zone – don’t worry about that) and then by heading to whatever Zone alias / Zone URL you defined.
++
++To learn more about Hugo hosting options with KeyCDN, check out the complete [Hugo hosting with KeyCDN integration guide](https://www.keycdn.com/support/hugo-hosting/).
--- /dev/null
- linkTitle: In this section
- description: How to use Hugo Modules.
+---
+title: Hugo Modules
++
++description: Use Hugo Modules to manage the content, presentation, and behavior of your site.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: hugo-modules-in-this-section
+ parent: modules
+ weight: 10
+weight: 10
+toc: true
+aliases: [/themes/overview/,/themes/]
+---
+
+**Hugo Modules** are the core building blocks in Hugo. A _module_ can be your main project or a smaller module providing one or more of the 7 component types defined in Hugo: **static**, **content**, **layouts**, **data**, **assets**, **i18n**, and **archetypes**.
+
+You can combine modules in any combination you like, and even mount directories from non-Hugo projects, forming a big, virtual union file system.
+
+Hugo Modules are powered by Go Modules. For more information about Go Modules, see:
+
+- [https://go.dev/wiki/Modules](https://go.dev/wiki/Modules)
+- [https://go.dev/blog/using-go-modules](https://go.dev/blog/using-go-modules)
+
+Some example projects:
+
+- [https://github.com/bep/docuapi](https://github.com/bep/docuapi) is a theme that has been ported to Hugo Modules while testing this feature. It is a good example of a non-Hugo-project mounted into Hugo's directory structure. It even shows a JS Bundler implementation in regular Go templates.
+- [https://github.com/bep/my-modular-site](https://github.com/bep/my-modular-site) is a very simple site used for testing.
--- /dev/null
- : (`bool`) Whether the extended version of Hugo is required.
+---
+title: Configure Hugo modules
+description: This page describes the configuration options for a module.
+categories: [hugo modules]
+keywords: [modules,themes]
+menu:
+ docs:
+ parent: modules
+ weight: 20
+weight: 20
+toc: true
+---
+
+## Module configuration: top level
+
+{{< code-toggle file=hugo >}}
+[module]
+noProxy = 'none'
+noVendor = ''
+private = '*.*'
+proxy = 'direct'
+replacements = ''
+vendorClosest = false
+workspace = 'off'
+{{< /code-toggle >}}
+
+noProxy
+: (`string`) Comma separated glob list matching paths that should not use the proxy configured above.
+
+noVendor
+: (`string`) A optional Glob pattern matching module paths to skip when vendoring, e.g. "github.com/**"
+
+private
+: (`string`) Comma separated glob list matching paths that should be treated as private.
+
+proxy
+: (`string`) Defines the proxy server to use to download remote modules. Default is `direct`, which means "git clone" and similar.
+
+vendorClosest
+: (`bool`) When enabled, we will pick the vendored module closest to the module using it. The default behavior is to pick the first. Note that there can still be only one dependency of a given module path, so once it is in use it cannot be redefined. Default is `false`.
+
+workspace
+: (`string`) The workspace file to use. This enables Go workspace mode. Note that this can also be set via OS env, e.g. `export HUGO_MODULE_WORKSPACE=/my/hugo.work` This only works with Go 1.18+. In Hugo `v0.109.0` we changed the default to `off` and we now resolve any relative work file names relative to the working directory.
+
+replacements
+: (`string`) A comma-separated list of mappings from module paths to directories, e.g. `github.com/bep/my-theme -> ../..,github.com/bep/shortcodes -> /some/path`. This is mostly useful for temporary local development of a module, in which case you might want to save it as an environment variable, e.g: `env HUGO_MODULE_REPLACEMENTS="github.com/bep/my-theme -> ../.."`. Relative paths are relative to [themesDir](/getting-started/configuration/#all-configuration-settings). Absolute paths are allowed.
+
+Note that the above terms maps directly to their counterparts in Go Modules. Some of these setting may be natural to set as OS environment variables. To set the proxy server to use, as an example:
+
+```txt
+env HUGO_MODULE_PROXY=https://proxy.example.org hugo
+```
+
+{{< gomodules-info >}}
+
+## Module configuration: hugoVersion
+
+If your module requires a particular version of Hugo to work, you can indicate that in the `module` section and the user will be warned if using a too old/new version.
+
+{{< code-toggle file=hugo >}}
+[module]
+[module.hugoVersion]
+ min = ""
+ max = ""
+ extended = false
+
+{{< /code-toggle >}}
+
+Any of the above can be omitted.
+
+min
+: (`string`) The minimum Hugo version supported, e.g. `0.55.0`
+
+max
+: (`string`) The maximum Hugo version supported, e.g. `0.55.0`
+
+extended
- {{< new-in 0.128.0 >}}
++: (`bool`) Whether the extended edition of Hugo is required, satisfied by installing either the extended or extended/deploy edition.
+
+## Module configuration: imports
+
+{{< code-toggle file=hugo >}}
+[module]
+[[module.imports]]
+ path = "github.com/gohugoio/hugoTestModules1_linux/modh1_2_1v"
+ ignoreConfig = false
+ ignoreImports = false
+ disable = false
+[[module.imports]]
+ path = "my-shortcodes"
+{{< /code-toggle >}}
+
+path
+: Can be either a valid Go Module module path, e.g. `github.com/gohugoio/myShortcodes`, or the directory name for the module as stored in your `themes` directory.
+
+ignoreConfig
+: If enabled, any module configuration file, e.g. `hugo.toml`, will not be loaded. Note that this will also stop the loading of any transitive module dependencies.
+
+ignoreImports
+: If enabled, module imports will not be followed.
+
+disable
+: Set to `true` to disable the module while keeping any version info in the `go.*` files.
+
+noMounts
+: Do not mount any directory in this import.
+
+noVendor
+: Never vendor this import (only allowed in main project).
+
+{{< gomodules-info >}}
+
+## Module configuration: mounts
+
+{{% note %}}
+When the `mounts` configuration was introduced in Hugo 0.56.0, we were careful to preserve the existing `contentDir`, `staticDir`, and similar configuration to make sure all existing sites just continued to work. But you should not have both: if you add a `mounts` section you should remove the old `contentDir`, `staticDir`, etc. settings.
+{{% /note %}}
+
+{{% note %}}
+When you add a mount, the default mount for the concerned target root is ignored: be sure to explicitly add it.
+{{% /note %}}
+
+### Default mounts
+
+{{< code-toggle file=hugo >}}
+[module]
+[[module.mounts]]
+ source="content"
+ target="content"
+[[module.mounts]]
+ source="static"
+ target="static"
+[[module.mounts]]
+ source="layouts"
+ target="layouts"
+[[module.mounts]]
+ source="data"
+ target="data"
+[[module.mounts]]
+ source="assets"
+ target="assets"
+[[module.mounts]]
+ source="i18n"
+ target="i18n"
+[[module.mounts]]
+ source="archetypes"
+ target="archetypes"
+{{< /code-toggle >}}
+
+source
+: (`string`) The source directory of the mount. For the main project, this can be either project-relative or absolute. For other modules it must be project-relative.
+
+target
+: (`string`) Where it should be mounted into Hugo's virtual filesystem. It must start with one of Hugo's component directories: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, or `archetypes`. E.g. `content/blog`.
+
+disableWatch
- : (`string` or `string slice`) One or more [glob](https://github.com/gobwas/glob) patterns matching files or directories to include. If `excludeFiles` is not set, the files matching `includeFiles` will be the files mounted.
++{{< new-in 0.128.0 />}}
+: (`bool`) Whether to disable watching in watch mode for this mount. Default is `false`.
+
+lang
+: (`string`) The language code, e.g. "en". Only relevant for `content` mounts, and `static` mounts when in multihost mode.
+
+includeFiles
- : (`string` or `string slice`) One or more glob patterns matching files to exclude.
++: (`string` or `[]string`) One or more [glob](https://github.com/gobwas/glob) patterns matching files or directories to include. If `excludeFiles` is not set, the files matching `includeFiles` will be the files mounted.
+
+The glob patterns are matched to the file names starting from the `source` root, they should have Unix styled slashes even on Windows, `/` matches the mount root and `**` can be used as a super-asterisk to match recursively down all directories, e.g `/posts/**.jpg`.
+
+The search is case-insensitive.
+
+excludeFiles
++: (`string` or `[]string`) One or more glob patterns matching files to exclude.
+
+### Example
+
+{{< code-toggle file=hugo >}}
+[module]
+[[module.mounts]]
+ source="content"
+ target="content"
+ excludeFiles="docs/*"
+[[module.mounts]]
+ source="node_modules"
+ target="assets"
+[[module.mounts]]
+ source="assets"
+ target="assets"
+{{< /code-toggle >}}
--- /dev/null
- Using the `use` directive, list all the modules you want to work on, pointing to its relative location. As in the example above, it's recommended to always include the main project (the ".") in the list.
+---
+title: Use Hugo Modules
+description: How to use Hugo Modules to build and manage your site.
+categories: [hugo modules]
+keywords: [modules,themes]
+menu:
+ docs:
+ parent: modules
+ weight: 30
+weight: 30
+aliases: [/themes/usage/,/themes/installing/,/installing-and-using-themes/]
+toc: true
+---
+
+## Prerequisite
+
+{{< gomodules-info >}}
+
+## Initialize a new module
+
+Use `hugo mod init` to initialize a new Hugo Module. If it fails to guess the module path, you must provide it as an argument, e.g.:
+
+```sh
+hugo mod init github.com/<your_user>/<your_project>
+```
+
+Also see the [CLI Doc](/commands/hugo_mod_init/).
+
+## Use a module for a theme
+
+The easiest way to use a Module for a theme is to import it in the configuration.
+
+1. Initialize the hugo module system: `hugo mod init github.com/<your_user>/<your_project>`
+1. Import the theme:
+
+{{< code-toggle file=hugo >}}
+[module]
+ [[module.imports]]
+ path = "github.com/spf13/hyde"
+{{< /code-toggle >}}
+
+## Update modules
+
+Modules will be downloaded and added when you add them as imports to your configuration, see [Module Imports](/hugo-modules/configuration/#module-configuration-imports).
+
+To update or manage versions, you can use `hugo mod get`.
+
+Some examples:
+
+### Update all modules
+
+```sh
+hugo mod get -u
+```
+
+### Update all modules recursively
+
+```sh
+hugo mod get -u ./...
+```
+
+### Update one module
+
+```sh
+hugo mod get -u github.com/gohugoio/myShortcodes
+```
+
+### Get a specific version
+
+```sh
+hugo mod get github.com/gohugoio/myShortcodes@v1.0.7
+```
+
+Also see the [CLI Doc](/commands/hugo_mod_get/).
+
+## Make and test changes in a module
+
+One way to do local development of a module imported in a project is to add a replace directive to a local directory with the source in `go.mod`:
+
+```sh
+replace github.com/bep/hugotestmods/mypartials => /Users/bep/hugotestmods/mypartials
+```
+
+If you have the `hugo server` running, the configuration will be reloaded and `/Users/bep/hugotestmods/mypartials` put on the watch list.
+
+Instead of modifying the `go.mod` files, you can also use the modules configuration [`replacements`](/hugo-modules/configuration/#module-configuration-top-level) option.
+
+## Print dependency graph
+
+Use `hugo mod graph` from the relevant module directory and it will print the dependency graph, including vendoring, module replacement or disabled status.
+
+E.g.:
+
+```txt
+hugo mod graph
+
+github.com/bep/my-modular-site github.com/bep/hugotestmods/mymounts@v1.2.0
+github.com/bep/my-modular-site github.com/bep/hugotestmods/mypartials@v1.0.7
+github.com/bep/hugotestmods/mypartials@v1.0.7 github.com/bep/hugotestmods/myassets@v1.0.4
+github.com/bep/hugotestmods/mypartials@v1.0.7 github.com/bep/hugotestmods/myv2@v1.0.0
+DISABLED github.com/bep/my-modular-site github.com/spf13/hyde@v0.0.0-20190427180251-e36f5799b396
+github.com/bep/my-modular-site github.com/bep/hugo-fresh@v1.0.1
+github.com/bep/my-modular-site in-themesdir
+```
+
+Also see the [CLI Doc](/commands/hugo_mod_graph/).
+
+## Vendor your modules
+
+`hugo mod vendor` will write all the module dependencies to a `_vendor` directory, which will then be used for all subsequent builds.
+
+Note that:
+
+* You can run `hugo mod vendor` on any level in the module tree.
+* Vendoring will not store modules stored in your `themes` directory.
+* Most commands accept a `--ignoreVendorPaths` flag, which will then not use the vendored modules in `_vendor` for the module paths matching the [Glob](https://github.com/gobwas/glob) pattern given.
+
+Also see the [CLI Doc](/commands/hugo_mod_vendor/).
+
+## Tidy go.mod, go.sum
+
+Run `hugo mod tidy` to remove unused entries in `go.mod` and `go.sum`.
+
+Also see the [CLI Doc](/commands/hugo_mod_clean/).
+
+## Clean module cache
+
+Run `hugo mod clean` to delete the entire modules cache.
+
+Note that you can also configure the `modules` cache with a `maxAge`, see [File Caches](/getting-started/configuration/#configure-file-caches).
+
+Also see the [CLI Doc](/commands/hugo_mod_clean/).
+
+## Module workspaces
+
+Workspace support was added in [Go 1.18](https://go.dev/blog/get-familiar-with-workspaces) and Hugo got solid support for it in the `v0.109.0` version.
+
+A common use case for a workspace is to simplify local development of a site with its theme modules.
+
+A workspace can be configured in a `*.work` file and activated with the [module.workspace](/hugo-modules/configuration/) setting, which for this use is commonly controlled via the `HUGO_MODULE_WORKSPACE` OS environment variable.
+
+See the [hugo.work](https://github.com/gohugoio/hugo/blob/master/docs/hugo.work) file in the Hugo Docs repo for an example:
+
+```text
+go 1.20
+
+use .
+use ../gohugoioTheme
+```
+
++Using the `use` directive, list all the modules you want to work on, pointing to its relative location. As in the example above, it's recommended to always include the main project (the `.`) in the list.
+
+With that you can start the Hugo server with that workspace enabled:
+
+```sh
+HUGO_MODULE_WORKSPACE=hugo.work hugo server --ignoreVendorPaths "**"
+```
+
+The `--ignoreVendorPaths` flag is added above to ignore any of the vendored dependencies inside `_vendor`. If you don't use vendoring, you don't need that flag. But now the server is set up watching the files and directories in the workspace and you can see your local edits reloaded.
--- /dev/null
- linkTitle: In this section
+---
+title: Hugo Pipes
++description: Use asset pipelines to transform and optimize images, stylesheets, and JavaScript.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: hugo-pipes-in-this-section
+ parent: hugo-pipes
+ weight: 10
+weight: 10
+---
--- /dev/null
- action:
- aliases: []
- returnType: resource.Resource
- signatures: ['resources.Concat TARGETPATH [RESOURCE...]']
+---
+title: Concat
+linkTitle: Concatenating assets
+description: Bundle any number of assets into one resource.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 90
+weight: 90
- ## Usage
-
- Asset files of the same MIME type can be bundled into one resource using `resources.Concat` which takes two arguments, the target path for the created resource bundle and a slice of resource objects to be concatenated.
-
- ```go-html-template
- {{ $plugins := resources.Get "js/plugins.js" }}
- {{ $global := resources.Get "js/global.js" }}
- {{ $js := slice $plugins $global | resources.Concat "js/bundle.js" }}
- ```
+---
+
++See the [`resources.Concat`](/functions/resources/concat/) function.
--- /dev/null
- description: Process a given resource, adding a hash string of the resource's content.
+---
+title: Fingerprint
+linkTitle: Fingerprinting and SRI hashing
- action:
- aliases: [fingerprint]
- returnType: resource.Resource
- signatures: ['resources.Fingerprint [ALGORITHM] RESOURCE']
++description: Cryptographically hash the content of the given resource.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 100
+weight: 100
- ## Usage
-
- Fingerprinting and [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can be applied to any asset file using `resources.Fingerprint` which takes two arguments, the resource object and an optional [hash algorithm](https://en.wikipedia.org/wiki/Secure_Hash_Algorithms).
-
- The default hash algorithm is `sha256`. Other available algorithms are `sha384` and (as of Hugo `0.55`) `sha512` and `md5`.
-
- Any so processed asset will bear a `.Data.Integrity` property containing an integrity string, which is made up of the name of the hash algorithm, one hyphen and the base64-encoded hash sum.
-
- ```go-html-template
- {{ $js := resources.Get "js/global.js" }}
- {{ $secureJS := $js | resources.Fingerprint "sha512" }}
- <script src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>
- ```
+---
+
++See the [`resources.Fingerprint`](/functions/resources/fingerprint/) function.
--- /dev/null
- description: Minifies a given resource.
+---
+title: Minify
+linkTitle: Asset minification
- action:
- aliases: [minify]
- returnType: resource.Resource
- signatures: [resources.Minify RESOURCE]
++description: Minify a given resource.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 80
+weight: 80
- ## Usage
-
- Any CSS, JS, JSON, HTML, SVG, or XML resource can be minified using `resources.Minify` which takes for argument the resource object.
-
- ```go-html-template
- {{ $css := resources.Get "css/main.css" }}
- {{ $style := $css | resources.Minify }}
- ```
-
- Note that you can also minify the final HTML output to `/public` by running `hugo --minify`.
+---
+
++See the [`resources.Minify`](/functions/resources/minify/) function.
--- /dev/null
- description: Process CSS files with PostCSS, using any of the available plugins.
+---
+title: PostCSS
- toc: true
- action:
- aliases: [postCSS]
- returnType: resource.Resource
- signatures: ['css.PostCSS [OPTIONS] RESOURCE']
++description: Process the given resource with PostCSS using any PostCSS plugin.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 40
+weight: 40
- ## Setup
-
- Follow the steps below to transform CSS using any of the [available PostCSS plugins](https://www.postcss.parts/).
-
- Step 1
- : Install [Node.js](https://nodejs.org/en/download).
-
- Step 2
- : Install the required Node.js packages in the root of your project. For example, to add vendor prefixes to CSS rules:
-
- ```sh
- npm i -D postcss postcss-cli autoprefixer
- ```
-
- Step 3
- : Create a PostCSS configuration file in the root of your project. You must name this file `postcss.config.js` or one of the other [supported file names]. For example:
-
- [supported file names]: https://github.com/postcss/postcss-load-config#usage
-
- {{< code file=postcss.config.js >}}
- module.exports = {
- plugins: [
- require('autoprefixer')
- ]
- };
- {{< /code >}}
-
- {{% note %}}
- If you are a Windows user, and the path to your project contains a space, you must place the PostCSS configuration within the package.json file. See [this example](https://github.com/postcss/postcss-load-config#packagejson) and issue [#7333](https://github.com/gohugoio/hugo/issues/7333).
- {{% /note %}}
-
- Step 4
- : Place your CSS file within the `assets` directory.
-
- Step 5
- : Capture the CSS file as a resource and pipe it through `css.PostCSS` (alias `postCSS`):
-
- {{< code file=layouts/partials/css.html >}}
- {{ with resources.Get "css/main.css" | postCSS }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{< /code >}}
-
- If starting with a Sass file within the `assets` directory:
-
- {{< code file=layouts/partials/css.html >}}
- {{ with resources.Get "sass/main.scss" | toCSS | postCSS }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{< /code >}}
-
- ## Options
-
- The `css.PostCSS` method takes an optional map of options.
-
- config
- : (`string`) The directory that contains the PostCSS configuration file. Default is the root of the project directory.
-
- noMap
- : (`bool`) Default is `false`. If `true`, disables inline sourcemaps.
-
- inlineImports
- : (`bool`) Default is `false`. Enable inlining of @import statements. It does so recursively, but will only import a file once.
- URL imports (e.g. `@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');`) and imports with media queries will be ignored.
- Note that this import routine does not care about the CSS spec, so you can have @import anywhere in the file.
- Hugo will look for imports relative to the module mount and will respect theme overrides.
-
- skipInlineImportsNotFound
- : (`bool`) Default is `false`. If you have regular CSS imports in your CSS that you want to preserve, you can either use imports with URL or media queries (Hugo does not try to resolve those) or set `skipInlineImportsNotFound` to true.
-
- {{< code file=layouts/partials/css.html >}}
- {{ $opts := dict "config" "config-directory" "noMap" true }}
- {{ with resources.Get "css/main.css" | postCSS $opts }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{< /code >}}
-
- ## No configuration file
-
- To avoid using a PostCSS configuration file, you can specify a minimal configuration using the options map.
-
- use
- : (`string`) A space-delimited list of PostCSS plugins to use.
-
- parser
- : (`string`) A custom PostCSS parser.
-
- stringifier
- : (`string`) A custom PostCSS stringifier.
-
- syntax
- : (`string`) Custom postcss syntax.
-
- {{< code file=layouts/partials/css.html >}}
- {{ $opts := dict "use" "autoprefixer postcss-color-alpha" }}
- {{ with resources.Get "css/main.css" | postCSS $opts }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{< /code >}}
-
- ## Check Hugo environment
-
- The current Hugo environment name (set by `--environment` or in configuration or OS environment) is available in the Node context, which allows constructs like this:
-
- {{< code file=postcss.config.js >}}
- module.exports = {
- plugins: [
- require('autoprefixer'),
- ...process.env.HUGO_ENVIRONMENT === 'production'
- ? [purgecss]
- : []
- ]
- }
- {{< /code >}}
+---
+
++See the [`css.PostCSS`](/functions/css/postcss/) function.
--- /dev/null
- description: Allows delaying of resource transformations to after the build.
+---
+title: PostProcess
- action:
- aliases: []
- returnType: postpub.PostPublishedResource
- signatures: [resources.PostProcess RESOURCE]
++description: Process the given resource after the build.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 50
+weight: 50
- ## Usage
-
- Marking a resource with `resources.PostProcess` delays any transformations to after the build, typically because one or more of the steps in the transformation chain depends on the result of the build (e.g. files in `public`).
-
- A prime use case for this is [CSS purging with PostCSS](#css-purging-with-postcss).
-
- There are currently two limitations to this:
-
- 1. This only works in `*.html` templates (i.e. templates that produces HTML files).
- 1. You cannot manipulate the values returned from the resource's methods. E.g. the `upper` in this example will not work as expected:
-
- ```go-html-template
- {{ $css := resources.Get "css/main.css" }}
- {{ $css = $css | css.PostCSS | minify | fingerprint | resources.PostProcess }}
- {{ $css.RelPermalink | upper }}
- ```
-
- ## CSS purging with PostCSS
-
- {{% note %}}
- There are several ways to set up CSS purging with PostCSS in Hugo. If you have a simple project, you should consider going the simpler route and drop the use of `resources.PostProcess` and just extract keywords from the templates. See the [Tailwind documentation](https://tailwindcss.com/docs/controlling-file-size/#app) for some examples.
- {{% /note %}}
-
- The below configuration will write a `hugo_stats.json` file to the project root as part of the build. If you're only using this for the production build, you should consider placing it below [`config/production`](/getting-started/configuration/#configuration-directory).
-
- {{< code-toggle file=hugo >}}
- [build.buildStats]
- enable = true
- {{< /code-toggle >}}
-
- See the [configure build] documentation for details and options.
-
- [configure build]: /getting-started/configuration/#configure-build
-
- `postcss.config.js`
-
- ```js
- const purgecss = require('@fullhuman/postcss-purgecss')({
- content: [ './hugo_stats.json' ],
- defaultExtractor: (content) => {
- let els = JSON.parse(content).htmlElements;
- return els.tags.concat(els.classes, els.ids);
- }
- });
-
- module.exports = {
- plugins: [
- ...(process.env.HUGO_ENVIRONMENT === 'production' ? [ purgecss ] : [])
- ]
- };
- ```
-
- Note that in the example above, the "CSS purge step" will only be applied to the production build. This means that you need to do something like this in your head template to build and include your CSS:
-
- ```go-html-template
- {{ $css := resources.Get "css/main.css" }}
- {{ $css = $css | css.PostCSS }}
- {{ if hugo.IsProduction }}
- {{ $css = $css | minify | fingerprint | resources.PostProcess }}
- {{ end }}
- <link href="{{ $css.RelPermalink }}" rel="stylesheet" />
- ```
-
- ## Hugo environment variables available in PostCSS
-
- These are the environment variables Hugo passes down to PostCSS (and Babel), which allows you do do `process.env.HUGO_ENVIRONMENT === 'production' ? [autoprefixer] : []` and similar:
-
- PWD
- : The absolute path to the project working directory.
-
- HUGO_ENVIRONMENT
- : The value e.g. set with `hugo -e production` (defaults to `production` for `hugo` and `development` for `hugo server`).
-
- HUGO_PUBLISHDIR
- : The absolute path to the publish directory (the `public` directory). Note that the value will always point to a directory on disk even when running `hugo server` in memory mode. If you write to this directory from PostCSS when running the server, you could run the server with one of these flags:
-
- ```sh
- hugo server --renderToDisk
- hugo server --renderStaticToDisk
- ```
-
- Also, Hugo will add environment variables for all files mounted below `assets/_jsconfig`. A default mount will be set up with files in the project root matching this regexp: `(babel|postcss|tailwind)\.config\.js`.
-
- These will get environment variables named on the form `HUGO_FILE_:filename:` where `:filename:` is all upper case with periods replaced with underscore. This allows you to do this and similar:
-
- ```js
- let tailwindConfig = process.env.HUGO_FILE_TAILWIND_CONFIG_JS || './tailwind.config.js';
- ```
+---
+
++See the [`resources.PostProcess`](/functions/resources/postprocess/) function.
--- /dev/null
- description: Creates a resource from a string.
+---
+title: FromString
+linkTitle: Resource from string
- action:
- aliases: []
- returnType: resource.Resource
- signatures: [resources.FromString TARGETPATH STRING]
++description: Create a resource from a string.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 110
+weight: 110
- ## Usage
-
- It is possible to create a resource directly from the template using `resources.FromString` which takes two arguments, the target path for the created resource and the given content string.
-
- The result is cached using the target path as the cache key.
-
- The following example creates a resource file containing localized variables for every project's languages.
-
- ```go-html-template
- {{ $string := (printf "var rootURL = '%s'; var apiURL = '%s';" (absURL "/") (.Param "API_URL")) }}
- {{ $targetPath := "js/vars.js" }}
- {{ $vars := $string | resources.FromString $targetPath }}
- {{ $global := resources.Get "js/global.js" | resources.Minify }}
-
- <script src="{{ $vars.Permalink }}"></script>
- <script src="{{ $global.Permalink }}"></script>
- ```
+---
+
++See the [`resources.FromString`](/functions/resources/fromstring/) function.
--- /dev/null
- description: Creates a resource from a template
+---
+title: ExecuteAsTemplate
+linkTitle: Resource from template
- action:
- aliases: []
- returnType: resource.Resource
- signatures: [resources.ExecuteAsTemplate TARGETPATH CONTEXT RESOURCE]
++description: Create a resource from a Go template, parsed and executed with the given context.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
+ weight: 120
+weight: 120
- ## Usage
-
- In order to use Hugo Pipes function on an asset file containing Go Template magic the function `resources.ExecuteAsTemplate` must be used.
-
- The function takes three arguments: the target path for the created resource, the template context, and the resource object. The target path is used to cache the result.
-
- ```go-html-template
- // assets/sass/template.scss
- $backgroundColor: {{ .Param "backgroundColor" }};
- $textColor: {{ .Param "textColor" }};
- body{
- background-color:$backgroundColor;
- color: $textColor;
- }
- // [...]
- ```
-
- ```go-html-template
- {{ $sassTemplate := resources.Get "sass/template.scss" }}
- {{ $style := $sassTemplate | resources.ExecuteAsTemplate "main.scss" . | css.Sass }}
- ```
+---
+
++See the [`resources.ExecuteAsTemplate`](/functions/resources/executeastemplate/) function.
--- /dev/null
- returnType: resource.Resource
+---
+title: ToCSS
+linkTitle: Transpile Sass to CSS
+description: Transpile Sass to CSS.
+categories: [asset management]
+keywords: []
+menu:
+ docs:
+ parent: hugo-pipes
- action:
- aliases: [toCSS]
- returnType: resource.Resource
- signatures: ['css.Sass [OPTIONS] RESOURCE']
- toc: true
+ weight: 30
+weight: 30
- ## Usage
-
- Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language.
-
- ```go-html-template
- {{ $opts := dict "transpiler" "libsass" "targetPath" "css/style.css" }}
- {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- ```
-
- Sass has two forms of syntax: [SCSS] and [indented]. Hugo supports both.
-
- [scss]: https://sass-lang.com/documentation/syntax#scss
- [indented]: https://sass-lang.com/documentation/syntax#the-indented-syntax
-
- ## Options
-
- transpiler
- : (`string`) The transpiler to use, either `libsass` (default) or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass) below.
-
- targetPath
- : (`string`) If not set, the transformed resource's target path will be the original path of the asset file with its extension replaced by `.css`.
-
- vars
- : (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
-
- ```scss
- // LibSass
- @import "hugo:vars";
-
- // Dart Sass
- @use "hugo:vars" as v;
- ```
-
- outputStyle
- : (`string`) Output styles available to LibSass include `nested` (default), `expanded`, `compact`, and `compressed`. Output styles available to Dart Sass include `expanded` (default) and `compressed`.
-
- precision
- : (`int`) Precision of floating point math. Not applicable to Dart Sass.
-
- enableSourceMap
- : (`bool`) If `true`, generates a source map.
-
- sourceMapIncludeSources
- : (`bool`) If `true`, embeds sources in the generated source map. Not applicable to LibSass.
-
- includePaths
- : (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
-
- ```go-html-template
- {{ $opts := dict
- "transpiler" "dartsass"
- "targetPath" "css/style.css"
- "vars" site.Params.styles
- "enableSourceMap" (not hugo.IsProduction)
- "includePaths" (slice "node_modules/bootstrap/scss")
- }}
- {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- ```
-
- ## Dart Sass
-
- The extended version of Hugo includes [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass].
-
- Use the latest features of the Sass language by installing Dart Sass in your development and production environments.
-
- ### Installation overview
-
- Dart Sass is compatible with Hugo v0.114.0 and later.
-
- If you have been using Embedded Dart Sass[^1] with Hugo v0.113.0 and earlier, uninstall Embedded Dart Sass, then install Dart Sass. If you have installed both, Hugo will use Dart Sass.
-
- If you install Hugo as a [Snap package] there is no need to install Dart Sass. The Hugo Snap package includes Dart Sass.
-
- [^1]: In 2023, the Sass team deprecated Embedded Dart Sass in favor of Dart Sass.
-
- ### Installing in a development environment
-
- When you install Dart Sass somewhere in your PATH, Hugo will find it.
-
- OS|Package manager|Site|Installation
- :--|:--|:--|:--
- Linux|Homebrew|[brew.sh]|`brew install sass/sass/sass`
- Linux|Snap|[snapcraft.io]|`sudo snap install dart-sass`
- macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass`
- Windows|Chocolatey|[chocolatey.org]|`choco install sass`
- Windows|Scoop|[scoop.sh]|`scoop install sass`
-
- You may also install [prebuilt binaries] for Linux, macOS, and Windows.
-
- Run `hugo env` to list the active transpilers.
-
- ### Installing in a production environment
-
- For [CI/CD] deployments (e.g., GitHub Pages, GitLab Pages, Netlify, etc.) you must edit the workflow to install Dart Sass before Hugo builds the site[^2]. Some providers allow you to use one of the package managers above, or you can download and extract one of the prebuilt binaries.
-
- [^2]: You do not have to do this if (a) you have not modified the assets cache location, and (b) you have not set `useResourceCacheWhen` to `never` in your [site configuration], and (c) you add and commit your `resources` directory to your repository.
-
- #### GitHub Pages
-
- To install Dart Sass for your builds on GitHub Pages, add this step to the GitHub Pages workflow file:
-
- ```yaml
- - name: Install Dart Sass
- run: sudo snap install dart-sass
- ```
-
- If you are using GitHub Pages for the first time with your repository, GitHub provides a [starter workflow] for Hugo that includes Dart Sass. This is the simplest way to get started.
-
- #### GitLab Pages
-
- To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file should look something like this:
-
- ```yaml
- variables:
- HUGO_VERSION: 0.141.0
- DART_SASS_VERSION: 1.83.4
- GIT_DEPTH: 0
- GIT_STRATEGY: clone
- GIT_SUBMODULE_STRATEGY: recursive
- TZ: America/Los_Angeles
- image:
- name: golang:1.20-buster
- pages:
- script:
- # Install Dart Sass
- - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
- - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
- - cp -r dart-sass/* /usr/local/bin
- - rm -rf dart-sass*
- # Install Hugo
- - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- - apt install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
- # Build
- - hugo --gc --minify
- artifacts:
- paths:
- - public
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- ```
-
- #### Netlify
-
- To install Dart Sass for your builds on Netlify, the `netlify.toml` file should look something like this:
-
- ```toml
- [build.environment]
- HUGO_VERSION = "0.141.0"
- DART_SASS_VERSION = "1.83.4"
- NODE_VERSION = "22"
- TZ = "America/Los_Angeles"
-
- [build]
- publish = "public"
- command = """\
- curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
- export PATH=/opt/build/repo/dart-sass:$PATH && \
- hugo --gc --minify \
- """
- ```
-
- ### Example
-
- To transpile with Dart Sass, set `transpiler` to `dartsass` in the options map passed to `css.Sass`. For example:
-
- ```go-html-template
- {{ $opts := dict "transpiler" "dartsass" "targetPath" "css/style.css" }}
- {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- ```
-
- ### Miscellaneous
-
- If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model.
-
- [brew.sh]: https://brew.sh/
- [chocolatey.org]: https://community.chocolatey.org/packages/sass
- [ci/cd]: https://en.wikipedia.org/wiki/CI/CD
- [dart sass]: https://sass-lang.com/dart-sass
- [libsass]: https://sass-lang.com/libsass
- [prebuilt binaries]: https://github.com/sass/dart-sass/releases/latest
- [scoop.sh]: https://scoop.sh/#/apps?q=sass
- [site configuration]: /getting-started/configuration/#configure-build
- [snap package]: /installation/linux/#snap
- [snapcraft.io]: https://snapcraft.io/dart-sass
- [starter workflow]: https://github.com/actions/starter-workflows/blob/main/pages/hugo.yml
+aliases: [/hugo-pipes/transform-to-css/]
+---
+
++See the [`css.Sass`](/functions/css/sass) function.
--- /dev/null
- Deploy your site directly to a Google Cloud Storage bucket, an AWS S3 bucket, or an Azure Storage container. See [details].|:x:|:heavy_check_mark:
+---
+_comment: Do not remove front matter.
+---
+
+Hugo is available in three editions: standard, extended, and extended/deploy. While the standard edition provides core functionality, the extended and extended/deploy editions offer advanced features.
+
+Feature|extended edition|extended/deploy edition
+:--|:-:|:-:
+Encode to the WebP format when [processing images]. You can decode WebP images with any edition.|:heavy_check_mark:|:heavy_check_mark:
+[Transpile Sass to CSS] using the embedded LibSass transpiler. You can use the [Dart Sass] transpiler with any edition.|:heavy_check_mark:|:heavy_check_mark:
- [dart sass]: /hugo-pipes/transpile-sass-to-css/#dart-sass
++Deploy your site directly to a Google Cloud Storage bucket, an AWS S3 bucket, or an Azure Storage container. See [details].|:x:|:heavy_check_mark:
+
- [transpile sass to css]: /hugo-pipes/transpile-sass-to-css/
++[dart sass]: /functions/css/sass/#dart-sass
+[processing images]: /content-management/image-processing/
++[transpile sass to css]: /functions/css/sass/
+[details]: /hosting-and-deployment/hugo-deploy/
--- /dev/null
- [dart sass install]: /hugo-pipes/transpile-sass-to-css/#dart-sass
+---
+_comment: Do not remove front matter.
+---
+
+## Prerequisites
+
+Although not required in all cases, [Git], [Go], and [Dart Sass] are commonly used when working with Hugo.
+
+Git is required to:
+
+- Build Hugo from source
+- Use the [Hugo Modules] feature
+- Install a theme as a Git submodule
+- Access [commit information] from a local Git repository
+- Host your site with services such as [CloudCannon], [Cloudflare Pages], [GitHub Pages], [GitLab Pages], and [Netlify]
+
+Go is required to:
+
+- Build Hugo from source
+- Use the Hugo Modules feature
+
+Dart Sass is required to transpile Sass to CSS when using the latest features of the Sass language.
+
+Please refer to the relevant documentation for installation instructions:
+
+- [Git][git install]
+- [Go][go install]
+- [Dart Sass][dart sass install]
+
+[cloudcannon]: https://cloudcannon.com/
+[cloudflare pages]: https://pages.cloudflare.com/
++[dart sass install]: /functions/css/sass/#dart-sass
+[dart sass]: https://sass-lang.com/dart-sass
+[git install]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+[git]: https://git-scm.com/
+[github pages]: https://pages.github.com/
+[gitlab pages]: https://docs.gitlab.com/ee/user/project/pages/
+[go install]: https://go.dev/doc/install
+[go]: https://go.dev/
+[netlify]: https://www.netlify.com/
--- /dev/null
- linkTitle: In this section
+---
+title: Installation
++
+description: Install Hugo on macOS, Linux, Windows, BSD, and on any machine that can run the Go compiler tool chain.
+aliases: [/getting-started/installing/]
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: installation-in-this-section
+ parent: installation
+ weight: 10
+weight: 10
+---
+
+Install Hugo on macOS, Linux, Windows, BSD, and on any machine that can run the Go compiler tool chain.
--- /dev/null
+---
+title: Windows
+description: Install Hugo on Windows.
+categories: [installation]
+keywords: []
+menu:
+ docs:
+ parent: installation
+ weight: 40
+weight: 40
+toc: true
+---
+
+{{% note %}}
+Hugo v0.121.1 and later require at least Windows 10 or Windows Server 2016.
+{{% /note %}}
+
+## Editions
+
+{{% include "installation/_common/01-editions.md" %}}
+
+Unless your specific deployment needs require the extended/deploy edition, we recommend the extended edition.
+
+{{% include "installation/_common/02-prerequisites.md" %}}
+
+{{% include "installation/_common/03-prebuilt-binaries.md" %}}
+
+## Package managers
+
+### Chocolatey
+
+[Chocolatey] is a free and open-source package manager for Windows. To install the extended edition of Hugo:
+
+```sh
+choco install hugo-extended
+```
+
+[Chocolatey]: https://chocolatey.org/
+
+### Scoop
+
+[Scoop] is a free and open-source package manager for Windows. To install the extended edition of Hugo:
+
+```sh
+scoop install hugo-extended
+```
+
+[Scoop]: https://scoop.sh/
+
+### Winget
+
+[Winget] is Microsoft's official free and open-source package manager for Windows. To install the extended edition of Hugo:
+
+```sh
+winget install Hugo.Hugo.Extended
+```
+
++To uninstall the extended edition of Hugo:
++
++```sh
++winget uninstall --name "Hugo (Extended)"
++```
++
+[Winget]: https://learn.microsoft.com/en-us/windows/package-manager/
+
+{{% include "installation/_common/04-build-from-source.md" %}}
+
+{{% note %}}
+See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows.
+{{% /note %}}
+
+## Comparison
+
+||Prebuilt binaries|Package managers|Build from source
+:--|:--:|:--:|:--:
+Easy to install?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
+Easy to upgrade?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
+Easy to downgrade?|:heavy_check_mark:|:heavy_check_mark: [^2]|:heavy_check_mark:
+Automatic updates?|:x:|:x: [^1]|:x:
+Latest version available?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
+
+[^1]: Possible but requires advanced configuration.
+[^2]: Easy if a previous version is still installed.
--- /dev/null
- linkTitle: In this section
- description: A list of Hugo template methods including examples.
+---
+title: Methods
++
++description: Use these methods within your templates.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: methods-in-this-section
+ parent: methods
+ weight: 10
+weight: 10
+showSectionMenu: true
+aliases: ['/variables/']
+---
+
+Use these methods within your templates.
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: Ancestors
+description: Returns a collection of Page objects, one for each ancestor section of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: page.Pages
+ signatures: [PAGE.Ancestors]
+---
+
++{{% glossary-term section %}}
+
+With this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md <-- front matter: weight = 202311
+│ │ ├── auction-1.md
+│ │ └── auction-2.md
+│ ├── 2023-12/
+│ │ ├── _index.md <-- front matter: weight = 202312
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md <-- front matter: weight = 30
+│ ├── bidding.md
+│ └── payment.md
+├── books/
+│ ├── _index.md <-- front matter: weight = 10
+│ ├── book-1.md
+│ └── book-2.md
+├── films/
+│ ├── _index.md <-- front matter: weight = 20
+│ ├── film-1.md
+│ └── film-2.md
+└── _index.md
+```
+
+And this template:
+
+```go-html-template
+{{ range .Ancestors }}
+ <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+{{ end }}
+```
+
+On the November 2023 auctions page, Hugo renders:
+
+```html
+<a href="/auctions/2023-11/">Auctions in November 2023</a>
+<a href="/auctions/">Auctions</a>
+<a href="/">Home</a>
+```
+
+In the example above, notice that Hugo orders the ancestors from closest to furthest. This makes breadcrumb navigation simple:
+
+```go-html-template
+<nav aria-label="breadcrumb" class="breadcrumb">
+ <ol>
+ {{ range .Ancestors.Reverse }}
+ <li>
+ <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+ </li>
+ {{ end }}
+ <li class="active">
+ <a aria-current="page" href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+ </li>
+ </ol>
+</nav>
+```
+
+With some CSS, the code above renders something like this, where each breadcrumb links to its page:
+
+```text
+Home > Auctions > Auctions in November 2023 > Auction 1
+```
--- /dev/null
- {{< new-in 0.134.0 >}}
+---
+title: ContentWithoutSummary
+description: Returns the rendered content of the given page, excluding the content summary.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Content
+ - methods/page/Summary
+ - methods/page/RawContent
+ - methods/page/Plain
+ - methods/page/PlainWords
+ - methods/page/RenderShortcodes
+ returnType: template.HTML
+ signatures: [PAGE.ContentWithoutSummary]
+---
+
++{{< new-in 0.134.0 />}}
+
+Applicable when using manual or automatic [content summaries], the `ContentWithoutSummary` method on a `Page` object renders Markdown and shortcodes to HTML, excluding the content summary from the result.
+
+[content summaries]: /content-management/summaries/#manual-summary
+
+```go-html-template
+{{ .ContentWithoutSummary }}
+```
+
+The `ContentWithoutSummary` method returns the same as `Content` if you define the content summary in front matter.
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: CurrentSection
+description: Returns the Page object of the section in which the given page resides.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: page.Page
+ signatures: [PAGE.CurrentSection]
+---
+
++{{% glossary-term section %}}
+
+{{% note %}}
+The current section of a [section page](g), [taxonomy page](g), [term page](g), or the home page, is itself.
+{{% /note %}}
+
+Consider this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md <-- current section: 2023-11
+│ │ ├── auction-1.md
+│ │ └── auction-2.md <-- current section: 2023-11
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md <-- current section: auctions
+│ ├── bidding.md
+│ └── payment.md <-- current section: auctions
+├── books/
+│ ├── _index.md <-- current section: books
+│ ├── book-1.md
+│ └── book-2.md <-- current section: books
+├── films/
+│ ├── _index.md <-- current section: films
+│ ├── film-1.md
+│ └── film-2.md <-- current section: films
+└── _index.md <-- current section: home
+```
+
+To create a link to the current section page:
+
+```go-html-template
+<a href="{{ .CurrentSection.RelPermalink }}">{{ .CurrentSection.LinkTitle }}</a>
+```
--- /dev/null
- To back one of the pages above with a file, create an `_index.md` file in the corresponding directory. For example:
+---
+title: File
+description: For pages backed by a file, returns file information for the given page.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: hugolib.fileInfo
+ signatures: [PAGE.File]
+toc: true
+---
+
+By default, not all pages are backed by a file, including top level [section pages](g), [taxonomy pages](g), and [term pages](g). By definition, you cannot retrieve file information when the file does not exist.
+
- {{< new-in 0.126.0 >}}
++To back one of the pages above with a file, create an `_index.md` file in the corresponding directory. For example:
+
+```text
+content/
+└── books/
+ ├── _index.md <-- the top level section page
+ ├── book-1.md
+ └── book-2.md
+```
+
+{{% note %}}
+Code defensively by verifying file existence as shown in the examples below.
+{{% /note %}}
+
+## Methods
+
+{{% note %}}
+The path separators (slash or backslash) in `Path`, `Dir`, and `Filename` depend on the operating system.
+{{% /note %}}
+
+###### BaseFileName
+
+(`string`) The file name, excluding the extension.
+
+```go-html-template
+{{ with .File }}
+ {{ .BaseFileName }}
+{{ end }}
+```
+
+###### ContentBaseName
+
+(`string`) If the page is a branch or leaf bundle, the name of the containing directory, else the `TranslationBaseName`.
+
+```go-html-template
+{{ with .File }}
+ {{ .ContentBaseName }}
+{{ end }}
+```
+
+###### Dir
+
+(`string`) The file path, excluding the file name, relative to the `content` directory.
+
+```go-html-template
+{{ with .File }}
+ {{ .Dir }}
+{{ end }}
+```
+
+###### Ext
+
+(`string`) The file extension.
+
+```go-html-template
+{{ with .File }}
+ {{ .Ext }}
+{{ end }}
+```
+
+###### Filename
+
+(`string`) The absolute file path.
+
+```go-html-template
+{{ with .File }}
+ {{ .Filename }}
+{{ end }}
+```
+
+###### IsContentAdapter
+
++{{< new-in 0.126.0 />}}
+
+(`bool`) Reports whether the file is a [content adapter].
+
+[content adapter]: /content-management/content-adapters/
+
+```go-html-template
+{{ with .File }}
+ {{ .IsContentAdapter }}
+{{ end }}
+```
+
+###### LogicalName
+
+(`string`) The file name.
+
+```go-html-template
+{{ with .File }}
+ {{ .LogicalName }}
+{{ end }}
+```
+
+###### Path
+
+(`string`) The file path, relative to the `content` directory.
+
+```go-html-template
+{{ with .File }}
+ {{ .Path }}
+{{ end }}
+```
+
+###### Section
+
+(`string`) The name of the top level section in which the file resides.
+
+```go-html-template
+{{ with .File }}
+ {{ .Section }}
+{{ end }}
+```
+
+###### TranslationBaseName
+
+(`string`) The file name, excluding the extension and language identifier.
+
+```go-html-template
+{{ with .File }}
+ {{ .TranslationBaseName }}
+{{ end }}
+```
+
+###### UniqueID
+
+(`string`) The MD5 hash of `.File.Path`.
+
+```go-html-template
+{{ with .File }}
+ {{ .UniqueID }}
+{{ end }}
+```
+
+## Examples
+
+Consider this content structure in a multilingual project:
+
+```text
+content/
+├── news/
+│ ├── b/
+│ │ ├── index.de.md <-- leaf bundle
+│ │ └── index.en.md <-- leaf bundle
+│ ├── a.de.md <-- regular content
+│ ├── a.en.md <-- regular content
+│ ├── _index.de.md <-- branch bundle
+│ └── _index.en.md <-- branch bundle
+├── _index.de.md
+└── _index.en.md
+```
+
+With the English language site:
+
+ |regular content|leaf bundle|branch bundle
+:--|:--|:--|:--
+BaseFileName|a.en|index.en|_index.en
+ContentBaseName|a|b|news
+Dir|news/|news/b/|news/
+Ext|md|md|md
+Filename|/home/user/...|/home/user/...|/home/user/...
+IsContentAdapter|false|false|false
+LogicalName|a.en.md|index.en.md|_index.en.md
+Path|news/a.en.md|news/b/index.en.md|news/_index.en.md
+Section|news|news|news
+TranslationBaseName|a|index|_index
+UniqueID|15be14b...|186868f...|7d9159d...
+
+## Defensive coding
+
+Some of the pages on a site may not be backed by a file. For example:
+
+- Top level section pages
+- Taxonomy pages
+- Term pages
+
+Without a backing file, Hugo will throw an error if you attempt to access a `.File` property. To code defensively, first check for file existence:
+
+```go-html-template
+{{ with .File }}
+ {{ .ContentBaseName }}
+{{ end }}
+```
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: FirstSection
+description: Returns the Page object of the top level section of which the given page is a descendant.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: page.Page
+ signatures: [PAGE.FirstSection]
+---
+
++{{% glossary-term section %}}
+
+{{% note %}}
+When called on the home page, the `FirstSection` method returns the `Page` object of the home page itself.
+{{% /note %}}
+
+Consider this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md <-- first section: auctions
+│ │ ├── auction-1.md
+│ │ └── auction-2.md <-- first section: auctions
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md <-- first section: auctions
+│ ├── bidding.md
+│ └── payment.md <-- first section: auctions
+├── books/
+│ ├── _index.md <-- first section: books
+│ ├── book-1.md
+│ └── book-2.md <-- first section: books
+├── films/
+│ ├── _index.md <-- first section: films
+│ ├── film-1.md
+│ └── film-2.md <-- first section: films
+└── _index.md <-- first section: home
+```
+
+To link to the top level section of which the current page is a descendant:
+
+```go-html-template
+<a href="{{ .FirstSection.RelPermalink }}">{{ .FirstSection.LinkTitle }}</a>
+```
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: InSection
+description: Reports whether the given page is in the given section.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: bool
+ signatures: [PAGE.InSection SECTION]
+toc: true
+---
+
+The `InSection` method on a `Page` object reports whether the given page is in the given section. Note that the method returns `true` when comparing a page to a sibling.
+
++{{% glossary-term section %}}
+
+With this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md
+│ │ ├── auction-1.md
+│ │ └── auction-2.md
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md
+│ ├── bidding.md
+│ └── payment.md
+└── _index.md
+```
+
+When rendering the "auction-1" page:
+
+```go-html-template
+{{ with .Site.GetPage "/" }}
+ {{ $.InSection . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.InSection . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11" }}
+ {{ $.InSection . }} → true
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11/auction-2" }}
+ {{ $.InSection . }} → true
+{{ end }}
+```
+
+In the examples above we are coding defensively using the [`with`] statement, returning nothing if the page does not exist. By adding an [`else`] clause we can do some error reporting:
+
+```go-html-template
+{{ $path := "/auctions/2023-11" }}
+{{ with .Site.GetPage $path }}
+ {{ $.InSection . }} → true
+{{ else }}
+ {{ errorf "Unable to find the section with path %s" $path }}
+{{ end }}
+ ```
+
+## Understanding context
+
+Inside of the `with` block, the [context](g) (the dot) is the section `Page` object, not the `Page` object passed into the template. If we were to use this syntax:
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ .InSection . }} → true
+{{ end }}
+```
+
+The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+
+{{% note %}}
+Use the `$` to get the context passed into the template.
+{{% /note %}}
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.InSection . }} → true
+{{ end }}
+```
+
+{{% note %}}
+Gaining a thorough understanding of context is critical for anyone writing template code.
+{{% /note %}}
+
+[`with`]: /functions/go-template/with/
+[`else`]: /functions/go-template/else/
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: IsAncestor
+description: Reports whether PAGE1 is an ancestor of PAGE2.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: bool
+ signatures: [PAGE1.IsAncestor PAGE2]
+toc: true
+---
+
++{{% glossary-term section %}}
+
+With this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md
+│ │ ├── auction-1.md
+│ │ └── auction-2.md
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md
+│ ├── bidding.md
+│ └── payment.md
+└── _index.md
+```
+
+When rendering the "auctions" page:
+
+```go-html-template
+{{ with .Site.GetPage "/" }}
+ {{ $.IsAncestor . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.IsAncestor . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11" }}
+ {{ $.IsAncestor . }} → true
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11/auction-2" }}
+ {{ $.IsAncestor . }} → true
+{{ end }}
+```
+
+In the examples above we are coding defensively using the [`with`] statement, returning nothing if the page does not exist. By adding an [`else`] clause we can do some error reporting:
+
+```go-html-template
+{{ $path := "/auctions/2023-11" }}
+{{ with .Site.GetPage $path }}
+ {{ $.IsAncestor . }} → true
+{{ else }}
+ {{ errorf "Unable to find the section with path %s" $path }}
+{{ end }}
+ ```
+
+## Understanding context
+
+Inside of the `with` block, the [context](g) (the dot) is the section `Page` object, not the `Page` object passed into the template. If we were to use this syntax:
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ .IsAncestor . }} → true
+{{ end }}
+```
+
+The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+
+{{% note %}}
+Use the `$` to get the context passed into the template.
+{{% /note %}}
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.IsAncestor . }} → true
+{{ end }}
+```
+
+{{% note %}}
+Gaining a thorough understanding of context is critical for anyone writing template code.
+{{% /note %}}
+
+[`with`]: /functions/go-template/with/
+[`else`]: /functions/go-template/else/
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: IsDescendant
+description: Reports whether PAGE1 is a descendant of PAGE2.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/Parent
+ - methods/page/Sections
+ returnType: bool
+ signatures: [PAGE1.IsDescendant PAGE2]
+---
+
++{{% glossary-term section %}}
+
+With this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md
+│ │ ├── auction-1.md
+│ │ └── auction-2.md
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md
+│ ├── bidding.md
+│ └── payment.md
+└── _index.md
+```
+
+When rendering the "auctions" page:
+
+```go-html-template
+{{ with .Site.GetPage "/" }}
+ {{ $.IsDescendant . }} → true
+{{ end }}
+
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.IsDescendant . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11" }}
+ {{ $.IsDescendant . }} → false
+{{ end }}
+
+{{ with .Site.GetPage "/auctions/2023-11/auction-2" }}
+ {{ $.IsDescendant . }} → false
+{{ end }}
+```
+
+In the examples above we are coding defensively using the [`with`] statement, returning nothing if the page does not exist. By adding an [`else`] clause we can do some error reporting:
+
+```go-html-template
+{{ $path := "/auctions/2023-11" }}
+{{ with .Site.GetPage $path }}
+ {{ $.IsDescendant . }} → true
+{{ else }}
+ {{ errorf "Unable to find the section with path %s" $path }}
+{{ end }}
+ ```
+
+## Understanding context
+
+Inside of the `with` block, the [context](g) (the dot) is the section `Page` object, not the `Page` object passed into the template. If we were to use this syntax:
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ .IsDescendant . }} → true
+{{ end }}
+```
+
+The result would be wrong when rendering the "auction-1" page because we are comparing the section page to itself.
+
+{{% note %}}
+Use the `$` to get the context passed into the template.
+{{% /note %}}
+
+```go-html-template
+{{ with .Site.GetPage "/auctions" }}
+ {{ $.IsDescendant . }} → true
+{{ end }}
+```
+
+{{% note %}}
+Gaining a thorough understanding of context is critical for anyone writing template code.
+{{% /note %}}
+
+[`with`]: /functions/go-template/with/
+[`else`]: /functions/go-template/else/
--- /dev/null
- In the last example, the collection includes pages in the resources subdirectory. That directory is not a [section](g)---it does not contain an `_index.md` file. Its contents are part of the lesson-2 section.
+---
+title: Pages
+description: Returns a collection of regular pages within the current section, and section pages of immediate descendant sections.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/RegularPages
+ - methods/page/RegularPagesRecursive
+ returnType: page.Pages
+ signatures: [PAGE.Pages]
+---
+
+The `Pages` method on a `Page` object is available to these [page kinds](g): `home`, `section`, `taxonomy`, and `term`. The templates for these page kinds receive a page [collection](g) in [context](g).
+
+Range through the page collection in your template:
+
+```go-html-template
+{{ range .Pages.ByTitle }}
+ <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
+{{ end }}
+```
+
+Consider this content structure:
+
+```text
+content/
+├── lessons/
+│ ├── lesson-1/
+│ │ ├── _index.md
+│ │ ├── part-1.md
+│ │ └── part-2.md
+│ ├── lesson-2/
+│ │ ├── resources/
+│ │ │ ├── task-list.md
+│ │ │ └── worksheet.md
+│ │ ├── _index.md
+│ │ ├── part-1.md
+│ │ └── part-2.md
+│ ├── _index.md
+│ ├── grading-policy.md
+│ └── lesson-plan.md
+├── _index.md
+├── contact.md
+└── legal.md
+```
+
+When rendering the home page, the `Pages` method returns:
+
+ contact.md
+ legal.md
+ lessons/_index.md
+
+When rendering the lessons page, the `Pages` method returns:
+
+ lessons/grading-policy.md
+ lessons/lesson-plan.md
+ lessons/lesson-1/_index.md
+ lessons/lesson-2/_index.md
+
+When rendering lesson-1, the `Pages` method returns:
+
+ lessons/lesson-1/part-1.md
+ lessons/lesson-1/part-2.md
+
+When rendering lesson-2, the `Pages` method returns:
+
+ lessons/lesson-2/part-1.md
+ lessons/lesson-2/part-2.md
+ lessons/lesson-2/resources/task-list.md
+ lessons/lesson-2/resources/worksheet.md
+
++In the last example, the collection includes pages in the resources subdirectory. That directory is not a [section](g)---it does not contain an `_index.md` file. Its contents are part of the lesson-2 section.
+
+{{% note %}}
+When used with a `Site` object, the `Pages` method recursively returns all pages within the site. See [details].
+
+[details]: /methods/site/pages/
+{{% /note %}}
+
+```go-html-template
+{{ range .Site.Pages.ByTitle }}
+ <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
+{{ end }}
+```
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: Parent
+description: Returns the Page object of the parent section of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Sections
+ returnType: page.Page
+ signatures: [PAGE.Parent]
+---
+
++{{% glossary-term section %}}
+
+{{% note %}}
+The parent section of a regular page is the [current section].
+
+[current section]: /methods/page/currentsection/
+{{% /note %}}
+
+Consider this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md <-- parent: auctions
+│ │ ├── auction-1.md
+│ │ └── auction-2.md <-- parent: 2023-11
+│ ├── 2023-12/
+│ │ ├── _index.md
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md <-- parent: home
+│ ├── bidding.md
+│ └── payment.md <-- parent: auctions
+├── books/
+│ ├── _index.md <-- parent: home
+│ ├── book-1.md
+│ └── book-2.md <-- parent: books
+├── films/
+│ ├── _index.md <-- parent: home
+│ ├── film-1.md
+│ └── film-2.md <-- parent: films
+└── _index.md <-- parent: nil
+```
+
+In the example above, note the parent section of the home page is nil. Code defensively by verifying existence of the parent section before calling methods on its `Page` object. To create a link to the parent section page of the current page:
+
+```go-html-template
+{{ with .Parent }}
+ <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+{{ end }}
+```
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: Path
+description: Returns the logical path of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/File
+ - methods/page/RelPermalink
+ returnType: string
+ signatures: [PAGE.Path]
+toc: true
+---
+
++{{< new-in 0.123.0 />}}
+
+The `Path` method on a `Page` object returns the [logical path](g) of the given page, regardless of whether the page is backed by a file.
+
+```go-html-template
+{{ .Path }} → /posts/post-1
+```
+
+This value is neither a file path nor a relative URL. It is a logical identifier for each page, independent of content format, language, and URL modifiers.
+
+{{% note %}}
+Beginning with the release of [v0.92.0] in January 2022, Hugo emitted a warning whenever calling the `Path` method. The warning indicated that this method would change in a future release.
+
+The meaning of, and value returned by, the `Path` method on a `Page` object changed with the release of [v0.123.0] in February 2024.
+
+[v0.92.0]: https://github.com/gohugoio/hugo/releases/tag/v0.92.0
+[v0.123.0]: https://github.com/gohugoio/hugo/releases/tag/v0.123.0
+{{% /note %}}
+
+To determine the logical path for pages backed by a file, Hugo starts with the file path, relative to the `content` directory, and then:
+
+1. Strips the file extension
+1. Strips the language identifier
+1. Converts the result to lower case
+1. Replaces spaces with hyphens
+
+The value returned by the `Path` method on a `Page` object is independent of content format, language, and URL modifiers such as the `slug` and `url` front matter fields.
+
+## Examples
+
+### Monolingual site
+
+Note that the logical path is independent of content format and URL modifiers.
+
+File path|Front matter slug|Logical path
+:--|:--|:--
+`content/_index.md`||`/`
+`content/posts/_index.md`||`/posts`
+`content/posts/post-1.md`|`foo`|`/posts/post-1`
+`content/posts/post-2.html`|`bar`|`/posts/post-2`
+
+### Multilingual site
+
+Note that the logical path is independent of content format, language identifiers, and URL modifiers.
+
+File path|Front matter slug|Logical path
+:--|:--|:--
+`content/_index.en.md`||`/`
+`content/_index.de.md`||`/`
+`content/posts/_index.en.md`||`/posts`
+`content/posts/_index.de.md`||`/posts`
+`content/posts/posts-1.en.md`|`foo`|`/posts/post-1`
+`content/posts/posts-1.de.md`|`foo`|`/posts/post-1`
+`content/posts/posts-2.en.html`|`bar`|`/posts/post-2`
+`content/posts/posts-2.de.html`|`bar`|`/posts/post-2`
+
+### Pages not backed by a file
+
+The `Path` method on a `Page` object returns a value regardless of whether the page is backed by a file.
+
+```text
+content/
+└── posts/
+ └── post-1.md <-- front matter: tags = ['hugo']
+```
+
+When you build the site:
+
+```text
+public/
+├── posts/
+│ ├── post-1/
+│ │ └── index.html .Page.Path = /posts/post-1
+│ └── index.html .Page.Path = /posts
+├── tags/
+│ ├── hugo/
+│ │ └── index.html .Page.Path = /tags/hugo
+│ └── index.html .Page.Path = /tags
+└── index.html .Page.Path = /
+```
+
+## Finding pages
+
+These methods, functions, and shortcodes use the logical path to find the given page:
+
+Methods|Functions|Shortcodes
+:--|:--|:--
+[`Site.GetPage`]|[`urls.Ref`]|[`ref`]
+[`Page.GetPage`]|[`urls.RelRef`]|[`relref`]
+[`Page.Ref`]||
+[`Page.RelRef`]||
+[`Shortcode.Ref`]||
+[`Shortcode.RelRef`]||
+
+[`urls.Ref`]: /functions/urls/ref/
+[`urls.RelRef`]: /functions/urls/relref/
+[`Page.GetPage`]: /methods/page/getpage/
+[`Site.GetPage`]: /methods/site/getpage/
+[`ref`]: /shortcodes/ref/
+[`relref`]: /shortcodes/relref/
+[`Page.Ref`]: /methods/page/ref/
+[`Page.RelRef`]: /methods/page/relref/
+[`Shortcode.Ref`]: /methods/shortcode/ref
+[`Shortcode.RelRef`]: /methods/shortcode/relref
+
+{{% note %}}
+Specify the logical path when using any of these methods, functions, or shortcodes. If you include a file extension or language identifier, Hugo will strip these values before finding the page in the logical tree.
+{{% /note %}}
+
+## Logical tree
+
+Just as file paths form a file tree, logical paths form a logical tree.
+
+A file tree:
+
+```text
+content/
+└── s1/
+ ├── p1/
+ │ └── index.md
+ └── p2.md
+```
+
+The same content represented as a logical tree:
+
+```text
+content/
+└── s1/
+ ├── p1
+ └── p2
+```
+
+A key difference between these trees is the relative path from p1 to p2:
+
+- In the file tree, the relative path from p1 to p2 is `../p2.md`
+- In the logical tree, the relative path is `p2`
+
+{{% note %}}
+Remember to use the logical path when using any of the methods, functions, or shortcodes listed in the previous section. If you include a file extension or language identifier, Hugo will strip these values before finding the page in the logical tree.
+{{% /note %}}
--- /dev/null
- In the last example, the collection includes pages in the resources subdirectory. That directory is not a [section](g)---it does not contain an _index.md file. Its contents are part of the lesson-2 section.
+---
+title: RegularPages
+description: Returns a collection of regular pages within the current section.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Pages
+ - methods/page/RegularPagesRecursive
+ returnType: page.Pages
+ signatures: [PAGE.RegularPages]
+---
+
+The `RegularPages` method on a `Page` object is available to these [page kinds](g): `home`, `section`, `taxonomy`, and `term`. The templates for these page kinds receive a page [collection](g) in [context](g).
+
+Range through the page collection in your template:
+
+```go-html-template
+{{ range .RegularPages.ByTitle }}
+ <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
+{{ end }}
+```
+
+Consider this content structure:
+
+```text
+content/
+├── lessons/
+│ ├── lesson-1/
+│ │ ├── _index.md
+│ │ ├── part-1.md
+│ │ └── part-2.md
+│ ├── lesson-2/
+│ │ ├── resources/
+│ │ │ ├── task-list.md
+│ │ │ └── worksheet.md
+│ │ ├── _index.md
+│ │ ├── part-1.md
+│ │ └── part-2.md
+│ ├── _index.md
+│ ├── grading-policy.md
+│ └── lesson-plan.md
+├── _index.md
+├── contact.md
+└── legal.md
+```
+
+When rendering the home page, the `RegularPages` method returns:
+
+ contact.md
+ legal.md
+
+When rendering the lessons page, the `RegularPages` method returns:
+
+ lessons/grading-policy.md
+ lessons/lesson-plan.md
+
+When rendering lesson-1, the `RegularPages` method returns:
+
+ lessons/lesson-1/part-1.md
+ lessons/lesson-1/part-2.md
+
+When rendering lesson-2, the `RegularPages` method returns:
+
+ lessons/lesson-2/part-1.md
+ lessons/lesson-2/part-2.md
+ lessons/lesson-2/resources/task-list.md
+ lessons/lesson-2/resources/worksheet.md
+
++In the last example, the collection includes pages in the resources subdirectory. That directory is not a [section](g)---it does not contain an `_index.md` file. Its contents are part of the lesson-2 section.
+
+{{% note %}}
+When used with the `Site` object, the `RegularPages` method recursively returns all regular pages within the site. See [details].
+
+[details]: /methods/site/regularpages/
+{{% /note %}}
+
+```go-html-template
+{{ range .Site.RegularPages.ByTitle }}
+ <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
+{{ end }}
+```
--- /dev/null
- {{< new-in 0.117.0 >}}
+---
+title: RenderShortcodes
+description: Renders all shortcodes in the content of the given page, preserving the surrounding markup.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Content
+ - methods/page/Summary
+ - methods/page/ContentWithoutSummary
+ - methods/page/RawContent
+ - methods/page/Plain
+ - methods/page/PlainWords
+ - methods/page/RenderString
+ returnType: template.HTML
+ signatures: [PAGE.RenderShortcodes]
+toc: true
+---
+
++{{< new-in 0.117.0 />}}
+
+Use this method in shortcode templates to compose a page from multiple content files, while preserving a global context for footnotes and the table of contents.
+
+For example:
+
+{{< code file=layouts/shortcodes/include.html >}}
+{{ with .Get 0 }}
+ {{ with $.Page.GetPage . }}
+ {{- .RenderShortcodes }}
+ {{ else }}
+ {{ errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
+ {{ end }}
+{{ else }}
+ {{ errorf "The %q shortcode requires a positional parameter indicating the logical path of the file to include. See %s" .Name .Position }}
+{{ end }}
+{{< /code >}}
+
+Then call the shortcode in your Markdown:
+
+{{< code file=content/about.md lang=md >}}
+{{%/* include "/snippets/services" */%}}
+{{%/* include "/snippets/values" */%}}
+{{%/* include "/snippets/leadership" */%}}
+{{< /code >}}
+
+Each of the included Markdown files can contain calls to other shortcodes.
+
+## Shortcode notation
+
+In the example above it's important to understand the difference between the two delimiters used when calling a shortcode:
+
+- `{{</* myshortcode */>}}` tells Hugo that the rendered shortcode does not need further processing. For example, the shortcode content is HTML.
+- `{{%/* myshortcode */%}}` tells Hugo that the rendered shortcode needs further processing. For example, the shortcode content is Markdown.
+
+Use the latter for the "include" shortcode described above.
+
+## Further explanation
+
+To understand what is returned by the `RenderShortcodes` method, consider this content file
+
+{{< code file=content/about.md lang=text >}}
++++
+title = 'About'
+date = 2023-10-07T12:28:33-07:00
++++
+
+{{</* ref "privacy" */>}}
+
+An *emphasized* word.
+{{< /code >}}
+
+With this template code:
+
+```go-html-template
+{{ $p := site.GetPage "/about" }}
+{{ $p.RenderShortcodes }}
+```
+
+Hugo renders this:;
+
+```html
+https://example.org/privacy/
+
+An *emphasized* word.
+```
+
+Note that the shortcode within the content file was rendered, but the surrounding Markdown was preserved.
+
+## Limitations
+
+The primary use case for `.RenderShortcodes` is inclusion of Markdown content. If you try to use `.RenderShortcodes` inside `HTML` blocks when inside Markdown, you will get a warning similar to this:
+
+```
+WARN .RenderShortcodes detected inside HTML block in "/content/mypost.md"; this may not be what you intended ...
+```
+
+The above warning can be turned off is this is what you really want.
--- /dev/null
- {{< new-in "0.140.0" >}}
+---
+title: Resources
+description: Returns a collection of page resources.
+categories: []
+keywords: []
+action:
+ related:
+ - functions/resources/ByType
+ - functions/resources/Get
+ - functions/resources/GetMatch
+ - functions/resources/GetRemote
+ - functions/resources/Match
+ returnType: resource.Resources
+ signatures: [PAGE.Resources]
+toc: true
+---
+
+The `Resources` method on a `Page` object returns a collection of page resources. A page resource is a file within a [page bundle](g).
+
+To work with global or remote resources, see the [`resources`] functions.
+
+## Methods
+
+###### ByType
+
+(`resource.Resources`) Returns a collection of page resources of the given [media type], or nil if none found. The media type is typically one of `image`, `text`, `audio`, `video`, or `application`.
+
+```go-html-template
+{{ range .Resources.ByType "image" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
+When working with global resources instead of page resources, use the [`resources.ByType`] function.
+
+###### Get
+
+(`resource.Resource`) Returns a page resource from the given path, or nil if none found.
+
+```go-html-template
+{{ with .Resources.Get "images/a.jpg" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
+When working with global resources instead of page resources, use the [`resources.Get`] function.
+
+###### GetMatch
+
+(`resource.Resource`) Returns the first page resource from paths matching the given [glob pattern], or nil if none found.
+
+```go-html-template
+{{ with .Resources.GetMatch "images/*.jpg" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
+When working with global resources instead of page resources, use the [`resources.GetMatch`] function.
+
+###### Match
+
+(`resource.Resources`) Returns a collection of page resources from paths matching the given [glob pattern], or nil if none found.
+
+```go-html-template
+{{ range .Resources.Match "images/*.jpg" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+{{ end }}
+```
+
+When working with global resources instead of page resources, use the [`resources.Match`] function.
+
+###### Mount
+
++{{< new-in 0.140.0 />}}
+
+(`ResourceGetter`) Mounts the given resources from the two arguments base (`string`) to the given target path (`string`) and returns an object that implements [Get](#get). Note that leading slashes in target marks an absolute path. Relative target paths allows you to mount resources relative to another set, e.g. a [Page bundle](/content-management/page-bundles/):
+
+```go-html-template
+{{ $common := resources.Match "/js/headlessui/*.*" }}
+{{ $importContext := (slice $.Page ($common.Mount "/js/headlessui" ".")) }}
+```
+
+This method is currently only useful in [js.Batch](/functions/js/batch/#import-context).
+
+## Pattern matching
+
+With the `GetMatch` and `Match` methods, Hugo determines a match using a case-insensitive [glob pattern].
+
+{{% include "functions/_common/glob-patterns.md" %}}
+
+[`resources.ByType`]: /functions/resources/ByType/
+[`resources.GetMatch`]: /functions/resources/ByType/
+[`resources.Get`]: /functions/resources/ByType/
+[`resources.Match`]: /functions/resources/ByType/
+[`resources`]: /functions/resources/
+[glob pattern]: https://github.com/gobwas/glob#example
+[media type]: https://en.wikipedia.org/wiki/Media_type
--- /dev/null
- description: Returns a "scratch pad" on the given page to store and manipulate data.
+---
+title: Scratch
- related:
- - methods/page/Store
- - functions/collections/NewScratch
++description: Returns a "scratch pad" to store and manipulate data, scoped to the current page.
+categories: []
+keywords: []
+action:
- toc: true
- aliases: [/extras/scratch/,/doc/scratch/,/functions/scratch]
- expiryDate: 2025-11-18 # deprecated 2024-11-18
++ related: []
+ returnType: maps.Scratch
+ signatures: [PAGE.Scratch]
-
- The `Scratch` method on a `Page` object creates a [scratch pad](g) to store and manipulate data. To create a scratch pad that is not reset on server rebuilds, use the [`Store`] method instead.
-
- To create a locally scoped scratch pad that is not attached to a `Page` object, use the [`newScratch`] function.
-
- [`Store`]: /methods/page/store/
- [`newScratch`]: /functions/collections/newscratch/
-
- {{% include "methods/page/_common/scratch-methods.md" %}}
-
- ## Determinate values
-
- The `Scratch` method is often used to set scratch pad values within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are indeterminate until Hugo renders the page content.
-
- If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable:
-
- ```go-html-template
- {{ $noop := .Content }}
- {{ .Store.Get "mykey" }}
- ```
-
- You can also trigger content rendering with the `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount` methods. For example:
-
- ```go-html-template
- {{ $noop := .WordCount }}
- {{ .Store.Get "mykey" }}
- ```
++expiryDate: 2026-11-18 # deprecated 2024-11-18 (soft)
+---
+
+{{% deprecated-in 0.138.0 %}}
+Use the [`PAGE.Store`] method instead.
+
+This is a soft deprecation. This method will be removed in a future release, but the removal date has not been established. Although Hugo will not emit a warning if you continue to use this method, you should begin using `PAGE.Store` as soon as possible.
+
+Beginning with v0.138.0 the `PAGE.Scratch` method is aliased to `PAGE.Store`.
+
+[`PAGE.Store`]: /methods/page/store/
+{{% /deprecated-in %}}
--- /dev/null
- {{% include "methods/page/_common/definition-of-section.md" %}}
+---
+title: Sections
+description: Returns a collection of section pages, one for each immediate descendant section of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Ancestors
+ - methods/page/CurrentSection
+ - methods/page/FirstSection
+ - methods/page/InSection
+ - methods/page/IsAncestor
+ - methods/page/IsDescendant
+ - methods/page/Parent
+ returnType: page.Pages
+ signatures: [PAGE.Sections]
+---
+
++{{% glossary-term section %}}
+
+With this content structure:
+
+```text
+content/
+├── auctions/
+│ ├── 2023-11/
+│ │ ├── _index.md <-- front matter: weight = 202311
+│ │ ├── auction-1.md
+│ │ └── auction-2.md
+│ ├── 2023-12/
+│ │ ├── _index.md <-- front matter: weight = 202312
+│ │ ├── auction-3.md
+│ │ └── auction-4.md
+│ ├── _index.md <-- front matter: weight = 30
+│ ├── bidding.md
+│ └── payment.md
+├── books/
+│ ├── _index.md <-- front matter: weight = 20
+│ ├── book-1.md
+│ └── book-2.md
+├── films/
+│ ├── _index.md <-- front matter: weight = 10
+│ ├── film-1.md
+│ └── film-2.md
+└── _index.md
+```
+
+And this template:
+
+```go-html-template
+{{ range .Sections.ByWeight }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+{{ end }}
+```
+
+On the home page, Hugo renders:
+
+```html
+<h2><a href="/films/">Films</a></h2>
+<h2><a href="/books/">Books</a></h2>
+<h2><a href="/auctions/">Auctions</a></h2>
+```
+
+On the auctions page, Hugo renders:
+
+```html
+<h2><a href="/auctions/2023-11/">Auctions in November 2023</a></h2>
+<h2><a href="/auctions/2023-12/">Auctions in December 2023</a></h2>
+```
--- /dev/null
- : (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef).
+---
+title: Sitemap
+description: Returns the sitemap settings for the given page as defined in front matter, falling back to the sitemap settings as defined in the site configuration.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: config.SitemapConfig
+ signatures: [PAGE.Sitemap]
+toc: true
+---
+
+Access to the `Sitemap` method on a `Page` object is restricted to [sitemap templates].
+
+## Methods
+
+changefreq
- disable {{< new-in 0.125.0 >}}
++: (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef).
+
+```go-html-template
+{{ .Sitemap.ChangeFreq }}
+```
+
- : (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority).
++disable {{< new-in 0.125.0 />}}
+: (`bool`) Whether to disable page inclusion. Default is `false`. Set to `true` in front matter to exclude the page.
+
+```go-html-template
+{{ .Sitemap.Disable }}
+```
+
+priority
++: (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority).
+
+```go-html-template
+{{ .Sitemap.Priority }}
+```
+
+## Example
+
+With this site configuration:
+
+{{< code-toggle file=hugo >}}
+[sitemap]
+changeFreq = 'monthly'
+{{< /code-toggle >}}
+
+And this content:
+
+{{< code-toggle file=content/news.md fm=true >}}
+title = 'News'
+[sitemap]
+changeFreq = 'hourly'
+{{< /code-toggle >}}
+
+And this simplistic sitemap template:
+
+{{< code file=layouts/_default/sitemap.xml >}}
+{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ {{ range .Pages }}
+ <url>
+ <loc>{{ .Permalink }}</loc>
+ {{ if not .Lastmod.IsZero }}
+ <lastmod>{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</lastmod>
+ {{ end }}
+ {{ with .Sitemap.ChangeFreq }}
+ <changefreq>{{ . }}</changefreq>
+ {{ end }}
+ </url>
+ {{ end }}
+</urlset>
+{{< /code >}}
+
+The change frequency will be `hourly` for the news page, and `monthly` for other pages.
+
+[sitemap templates]: /templates/sitemap/
--- /dev/null
- linktitle: PAGE.Store
- description: Returns a persistent "scratch pad" on the given page to store and manipulate data.
+---
+title: Store
- - methods/page/scratch
- - methods/site/store
- - functions/hugo/store
- - functions/collections/NewScratch
++description: Returns a "scratch pad" to store and manipulate data, scoped to the current page.
+categories: []
+keywords: []
+action:
+ related:
- aliases: [/functions/store]
++ - methods/site/Store
++ - methods/shortcode/Store
++ - functions/hugo/Store
++ - functions/collections/NewScratch
+ returnType: maps.Scratch
+ signatures: [PAGE.Store]
+toc: true
- The `Store` method on a `Page` object creates a persistent [scratch pad](g) to store and manipulate data. To create a locally scoped scratch pad that is not attached to a `Page` object, use the [`newScratch`] function.
++aliases: [/functions/store/,/extras/scratch/,/doc/scratch/,/functions/scratch]
+---
+
- [`Scratch`]: /methods/page/scratch/
- [`newScratch`]: /functions/collections/newscratch/
++Use the `Store` method on a `Page` object to create a [scratch pad](g) to store and manipulate data, scoped to the current page. To create a scratch pad with a different [scope](g), refer to the [scope](#scope) section below.
+
- ## Methods
-
- ###### Set
-
- Sets the value of a given key.
-
- ```go-html-template
- {{ .Store.Set "greeting" "Hello" }}
- ```
-
- ###### Get
-
- Gets the value of a given key.
-
- ```go-html-template
- {{ .Store.Set "greeting" "Hello" }}
- {{ .Store.Get "greeting" }} → Hello
- ```
-
- ###### Add
-
- Adds a given value to existing value(s) of the given key.
-
- For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
-
- ```go-html-template
- {{ .Store.Set "greeting" "Hello" }}
- {{ .Store.Add "greeting" "Welcome" }}
- {{ .Store.Get "greeting" }} → HelloWelcome
- ```
-
- ```go-html-template
- {{ .Store.Set "total" 3 }}
- {{ .Store.Add "total" 7 }}
- {{ .Store.Get "total" }} → 10
- ```
-
- ```go-html-template
- {{ .Store.Set "greetings" (slice "Hello") }}
- {{ .Store.Add "greetings" (slice "Welcome" "Cheers") }}
- {{ .Store.Get "greetings" }} → [Hello Welcome Cheers]
- ```
-
- ###### SetInMap
-
- Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`.
-
- ```go-html-template
- {{ .Store.SetInMap "greetings" "english" "Hello" }}
- {{ .Store.SetInMap "greetings" "french" "Bonjour" }}
- {{ .Store.Get "greetings" }} → map[english:Hello french:Bonjour]
- ```
-
- ###### DeleteInMap
-
- Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`.
-
- ```go-html-template
- {{ .Store.SetInMap "greetings" "english" "Hello" }}
- {{ .Store.SetInMap "greetings" "french" "Bonjour" }}
- {{ .Store.DeleteInMap "greetings" "english" }}
- {{ .Store.Get "greetings" }} → map[french:Bonjour]
- ```
-
- ###### GetSortedMapValues
-
- Returns an array of values from `key` sorted by `mapKey`.
-
- ```go-html-template
- {{ .Store.SetInMap "greetings" "english" "Hello" }}
- {{ .Store.SetInMap "greetings" "french" "Bonjour" }}
- {{ .Store.GetSortedMapValues "greetings" }} → [Hello Bonjour]
- ```
-
- ###### Delete
-
- Removes the given key.
-
- ```go-html-template
- {{ .Store.Set "greeting" "Hello" }}
- {{ .Store.Delete "greeting" }}
- ```
++{{% include "_common/store-methods.md" %}}
+
++{{% include "_common/scratch-pad-scope.md" %}}
+
+## Determinate values
+
+The `Store` method is often used to set scratch pad values within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are indeterminate until Hugo renders the page content.
+
+If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable:
+
+```go-html-template
+{{ $noop := .Content }}
+{{ .Store.Get "mykey" }}
+```
+
+You can also trigger content rendering with the `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount` methods. For example:
+
+```go-html-template
+{{ $noop := .WordCount }}
+{{ .Store.Get "mykey" }}
+```
--- /dev/null
- See [details].
+---
+title: Title
+description: Returns the title of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/LinkTitle
+ returnType: string
+ signatures: [PAGE.Title]
+---
+
+With pages backed by a file, the `Title` method returns the `title` field as defined in front matter:
+
+{{< code-toggle file=content/about.md fm=true >}}
+title = 'About us'
+{{< /code-toggle >}}
+
+```go-html-template
+{{ .Title }} → About us
+```
+
+With section, taxonomy, and term pages not backed by a file, the `Title` method returns the section name, capitalized and pluralized. You can disable these transformations by setting [`capitalizeListTitles`] and [`pluralizeListTitles`] in your site configuration. For example:
+
+{{< code-toggle file=hugo >}}
+capitalizeListTitles = false
+pluralizeListTitles = false
+{{< /code-toggle >}}
+
+You can change the capitalization style in your site configuration to one of `ap`, `chicago`, `go`, `firstupper`, or `none`. For example:
+
+{{< code-toggle file=hugo >}}
+titleCaseStyle = "firstupper"
+{{< /code-toggle >}}
+
++ See [details].
+
+[`capitalizeListTitles`]: /getting-started/configuration/#capitalizelisttitles
+[`pluralizeListTitles`]: /getting-started/configuration/#pluralizelisttitles
+[details]: /getting-started/configuration/#configure-title-case
--- /dev/null
- - methods/page/Type
+---
+title: Type
+description: Returns the content type of the given page.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Kind
+ - methods/page/Layout
+ returnType: string
+ signatures: [PAGE.Type]
+---
+
+The `Type` method on a `Page` object returns the [content type](g) of the given page. The content type is defined by the `type` field in front matter, or inferred from the top-level directory name if the `type` field in front matter is not defined.
+
+With this content structure:
+
+```text
+content/
+├── auction/
+│ ├── _index.md
+│ ├── item-1.md
+│ └── item-2.md <-- front matter: type = books
+├── books/
+│ ├── _index.md
+│ ├── book-1.md
+│ └── book-2.md
+├── films/
+│ ├── _index.md
+│ ├── film-1.md
+│ └── film-2.md
+└── _index.md
+```
+
+To list the books, regardless of [section](g):
+
+```go-html-template
+{{ range where .Site.RegularPages.ByTitle "Type" "books" }}
+ <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
+{{ end }}
+```
+
+Hugo renders this to;
+
+```html
+<h2><a href="/books/book-1/">Book 1</a></h2>
+<h2><a href="/books/book-2/">Book 2</a></h2>
+<h2><a href="/auction/item-2/">Item 2</a></h2>
+```
+
+The `type` field in front matter is also useful for targeting a template. See [details].
+
+[details]: /templates/lookup-order/#target-a-template
--- /dev/null
- related:
- - methods/page/Paginate
+---
+title: PageSize
+description: Returns the number of pages per pager.
+categories: []
+keywords: []
+action:
- expiryDate: 2025-06-09 # deprecated 2024-06-09
++ related: []
+ returnType: int
+ signatures: [PAGER.PageSize]
-
- The number of pages per pager is determined by the optional second argument passed to the [`Paginate`] method, falling back to the `pagerSize` as defined in your [site configuration].
-
- [`Paginate`]: /methods/page/paginate/
- [site configuration]: /templates/pagination/#configuration
-
- ```go-html-template
- {{ $pages := where site.RegularPages "Type" "posts" }}
- {{ $paginator := .Paginate $pages }}
-
- {{ range $paginator.Pages }}
- <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
- {{ end }}
-
- {{ with $paginator }}
- {{ .PageSize }}
- {{ end }}
- ```
++expiryDate: 2026-06-09 # deprecated 2024-06-09 in v0.128.0
+---
+
+{{% deprecated-in 0.128.0 %}}
+Use [`PAGER.PagerSize`] instead.
+
+[`PAGER.PagerSize`]: /methods/pager/pagersize/
+{{% /deprecated-in %}}
--- /dev/null
- {{< new-in 0.128.0 >}}
+---
+title: PagerSize
+description: Returns the number of pages per pager.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/Paginate
+ returnType: int
+ signatures: [PAGER.PagerSize]
+---
+
++{{< new-in 0.128.0 />}}
+
+The number of pages per pager is determined by the optional second argument passed to the [`Paginate`] method, falling back to the `pagerSize` as defined in your [site configuration].
+
+[`Paginate`]: /methods/page/paginate/
+[site configuration]: /templates/pagination/#configuration
+
+```go-html-template
+{{ $pages := where site.RegularPages "Type" "posts" }}
+{{ $paginator := .Paginate $pages }}
+
+{{ range $paginator.Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+{{ end }}
+
+{{ with $paginator }}
+ {{ .PagerSize }}
+{{ end }}
+```
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Colors
+description: Applicable to images, returns a slice of the most dominant colors using a simple histogram method.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: '[]images.Color'
+ signatures: [RESOURCE.Colors]
+toc: true
+math: true
+---
+
+The `Resources.Colors` method returns a slice of the most dominant colors in an image, ordered from most dominant to least dominant. This method is fast, but if you also downsize your image you can improve performance by extracting the colors from the scaled image.
+
+{{% include "methods/resource/_common/global-page-remote-resources.md" %}}
+
+## Methods
+
+Each color is an object with the following methods:
+
+ColorHex
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`string`) Returns the [hexadecimal color] value, prefixed with a hash sign.
+
+Luminance
++{{< new-in 0.125.0 />}}
+: (`float64`) Returns the [relative luminance] of the color in the sRGB colorspace in the range [0, 1]. A value of `0` represents the darkest black, while a value of `1` represents the lightest white.
+
+{{% note %}}
+Image filters such as [`images.Dither`], [`images.Padding`], and [`images.Text`] accept either hexadecimal color values or `images.Color` objects as arguments.
+
+Hugo renders an `images.Color` object as a hexadecimal color value.
+
+[`images.Dither`]: /functions/images/dither/
+[`images.Padding`]: /functions/images/padding/
+[`images.Text`]: /functions/images/text/
+{{% /note %}}
+
+[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
+[relative luminance]: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
+
+## Sorting
+
+As a contrived example, create a table of an image's dominant colors with the most dominant color first, and display the relative luminance of each dominant color:
+
+```go-html-template
+{{ with resources.Get "images/a.jpg" }}
+ <table>
+ <thead>
+ <tr>
+ <th>Color</th>
+ <th>Relative luminance</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{ range .Colors }}
+ <tr>
+ <td>{{ .ColorHex }}</td>
+ <td>{{ .Luminance | lang.FormatNumber 4 }}</td>
+ </tr>
+ {{ end }}
+ </tbody>
+ </table>
+{{ end }}
+```
+
+Hugo renders this to:
+
+ColorHex|Relative luminance
+:--|:--
+`#bebebd`|`0.5145`
+`#514947`|`0.0697`
+`#768a9a`|`0.2436`
+`#647789`|`0.1771`
+`#90725e`|`0.1877`
+`#a48974`|`0.2704`
+
+To sort by dominance with the least dominant color first:
+
+```go-html-template
+{{ range .Colors | collections.Reverse }}
+```
+
+To sort by relative luminance with the darkest color first:
+
+```go-html-template
+{{ range sort .Colors "Luminance" }}
+```
+
+To sort by relative luminance with the lightest color first, use either of these constructs:
+
+```go-html-template
+{{ range sort .Colors "Luminance" | collections.Reverse }}
+{{ range sort .Colors "Luminance" "desc" }}
+```
+
+## Examples
+
+### Image borders
+
+To add a 5 pixel border to an image using the most dominant color:
+
+```go-html-template
+{{ with resources.Get "images/a.jpg" }}
+ {{ $mostDominant := index .Colors 0 }}
+ {{ $filter := images.Padding 5 $mostDominant }}
+ {{ with .Filter $filter }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+To add a 5 pixel border to an image using the darkest dominant color:
+
+```go-html-template
+{{ with resources.Get "images/a.jpg" }}
+ {{ $darkest := index (sort .Colors "Luminance") 0 }}
+ {{ $filter := images.Padding 5 $darkest }}
+ {{ with .Filter $filter }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+```
+
+### Light text on dark background
+
+To create a text box where the foreground and background colors are derived from an image's lightest and darkest dominant colors:
+
+```go-html-template
+{{ with resources.Get "images/a.jpg" }}
+ {{ $darkest := index (sort .Colors "Luminance") 0 }}
+ {{ $lightest := index (sort .Colors "Luminance" "desc") 0 }}
+ <div style="background: {{ $darkest }};">
+ <div style="color: {{ $lightest }};">
+ <p>This is light text on a dark background.</p>
+ </div>
+ </div>
+{{ end }}
+```
+
+### WCAG contrast ratio
+
+In the previous example we placed light text on a dark background, but does this color combination conform to [WCAG] guidelines for either the [minimum] or the [enhanced] contrast ratio?
+
+The WCAG defines the [contrast ratio] as:
+
+$$contrast\ ratio = { L_1 + 0.05 \over L_2 + 0.05 }$$
+
+where $L_1$ is the relative luminance of the lightest color and $L_2$ is the relative luminance of the darkest color.
+
+Calculate the contrast ratio to determine WCAG conformance:
+
+```go-html-template
+{{ with resources.Get "images/a.jpg" }}
+ {{ $lightest := index (sort .Colors "Luminance" "desc") 0 }}
+ {{ $darkest := index (sort .Colors "Luminance") 0 }}
+ {{ $cr := div
+ (add $lightest.Luminance 0.05)
+ (add $darkest.Luminance 0.05)
+ }}
+ {{ if ge $cr 7.5 }}
+ {{ printf "The %.2f contrast ratio conforms to WCAG Level AAA." $cr }}
+ {{ else if ge $cr 4.5 }}
+ {{ printf "The %.2f contrast ratio conforms to WCAG Level AA." $cr }}
+ {{ else }}
+ {{ printf "The %.2f contrast ratio does not conform to WCAG guidelines." $cr }}
+ {{ end }}
+{{ end }}
+```
+
+[WCAG]: https://en.wikipedia.org/wiki/Web_Content_Accessibility_Guidelines
+[contrast ratio]: https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
+[enhanced]: https://www.w3.org/WAI/WCAG22/quickref/?showtechniques=145#contrast-enhanced
+[minimum]: https://www.w3.org/WAI/WCAG22/quickref/?showtechniques=145#contrast-minimum
--- /dev/null
- ContentLength
- : (`int`) The content length in bytes.
+---
+title: Data
+description: Applicable to resources returned by the resources.GetRemote function, returns information from the HTTP response.
+categories: []
+keywords: []
+action:
+ related:
+ - functions/resources/GetRemote
+ - methods/resource/Err
+ returnType: map
+ signatures: [RESOURCE.Data]
+---
+
+The `Data` method on a resource returned by the [`resources.GetRemote`] function returns information from the HTTP response.
+
+[`resources.GetRemote`]: /functions/resources/getremote/
+
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
++{{ $opts := dict "responseHeaders" (slice "Server") }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ with .Data }}
+ {{ .ContentLength }} → 42764
+ {{ .ContentType }} → image/jpeg
++ {{ .Headers }} → map[Server:[Netlify]]
+ {{ .Status }} → 200 OK
+ {{ .StatusCode }} → 200
+ {{ .TransferEncoding }} → []
+ {{ end }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
- ContentType
- : (`string`) The content type.
++###### ContentLength
+
- Status
- : (`string`) The HTTP status text.
++(`int`) The content length in bytes.
+
- StatusCode
- : (`int`) The HTTP status code.
++###### ContentType
+
- TransferEncoding
- : (`string`) The transfer encoding.
++(`string`) The content type.
+
++###### Headers
++
++(`map[string][]string`) A map of response headers matching those requested in the [`responseHeaders`] option passed to the `resources.GetRemote` function. The header name matching is case-insensitive. In most cases there will be one value per header key.
++
++[`responseHeaders`]: /functions/resources/getremote/#responseheaders
++
++###### Status
++
++(`string`) The HTTP status text.
++
++###### StatusCode
++
++(`int`) The HTTP status code.
++
++###### TransferEncoding
++
++(`string`) The transfer encoding.
+
+[`resources.GetRemote`]: /functions/resources/getremote/
--- /dev/null
- expiryDate: 2026-01-16 # deprecated 2025-01-16
+---
+title: Err
+description: Applicable to resources returned by the resources.GetRemote function, returns an error message if the HTTP request fails, else nil.
+categories: []
+keywords: []
+action:
+ related:
+ - functions/resources/GetRemote
+ - methods/resource/Data
+ returnType: resource.resourceError
+ signatures: [RESOURCE.Err]
++expiryDate: 2027-01-16 # deprecated 2025-01-16 in v0.141.0
+---
+
+{{% deprecated-in 0.141.0 %}}
+Use the `try` statement instead. See [example].
+
+[example]: /functions/go-template/try/#example
+{{% /deprecated-in %}}
+
+The `Err` method on a resource returned by the [`resources.GetRemote`] function returns an error message if the HTTP request fails, else nil. If you do not handle the error yourself, Hugo will fail the build.
+
+[`resources.GetRemote`]: /functions/resources/getremote/
+
+In this example we send an HTTP request to a nonexistent domain:
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+The code above captures the error from the HTTP request, then fails the build:
+
+```text
+ERROR error calling resources.GetRemote: Get "https://broken-example.org/images/a.jpg": dial tcp: lookup broken-example.org on 127.0.0.53:53: no such host
+```
+
+To log an error as a warning instead of an error:
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+{{% note %}}
+An HTTP response with a 404 status code is not an HTTP request error. To handle 404 status codes, code defensively using the nested `with-else-end` construct as shown above.
+{{% /note %}}
--- /dev/null
- description: Returns a "scratch pad" scoped to the shortcode to store and manipulate data.
+---
+title: Scratch
- related:
- - functions/collections/NewScratch
++description: Returns a "scratch pad" to store and manipulate data, scoped to the current shortcode.
+categories: []
+keywords: []
+action:
- expiryDate: 2025-11-18 # deprecated 2024-11-18
++ related: []
+ returnType: maps.Scratch
+ signatures: [SHORTCODE.Scratch]
-
- The `Scratch` method within a shortcode creates a [scratch pad](g) to store and manipulate data. The scratch pad is scoped to the shortcode.
-
- {{% note %}}
- With the introduction of the [`newScratch`] function, and the ability to [assign values to template variables] after initialization, the `Scratch` method within a shortcode is obsolete.
-
- [assign values to template variables]: https://go.dev/doc/go1.11#text/template
- [`newScratch`]: /functions/collections/newscratch/
- {{% /note %}}
-
- {{% include "methods/page/_common/scratch-methods.md" %}}
++expiryDate: 2026-11-18 # deprecated 2024-11-18 (soft)
+---
+
+{{% deprecated-in 0.139.0 %}}
+Use the [`SHORTCODE.Store`] method instead.
+
+This is a soft deprecation. This method will be removed in a future release, but the removal date has not been established. Although Hugo will not emit a warning if you continue to use this method, you should begin using `SHORTCODE.Store` as soon as possible.
+
+Beginning with v0.139.0 the `SHORTCODE.Scratch` method is aliased to `SHORTCODE.Store`.
+
+[`SHORTCODE.Store`]: /methods/shortcode/store/
+{{% /deprecated-in %}}
--- /dev/null
- description: Returns a "Store pad" scoped to the shortcode to store and manipulate data.
+---
+title: Store
- - functions/collections/NewScratch
++description: Returns a "scratch pad" to store and manipulate data, scoped to the current shortcode.
+categories: []
+keywords: []
+action:
+ related:
- returnType: maps.Store
+ - methods/page/Store
+ - methods/site/Store
+ - functions/hugo/Store
- {{< new-in 0.139.0 >}}
++ - functions/collections/NewScratch
++ returnType: maps.Scratch
+ signatures: [SHORTCODE.Store]
++toc: true
+---
+
- The `Store` method within a shortcode creates a [scratch pad](g) to store and manipulate data. The scratch pad is scoped to the shortcode.
++{{< new-in 0.139.0 />}}
+
- {{% include "methods/page/_common/scratch-methods.md" %}}
++Use the `Store` method to create a [scratch pad](g) to store and manipulate data, scoped to the current shortcode. To create a scratch pad with a different [scope](g), refer to the [scope](#scope) section below.
+
+{{% note %}}
+With the introduction of the [`newScratch`] function, and the ability to [assign values to template variables] after initialization, the `Store` method within a shortcode is mostly obsolete.
+
+[assign values to template variables]: https://go.dev/doc/go1.11#text/template
+[`newScratch`]: /functions/collections/newScratch/
+{{% /note %}}
+
++{{% include "_common/store-methods.md" %}}
++
++{{% include "_common/scratch-pad-scope.md" %}}
--- /dev/null
+---
+title: Shortcode methods
+linkTitle: Shortcode
+description: Use these methods in your shortcode templates.
+categories: []
+keywords: []
+menu:
+ docs:
+ parent: methods
++aliases: [/variables/shortcodes]
+---
+
+Use these methods in your shortcode templates.
--- /dev/null
- expiryDate: 2024-10-30 # deprecated 2023-10-30
+---
+title: DisqusShortname
+description: Returns the Disqus shortname as defined in the site configuration.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: string
+ signatures: [SITE.DisqusShortname]
++expiryDate: 2025-10-30 # deprecated 2023-10-30 in v0.120.0
+---
+
+{{% deprecated-in 0.120.0 %}}
+Use [`Site.Config.Services.Disqus.Shortname`] instead.
+
+[`Site.Config.Services.Disqus.Shortname`]: /methods/site/config/
+{{% /deprecated-in %}}
--- /dev/null
- expiryDate: 2024-10-30 # deprecated 2023-10-30
+---
+title: GoogleAnalytics
+description: Returns the Google Analytics tracking ID as defined in the site configuration.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: string
+ signatures: [SITE.GoogleAnalytics]
++expiryDate: 2025-10-30 # deprecated 2023-10-30 in v0.120.0
+---
+
+{{% deprecated-in 0.120.0 %}}
+Use [`Site.Config.Services.GoogleAnalytics.ID`] instead.
+
+[`Site.Config.Services.GoogleAnalytics.ID`]: /methods/site/config/
+{{% /deprecated-in %}}
--- /dev/null
- expiryDate: 2024-10-30 # deprecated 2023-10-30
+---
+title: IsDevelopment
+description: Reports whether the current running environment is “development”.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: bool
+ signatures: [SITE.IsDevelopment]
-
- ```go-html-template
- {{ .Site.IsDevelopment }} → true/false
- ```
++expiryDate: 2025-10-30 # deprecated 2023-10-30 in v0.120.0
+---
+
+{{% deprecated-in 0.120.0 %}}
+Use [`hugo.IsDevelopment`] instead.
+
+[`hugo.IsDevelopment`]: /functions/hugo/isdevelopment/
+{{% /deprecated-in %}}
--- /dev/null
- expiryDate: 2025-03-16 # deprecated 2024-03-16
+---
+title: IsMultiLingual
+description: Reports whether there are two or more configured languages.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: bool
+ signatures: [SITE.IsMultiLingual]
-
- Site configuration:
-
- {{< code-toggle file=hugo >}}
- defaultContentLanguage = 'de'
- defaultContentLanguageInSubdir = true
- [languages]
- [languages.de]
- languageCode = 'de-DE'
- languageName = 'Deutsch'
- title = 'Projekt Dokumentation'
- weight = 1
- [languages.en]
- languageCode = 'en-US'
- languageName = 'English'
- title = 'Project Documentation'
- weight = 2
- {{< /code-toggle >}}
-
- Template:
-
- ```go-html-template
- {{ .Site.IsMultiLingual }} → true
- ```
++expiryDate: 2026-03-16 # deprecated 2024-03-16 in 0.124.0
+---
+
+{{% deprecated-in 0.124.0 %}}
+Use [`hugo.IsMultilingual`] instead.
+
+[`hugo.IsMultilingual`]: /functions/hugo/ismultilingual/
+{{% /deprecated-in %}}
--- /dev/null
- expiryDate: 2024-10-30 # deprecated 2023-10-30
+---
+title: IsServer
+description: Reports whether the built-in development server is running.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: bool
+ signatures: [SITE.IsServer]
-
- ```go-html-template
- {{ .Site.IsServer }} → true/false
- ```
++expiryDate: 2025-10-30 # deprecated 2023-10-30 in v0.120.0
+---
+
+{{% deprecated-in 0.120.0 %}}
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{% /deprecated-in %}}
--- /dev/null
- expiryDate: 2025-02-19 # deprecated 2024-02-19
+---
+title: LastChange
+description: Returns the last modification date of site content.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: time.Time
+ signatures: [SITE.LastChange]
-
- The `LastChange` method on a `Site` object returns a [`time.Time`] value. Use this with time [functions] and [methods]. For example:
-
- ```go-html-template
- {{ .Site.LastChange | time.Format ":date_long" }} → January 31, 2024
-
- ```
-
- [`time.Time`]: https://pkg.go.dev/time#Time
- [functions]: /functions/time/
- [methods]: /methods/time/
++expiryDate: 2026-02-19 # deprecated 2024-02-19 in v0.123.0
+---
+
+{{% deprecated-in 0.123.0 %}}
+Use [`.Site.Lastmod`] instead.
+
+[`.Site.Lastmod`]: /methods/site/lastmod/
+{{% /deprecated-in %}}
--- /dev/null
- {{< new-in 0.123.0 >}}
+---
+title: Lastmod
+description: Returns the last modification date of site content.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: time.Time
+ signatures: [SITE.Lastmod]
+---
+
++{{< new-in 0.123.0 />}}
+
+The `Lastmod` method on a `Site` object returns a [`time.Time`] value. Use this with time [functions] and [methods]. For example:
+
+```go-html-template
+{{ .Site.Lastmod | time.Format ":date_long" }} → January 31, 2024
+
+```
+
+[`time.Time`]: https://pkg.go.dev/time#Time
+[functions]: /functions/time/
+[methods]: /methods/time/
--- /dev/null
- linktitle: site.Store
- description: Returns a persistent "scratch pad" on the given site to store and manipulate data.
+---
+title: Store
- {{< new-in 0.139.0 >}}
++description: Returns a "scratch pad" to store and manipulate data, scoped to the current site.
+categories: []
+keywords: []
+action:
+ related:
+ - methods/page/store
+ - functions/hugo/store
+ - functions/collections/NewScratch
+ returnType: maps.Scratch
+ signatures: [site.Store]
+toc: true
+---
+
- The `Store` method on a `Site` object creates a persistent [scratch pad](g) to store and manipulate data. To create a locally scoped scratch pad that is not attached to a `Site` object, use the [`newScratch`] function.
-
- [`Scratch`]: /methods/site/scratch/
- [`newScratch`]: /functions/collections/newscratch/
++{{< new-in 0.139.0 />}}
+
++Use the `Store` method on a `Site` object to create a [scratch pad](g) to store and manipulate data, scoped to the current site. To create a scratch pad with a different [scope](g), refer to the [scope](#scope) section below.
+
+## Methods
+
+###### Set
+
+Sets the value of a given key.
+
+```go-html-template
+{{ site.Store.Set "greeting" "Hello" }}
+```
+
+###### Get
+
+Gets the value of a given key.
+
+```go-html-template
+{{ site.Store.Set "greeting" "Hello" }}
+{{ site.Store.Get "greeting" }} → Hello
+```
+
+###### Add
+
+Adds a given value to existing value(s) of the given key.
+
+For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
+
+```go-html-template
+{{ site.Store.Set "greeting" "Hello" }}
+{{ site.Store.Add "greeting" "Welcome" }}
+{{ site.Store.Get "greeting" }} → HelloWelcome
+```
+
+```go-html-template
+{{ site.Store.Set "total" 3 }}
+{{ site.Store.Add "total" 7 }}
+{{ site.Store.Get "total" }} → 10
+```
+
+```go-html-template
+{{ site.Store.Set "greetings" (slice "Hello") }}
+{{ site.Store.Add "greetings" (slice "Welcome" "Cheers") }}
+{{ site.Store.Get "greetings" }} → [Hello Welcome Cheers]
+```
+
+###### SetInMap
+
+Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`.
+
+```go-html-template
+{{ site.Store.SetInMap "greetings" "english" "Hello" }}
+{{ site.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ site.Store.Get "greetings" }} → map[english:Hello french:Bonjour]
+```
+
+###### DeleteInMap
+
+Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`.
+
+```go-html-template
+{{ site.Store.SetInMap "greetings" "english" "Hello" }}
+{{ site.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ site.Store.DeleteInMap "greetings" "english" }}
+{{ site.Store.Get "greetings" }} → map[french:Bonjour]
+```
+
+###### GetSortedMapValues
+
+Returns an array of values from `key` sorted by `mapKey`.
+
+```go-html-template
+{{ site.Store.SetInMap "greetings" "english" "Hello" }}
+{{ site.Store.SetInMap "greetings" "french" "Bonjour" }}
+{{ site.Store.GetSortedMapValues "greetings" }} → [Hello Bonjour]
+```
+
+###### Delete
+
+Removes the given key.
+
+```go-html-template
+{{ site.Store.Set "greeting" "Hello" }}
+{{ site.Store.Delete "greeting" }}
+```
+
++{{% include "_common/scratch-pad-scope.md" %}}
++
+## Determinate values
+
+The `Store` method is often used to set scratch pad values within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are indeterminate until Hugo renders the page content.
+
+If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable:
+
+```go-html-template
+{{ $noop := .Content }}
+{{ site.Store.Get "mykey" }}
+```
+
+You can also trigger content rendering with the `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount` methods. For example:
+
+```go-html-template
+{{ $noop := .WordCount }}
+{{ site.Store.Get "mykey" }}
+```
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Page
+description: Returns the taxonomy page or nil if the taxonomy has no terms.
+categories: []
+keywords: []
+action:
+ related: []
+ returnType: page.Page
+ signatures: [TAXONOMY.Page]
+---
+
++{{< new-in 0.125.0 />}}
+
+This `TAXONOMY` method returns nil if the taxonomy has no terms, so you must code defensively:
+
+```go-html-template
+{{ with .Site.Taxonomies.tags.Page }}
+ <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
+{{ end }}
+```
+
+This is rendered to:
+
+```html
+<a href="/tags/">Tags</a>
+```
--- /dev/null
+---
+
+title: Myshowcase
+date: 2021-01-14
++draft: true
+
+description: "A short description of this page."
+
+# The URL to the site on the internet.
+siteURL: https://gohugo.io/
+
+# Link to the site's Hugo source code if public and you can/want to share.
+# Remove or leave blank if not needed/wanted.
+siteSource: https://github.com/gohugoio/hugoDocs
+
+# Add credit to the article author. Leave blank or remove if not needed/wanted.
+byline: "[bep](https://github.com/bep), Hugo Lead"
+
+---
+
+To complete this showcase:
+
+1. Write the story about your site in this file.
+1. Add a summary to the `bio.md` file in this directory.
+1. Replace the `featured-template.png` with a screenshot of your site. You can rename it, but it must contain the word `featured`.
+1. Create a new pull request in https://github.com/gohugoio/hugoDocs/pulls
+
+The content of this bundle explained:
+
+index.md
+: The main content file. Fill in required front matter metadata and write your story. I does not have to be a novel. It can even be self-promotional, but it should include Hugo in some form.
+
+bio.md
+: A short summary of the website. Site credits (who built it) fits nicely here.
+
+featured.png
+: A reasonably sized screenshot of your website. It can be named anything, but the name must start with "featured". The sample image is `1500x750` (2:1 aspect ratio).
--- /dev/null
+---
+title: News
++description: Stay up-to-date with the latest news and announcements.
+outputs:
+ - html
+ - rss
+aliases: [/release-notes/]
++weight: 10
+---
--- /dev/null
- linkTitle: In this section
- description: Quick reference guides to Hugo's features, functions, and methods.
+---
+title: Quick reference guides
- Quick reference guides to Hugo's features, functions, and methods.
++linktitle: Quick reference
++description: Use these quick reference guides for quick access to key information.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: quick-reference-in-this-section
+ parent: quick-reference
+ weight: 10
+weight: 10
+showSectionMenu: false
+---
+
++{{% param description %}}
--- /dev/null
--- /dev/null
++---
++title: Glossary
++description: Terms commonly used throughout the documentation.
++categories: [quick-reference]
++keywords: [glossary]
++hide_in_this_section: true
++menu:
++ docs:
++ parent: quick-reference
++ weight: 40
++aliases: [/getting-started/glossary/]
++weight: 40
++layout: single
++build:
++ render: always
++ list: always
++cascade:
++ build:
++ render: never
++ list: local
++---
++
++{{% glossary %}}
--- /dev/null
--- /dev/null
++---
++title: action
++---
++
++See [_template action_](g).
--- /dev/null
--- /dev/null
++---
++title: archetype
++details: /content-management/archetypes
++---
++
++An _archetype_ is a template for new content.
--- /dev/null
--- /dev/null
++---
++title: argument
++---
++
++An _argument_ is a [_scalar_](g), [_array_](g), [_slice_](g), [_map_](g), or [_object_](g) passed to a [_function_](g), [_method_](g), or [_shortcode_](g).
--- /dev/null
--- /dev/null
++---
++title: array
++reference: https://go.dev/ref/spec#Array_types
++---
++
++An _array_ is a numbered sequence of [_elements_](g). Unlike Go's [_slice_](g) data type, an array has a fixed length. Elements within an array can be [_scalars_](g), slices, [_maps_](g), pages, or other arrays.
--- /dev/null
--- /dev/null
++---
++title: asset pipeline
++---
++
++An _asset pipeline_ is a system that automates and optimizes the handling of static assets like images, stylesheets, and JavaScript files.
--- /dev/null
--- /dev/null
++---
++title: bool
++---
++
++See [_boolean_](g).
--- /dev/null
--- /dev/null
++---
++title: boolean
++---
++
++A _boolean_ is a data type with two possible values, either `true` or `false`.
--- /dev/null
--- /dev/null
++---
++title: branch bundle
++reference: /content-management/page-bundles
++---
++
++A _branch bundle_ is a top-level content directory or any content directory containing an `_index.md` file. Analogous to a physical branch, a branch bundle may have descendants including [_leaf bundles_](g) and other branch bundles. A branch bundle may also contain [_page resources_](g) such as images.
--- /dev/null
--- /dev/null
++---
++title: build
++---
++
++To _build_ a site is to generate HTML files and assets such as images, CSS files, and JavaScript files. The build process includes rendering and resource transformations.
--- /dev/null
--- /dev/null
++---
++title: bundle
++---
++
++See [page bundle](g).
--- /dev/null
--- /dev/null
++---
++title: cache
++---
++
++A _cache_ is a software component that stores data so that future requests for the same data are faster.
--- /dev/null
--- /dev/null
++---
++title: chain
++---
++
++To _chain_ is to connect one or more [_identifiers_](g) with a dot. An identifier can represent a [_method_](g), [_object_](g), or [_field_](g). For example, `.Site.Params.author.name` or `.Date.UTC.Hour`.
--- /dev/null
--- /dev/null
++---
++title: CJK
++---
++
++_CJK_ is a collective term for the Chinese, Japanese, and Korean languages.
--- /dev/null
--- /dev/null
++---
++title: CLI
++---
++
++_CLI_ is an abbreviation of Command Line Interface.
--- /dev/null
--- /dev/null
++---
++title: collection
++---
++
++A _collection_ is an [_array_](g), [_slice_](g), or [_map_](g).
--- /dev/null
--- /dev/null
++---
++title: content adapter
++reference: /content-management/content-adapters
++---
++
++A _content adapter_ is a template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
--- /dev/null
--- /dev/null
++---
++title: content format
++reference: /content-management/formats
++---
++
++A _content format_ is a markup language for creating content. Typically Markdown, but may also be HTML, AsciiDoc, Org, Pandoc, or reStructuredText.
--- /dev/null
--- /dev/null
++---
++title: content type
++reference: /content-management/types
++---
++
++A _content type_ is a classification of content inferred from the top-level directory name or the `type` set in [front matter](g). Pages in the root of the `content` directory, including the home page, are of type "page". Accessed via `.Page.Type` in [_templates_](g).
--- /dev/null
--- /dev/null
++---
++title: content view
++reference: /templates/content-view
++---
++
++A _content view_ is a template called with the [`Render`](/methods/page/render/) method on a `Page` object.
--- /dev/null
--- /dev/null
++---
++title: context
++reference: /templates/introduction/#context
++---
++
++Represented by a dot (`.`) within a [_template action_](g), _context_ is the current location in a data structure. For example, while iterating over a [_collection_](g) of pages, the context within each iteration is the page's data structure. The context received by each template depends on template type and/or how it was called.
--- /dev/null
--- /dev/null
++---
++title: default sort order
++---
++
++The _default sort order_ is the default order in which Hugo sorts page collections: by [_weight_](g), then by date (descending), then by link title, and then by file path.
--- /dev/null
--- /dev/null
++---
++title: duration
++---
++
++A _duration_ is a data type that represent a length of time, expressed using units such as seconds (represented by `s`), minutes (represented by `m`), and hours (represented by `h`). For example, `42s` means 42 seconds, `6m7s` means 6 minutes and 7 seconds, and `6h7m42s` means 6 hours, 7 minutes, and 42 seconds.
--- /dev/null
--- /dev/null
++---
++title: element
++---
++
++An _element_ is a member of a [_slice_](g) or [_array_](g).
--- /dev/null
--- /dev/null
++---
++title: embedded template
++---
++
++An _embedded template_ is a built-in component within the Hugo application. This includes features like [_partials_](g), [_shortcodes_](g), and [_render hooks_](g) that provide pre-defined structures or functionalities for creating website content.
--- /dev/null
--- /dev/null
++---
++title: environment
++---
++
++Typically one of `development`, `staging`, or `production`, each _environment_ may exhibit different behavior depending on configuration and template logic. For example, in a production environment you might minify and fingerprint CSS, but that probably doesn't make sense in a development environment.
++
++When running the built-in development server with the `hugo server` command, the environment is set to `development`. When building your site with the `hugo` command, the environment is set to `production`. To override the environment value, use the `--environment` command line flag or the `HUGO_ENVIRONMENT` environment variable.
++
++To determine the current environment within a template, use the [`hugo.Environment`] function.
++
++[`hugo.Environment`]: /functions/hugo/environment/
--- /dev/null
--- /dev/null
++---
++title: field
++---
++
++A _field_ is a predefined key-value pair in front matter such as `date` or `title`.
--- /dev/null
--- /dev/null
++---
++title: flag
++reference: /commands/hugo
++---
++
++A _flag_ is an option passed to a command-line program, beginning with one or two hyphens.
--- /dev/null
--- /dev/null
++---
++title: float
++alias: true
++---
++
++See [floating point](g).
--- /dev/null
--- /dev/null
++---
++title: floating point
++---
++
++The term _floating point_ refers to a numeric data type with a fractional component. For example, `3.14159`.
--- /dev/null
--- /dev/null
++---
++title: fragment
++---
++
++A _fragment_ is the final segment of a URL, beginning with a hash (`#`) mark, that references an `id` attribute of an HTML element on the page.
--- /dev/null
--- /dev/null
++---
++title: front matter
++reference: /content-management/front-matter
++---
++
++The term _front matter_ refers to the metadata at the beginning of each content page, separated from the content by format-specific delimiters.
--- /dev/null
--- /dev/null
++---
++title: function
++reference: /functions
++---
++
++Used within a [_template action_](g), a _function_ takes one or more [_arguments_](g) and returns a value. Unlike [_methods_](g), functions are not associated with an [_object_](g).
--- /dev/null
--- /dev/null
++---
++title: glob
++reference: https://github.com/gobwas/glob?tab=readme-ov-file#example
++---
++
++A _glob_ is a pattern used to match filenames and paths. It's a shorthand for specifying a set of files, making it easier to work with multiple files at once.
--- /dev/null
--- /dev/null
++---
++title: global resource
++---
++
++A _global resource_ is file within the `assets` directory, or within any directory mounted to the `assets` directory.
--- /dev/null
--- /dev/null
++---
++title: headless bundle
++reference: /content-management/build-options/
++---
++
++A _headless bundle_ is an unpublished [_leaf bundle_](g) or an unpublished [_branch bundle_](g) whose content and resources you can include in other pages.
--- /dev/null
--- /dev/null
++---
++title: i18n
++---
++
++See [_internationalization_](g).
--- /dev/null
--- /dev/null
++---
++title: identifier
++---
++
++An _identifier_ is a string that represents a variable, method, object, or field. It must conform to Go's [language specification](https://go.dev/ref/spec#Identifiers), beginning with a letter or underscore, followed by zero or more letters, digits, or underscores.
--- /dev/null
--- /dev/null
++---
++title: int
++---
++
++See [_integer_](g).
--- /dev/null
--- /dev/null
++---
++title: integer
++---
++
++An _integer_ is a numeric data type without a fractional component. For example, `42`.
--- /dev/null
--- /dev/null
++---
++title: internationalization
++---
++
++The term _internationalization_ refers to software design and development efforts that enable [_localization_](g).
--- /dev/null
--- /dev/null
++---
++title: interpreted string literal
++reference: https://go.dev/ref/spec#String_literals
++---
++
++An _interpreted string literal_ is a character sequences between double quotes, as in "foo". Within the quotes, any character may appear except a newline and an unescaped double quote. The text between the quotes forms the value of the literal, with backslash escapes interpreted.
--- /dev/null
--- /dev/null
++---
++title: interval
++---
++
++An [_interval_](https://en.wikipedia.org/wiki/Interval_(mathematics)) is a range of numbers between two endpoints: closed, open, or half-open.
++
++- A _closed interval_, denoted by brackets, includes its endpoints. For example, [0, 1] is the interval where `0 <= x <= 1`.
++
++- An _open interval_, denoted by parentheses, excludes its endpoints. For example, (0, 1) is the interval where `0 < x < 1`.
++
++- A _half-open interval_ includes only one of its endpoints. For example, (0, 1] is the _left-open_ interval where `0 < x <= 1`, while [0, 1) is the _right-open_ interval where `0 <= x < 1`.
--- /dev/null
--- /dev/null
++---
++title: kind
++---
++
++See [_page kind_](g).
--- /dev/null
--- /dev/null
++---
++title: l10n
++---
++
++See [_localization_](g).
--- /dev/null
--- /dev/null
++---
++title: layout
++---
++
++See [_template_](g).
--- /dev/null
--- /dev/null
++---
++title: leaf bundle
++reference: /content-management/page-bundles/
++---
++
++A _leaf bundle_ is a directory that contains an `index.md` file and zero or more [_resources_](g). Analogous to a physical leaf, a leaf bundle is at the end of a [_branch bundle_](g). It has no descendants.
--- /dev/null
--- /dev/null
++---
++title: lexer
++---
++
++A _lexer_ is a software component that identifies keywords, identifiers, operators, numbers, and other basic building blocks of a programming language within the input text.
--- /dev/null
--- /dev/null
++---
++title: list page
++---
++
++A list page is any [_page kind_](g) that receives a page [_collection_](g) in [_context_](g). This includes the home page, [section pages](g), [taxonomy pages](g), and [term pages](g).
--- /dev/null
--- /dev/null
++---
++title: list template
++---
++
++A _list template_ is any [_template_](g) that renders a [_list page_](g). This includes home, [_section_](g), [_taxonomy_](g), and [_term_](g) templates.
--- /dev/null
--- /dev/null
++---
++title: localization
++reference: /content-management/multilingual/
++---
++
++The term _localization_ refers to the process of adapting a site to meet language and regional requirements. This includes translations, date formats, number formats, currency formats, and collation order.
--- /dev/null
--- /dev/null
++---
++title: logical path
++reference: /methods/page/path/#examples
++---
++
++{{< new-in 0.123.0 />}}
++
++A _logical path_ is a page or page resource identifier derived from the file path, excluding its extension and language identifier. This value is neither a file path nor a URL. Starting with a file path relative to the `content` directory, Hugo determines the logical path by stripping the file extension and language identifier, converting to lower case, then replacing spaces with hyphens.
--- /dev/null
--- /dev/null
++---
++title: map
++reference: https://go.dev/ref/spec#Map_types
++---
++
++A _map_ is an unordered group of elements, each indexed by a unique key.
--- /dev/null
--- /dev/null
++---
++title: Markdown attribute
++reference: /content-management/markdown-attributes/
++---
++
++A _Markdown attribute_ is a key-value pair attached to a Markdown element. These attributes are commonly used to add HTML attributes, like `class` and `id`, to the element when it's rendered into HTML. They provide a way to extend the basic Markdown syntax and add more semantic meaning or styling hooks to your content.
--- /dev/null
--- /dev/null
++---
++title: marshal
++reference: /functions/transform/remarshal/
++---
++
++To _marshal_ is to transform a data structure into a serialized object. For example, transforming a [_map_](g) into a JSON string.
--- /dev/null
--- /dev/null
++---
++title: method
++---
++
++Used within a [_template action_](g) and associated with an [_object_](g), a _method_ takes zero or more [_arguments_](g) and either returns a value or performs an action. For example, `.IsHome` is a method on the `.Page` object which returns `true` if the current page is the home page. See also [_function_](g).
--- /dev/null
--- /dev/null
++---
++title: module
++reference: /hugo-modules/
++---
++
++A _module_ is a packaged combination of [_archetypes_](g), assets, content, data, [_templates_](g), translation tables, static files, or configuration settings. A module may serve as the basis for a new site, or to augment an existing site.
--- /dev/null
--- /dev/null
++---
++title: node
++---
++
++A _node_ is a class of [_page kinds_](g) including `home`, `section`, `taxonomy`, and `term`.
--- /dev/null
--- /dev/null
++---
++title: noop
++---
++
++An abbreviated form of "no operation", a _noop_ is a statement that does nothing.
--- /dev/null
--- /dev/null
++---
++title: object
++---
++
++An _object_ is a data structure with or without associated [_methods_](g).
--- /dev/null
--- /dev/null
++---
++title: ordered taxonomy
++---
++
++Created by invoking the [`Alphabetical`] or [`ByCount`] method on a [`Taxonomy`](g) object, which is a [_map_](g), an _ordered taxonomy_ is a [_slice_](g), where each element is an object that contains the [_term_](g) and a slice of its [weighted pages](g).
++
++[`Alphabetical`]: /methods/taxonomy/alphabetical/
++[`ByCount`]: /methods/taxonomy/bycount/
--- /dev/null
--- /dev/null
++---
++title: output format
++reference: /templates/output-formats/
++---
++
++An _output format_ is a collection of settings that defines how Hugo renders a file when building a site. For example, `html`, `rss`, and `json` are built-in output formats. You can create multiple output formats and control their generation based on [page kind](g), or by enabling one or more output formats for specific pages.
--- /dev/null
--- /dev/null
++---
++title: page bundle
++reference: /content-management/page-bundles/
++---
++
++A _page bundle_ is a directory that encapsulates both content and associated [_resources_](g). There are two types of page bundles: [_leaf bundles_](g) and [_branch bundles_](g).
--- /dev/null
--- /dev/null
++---
++title: page collection
++---
++
++A _page collection_ is a slice of `Page` objects.
--- /dev/null
--- /dev/null
++---
++title: page kind
++reference: /methods/page/kind/
++---
++
++A _page kind_ is a classification of pages, one of `home`, `page`, `section`, `taxonomy`, or `term`.
--- /dev/null
--- /dev/null
++---
++title: page resource
++---
++
++A _page resource_ is a file within a [_page bundle_](g).
--- /dev/null
--- /dev/null
++---
++title: pager
++---
++
++Created during [_pagination_](g), a _pager_ contains a subset of a list page and navigation links to other pagers.
--- /dev/null
--- /dev/null
++---
++title: paginate
++---
++
++To _paginate_ is to split a list page into two or more subsets.
--- /dev/null
--- /dev/null
++---
++title: pagination
++reference: /templates/pagination
++---
++
++The term _pagination_ refers to the process of [_paginating_](g) a list page.
--- /dev/null
--- /dev/null
++---
++title: paginator
++---
++
++A _paginator_ is a collection of [_pagers_](g).
--- /dev/null
--- /dev/null
++---
++title: parameter
++---
++
++A _parameter_ is typically a user-defined key-value pair at the site or page level, but may also refer to a configuration setting or an [_argument_](g).
--- /dev/null
--- /dev/null
++---
++title: partial
++---
++
++A _partial_ is a [_template_](g) called from any other template including [_shortcodes_](g), [render hooks](g), and other partials. A partial either renders something or returns something. A partial can also call itself, for example, to [_walk_](g) a data structure.
--- /dev/null
--- /dev/null
++---
++title: permalink
++---
++
++A _permalink_ is the absolute URL of a published resource or a rendered page, including scheme and host.
--- /dev/null
--- /dev/null
++---
++title: pipe
++---
++
++See [_pipeline_](g).
--- /dev/null
--- /dev/null
++---
++title: pipeline
++---
++
++Within a [_template action_](g), a _pipeline_ is a possibly chained sequence of values, [_function_](g) calls, or [_method_](g) calls. Functions and methods in the pipeline may take multiple [_arguments_](g).
++
++A pipeline may be *chained* by separating a sequence of commands with pipeline characters (`|`). In a chained pipeline, the result of each command is passed as the last argument to the following command. The output of the final command in the pipeline is the value of the pipeline.
--- /dev/null
--- /dev/null
++---
++title: pretty URL
++---
++
++A _pretty URL_ is a URL that does not include a file extension.
--- /dev/null
--- /dev/null
++---
++title: publish
++---
++
++See [_build_](g).
--- /dev/null
--- /dev/null
++---
++title: raw string literal
++reference: https://go.dev/ref/spec#String_literals
++---
++
++A _raw string literal_ is a character sequences between backticks, as in \`bar\`. Within the backticks, any character may appear except a backtick. Backslashes have no special meaning and the string may contain newlines. Carriage return characters (`\r`) inside raw string literals are discarded from the raw string value.
--- /dev/null
--- /dev/null
++---
++title: regular page
++---
++
++A _regular page_ is a page with the "page" [_page kind_](g). See also [_section page_](g).
--- /dev/null
--- /dev/null
++---
++title: relative permalink
++---
++
++A _relative permalink_ is the host-relative URL of a published resource or a rendered page.
--- /dev/null
--- /dev/null
++---
++title: remote resource
++---
++
++A _remote resource_ is a file on a remote server, accessible via HTTP or HTTPS.
--- /dev/null
--- /dev/null
++---
++title: render hook
++reference: /render-hooks
++---
++
++A _render hook_ is a [_template_](g) that overrides standard Markdown rendering.
--- /dev/null
--- /dev/null
++---
++title: resource type
++---
++
++A _resource type_ is the main type of a resource's [media type]. Content files such as Markdown, HTML, AsciiDoc, Pandoc, reStructuredText, and Emacs Org Mode have resource type `page`. Other resource types include `image`, `video`, etc. Retrieve the resource type using the [`ResourceType`] method on a `Resource` object.
++
++[media type]: /methods/resource/mediatype/
++[`ResourceType`]: /methods/resource/resourcetype/
--- /dev/null
--- /dev/null
++---
++title: resource
++---
++
++A _resource_ is any file consumed by the build process to augment or generate content, structure, behavior, or presentation. For example: images, videos, content snippets, CSS, Sass, JavaScript, and data.
++
++Hugo supports three types of resources: [_global resources_](g), [_page resources_](g), and [_remote resources_](g).
--- /dev/null
--- /dev/null
++---
++title: scalar
++---
++
++A _scalar_ is a single value, one of [_string_](g), [_integer_](g), [floating point](g), or [_boolean_](g).
--- /dev/null
--- /dev/null
++---
++title: scope
++---
++
++The term _scope_ refers to the specific region of code where a [_variable_](g) or [_object_](g) is accessible. For example, a variable initialized in one [template](g) is not available within another.
--- /dev/null
--- /dev/null
++---
++title: scratch pad
++---
++
++Conceptually, a _scratch pad_ is a [_map_](g) with [_methods_](g) to set, get, update, and delete values. Attach the data structure to a `Page` or `Site` object using the [`Store`] method, or create a locally scoped scratch pad using the [`newScratch`] function.
++
++[`Store`]: /methods/page/store/
++[`newScratch`]: /functions/collections/newscratch/
--- /dev/null
--- /dev/null
++---
++title: section page
++---
++
++A _section page_ is a page with the "section" [_page kind_](g). Typically a listing of [_regular pages_](g) and/or other section pages within the current [_section_](g).
--- /dev/null
--- /dev/null
++---
++title: section
++---
++
++A _section_ is a top-level content directory or any content directory containing an `_index.md` file.
--- /dev/null
--- /dev/null
++---
++title: segment
++---
++
++A _segment_ is a subset of a site, filtered by [_logical path_](g), language, [_page kind_](g), or [_output format_](g).
--- /dev/null
--- /dev/null
++---
++title: shortcode
++reference: /content-management/shortcodes
++---
++
++A _shortcode_ is a [_template_](g) invoked within markup, accepting any number of [_arguments_](g). They can be used with any [content format](g) to insert elements such as videos, images, and social media embeds into your content.
--- /dev/null
--- /dev/null
++---
++title: slice
++reference: https://go.dev/ref/spec#Slice_types
++---
++
++A _slice_ is a numbered sequence of elements. Unlike Go's [_array_](g) data type, slices are dynamically sized. [_Elements_](g) within a slice can be [_scalars_](g), [_arrays_](g), [_maps_](g), pages, or other slices.
--- /dev/null
--- /dev/null
++---
++title: string
++---
++
++A _string_ is a sequence of bytes. For example, `"What is 6 times 7?"`.
--- /dev/null
--- /dev/null
++---
++title: taxonomic weight
++reference: content-management/taxonomies/#order-taxonomies
++---
++
++Defined in front matter and unique to each taxonomy, a _taxonomic weight_ is a [_weight_](g) that determines the sort order of page collections contained within a [`Taxonomy`](g) object.
--- /dev/null
--- /dev/null
++---
++title: taxonomy object
++---
++
++A _taxonomy object_ is a [_map_](g) of [_terms_](g) and the [weighted pages](g) associated with each term.
--- /dev/null
--- /dev/null
++---
++title: taxonomy page
++---
++
++A _taxonomy page_ is a page with the "taxonomy" [_page kind_](g). Typically a listing of [_terms_](g) within a given [_taxonomy_](g).
--- /dev/null
--- /dev/null
++---
++title: taxonomy
++reference: /content-management/taxonomies
++---
++A _taxonomy_ is a group of related [_terms_](g) used to classify content. For example, a "colors" taxonomy might include the terms "red", "green", and "blue".
--- /dev/null
--- /dev/null
++---
++title: template action
++reference: https://pkg.go.dev/text/template#hdr-Actions
++---
++
++A data evaluation or control structure within a [_template_](g), delimited by "{{" and "}}".
--- /dev/null
--- /dev/null
++---
++title: template
++reference: /templates
++---
++
++A _template_ is a file with [_template actions_](g), located within the `layouts` directory of a project, theme, or module.
--- /dev/null
--- /dev/null
++---
++title: term page
++---
++
++A _term page_ is a page with the "term" [_page kind_](g). Typically a listing of [_regular pages_](g) and [_section pages_](g) with a given [_term_](g).
--- /dev/null
--- /dev/null
++---
++title: term
++reference: /content-management/taxonomies
++---
++
++A _term_ is a member of a [_taxonomy_](g), used to classify content.
--- /dev/null
--- /dev/null
++---
++title: theme
++---
++
++A _theme_ is a packaged combination of [_archetypes_](g), assets, content, data, [_templates_](g), translation tables, static files, or configuration settings. A theme may serve as the basis for a new site, or to augment an existing site.
--- /dev/null
--- /dev/null
++---
++title: token
++---
++
++A _token_ is an identifier within a format string, beginning with a colon and replaced with a value when rendered. For example, use tokens in format strings for both [permalinks](/content-management/urls/#permalinks) and [dates](/functions/time/format/#localization).
--- /dev/null
--- /dev/null
++---
++title: type
++---
++
++See [content type](g).
--- /dev/null
--- /dev/null
++---
++title: ugly URL
++---
++
++An _ugly URL_ is a URL that includes a file extension.
--- /dev/null
--- /dev/null
++---
++title: unmarshal
++reference: /functions/transform/unmarshal/
++---
++
++To _unmarshal_ is to transform a serialized object into a data structure. For example, transforming a JSON file into a [_map_](g) that you can access within a template.
--- /dev/null
--- /dev/null
++---
++title: variable
++---
++
++A _variable_ is a user-defined [_identifier_](g) prepended with a `$` symbol, representing a value of any data type, initialized or assigned within a [_template action_](g). For example, `$foo` and `$bar` are variables.
--- /dev/null
--- /dev/null
++---
++title: walk
++---
++
++To _walk_ is to recursively traverse a nested data structure. For example, rendering a multilevel menu.
--- /dev/null
--- /dev/null
++---
++title: weight
++---
++
++A _weight_ is a numeric value used to position an element within a sorted [collection](g). Assign weights using non-zero integers. Lighter items float to the top, while heavier items sink to the bottom. Unweighted or zero-weighted elements are placed at the end of the collection. Weights are typically assigned to pages, menu entries, languages, and output formats.
--- /dev/null
--- /dev/null
++---
++title: weighted page
++---
++
++Contained within a [_taxonomy object_](g), a _weighted page_ is a [_map_](g) with two [_elements_](g): a `Page` object, and its [_taxonomic weight_](g) as defined in front matter. Access the elements using the `Page` and `Weight` keys.
--- /dev/null
--- /dev/null
++---
++title: zero time
++---
++
++The _zero time_ is January 1, 0001, 00:00:00 UTC. Formatted per [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) the _zero time_ is 0001-01-01T00:00:00-00:00.
--- /dev/null
- weight: 40
- weight: 40
+---
+title: Methods
+description: A quick reference guide to Hugo's methods, grouped by object.
+categories: [quick reference]
+keywords: []
+menu:
+ docs:
+ parent: quick-reference
++ weight: 50
++weight: 50
+toc: true
+---
+
+{{% quick-reference section="methods" %}}
--- /dev/null
- weight: 50
- weight: 50
+---
+title: Page collections
+description: A quick reference guide to Hugo's page collections.
+categories: [quick reference]
+keywords: []
+menu:
+ docs:
+ parent: quick-reference
++ weight: 60
++weight: 60
+toc: true
+---
+
+## Page
+
+assets/
+Use these `Page` methods when rendering lists on [section pages](g), [taxonomy pages](g), [term pages](g), and the home page.
+
+{{< list-pages-in-section path=/methods/page filter=methods_page_page_collections filterType=include omitElementIDs=true titlePrefix=PAGE. >}}
+
+## Site
+
+Use these `Site` methods when rendering lists on any page.
+
+{{< list-pages-in-section path=/methods/site filter=methods_site_page_collections filterType=include omitElementIDs=true titlePrefix=SITE. >}}
+
+## Filter
+
+Use the [`where`] function to filter page collections.
+
+[`where`]: /functions/collections/where/
+
+## Sort
+
+By default, Hugo sorts page collections by:
+
+1. [Weight]
+1. [Date] in descending order
+1. [LinkTitle] falling back to [Title]
+1. [Filename] if the page is backed by a file
+
+[Date]: /methods/page/date/
+[Weight]: /methods/page/weight/
+[LinkTitle]: /methods/page/linktitle/
+[Title]: /methods/page/title/
+[Filename]: /methods/page/file/#filename
+
+Use these methods to sort page collections.
+
+{{< list-pages-in-section path=/methods/pages filter=methods_pages_sort filterType=include titlePrefix=. omitElementIDs=true titlePrefix=PAGES. >}}
+
+## Group
+
+Use these methods to group page collections.
+
+{{< list-pages-in-section path=/methods/pages filter=methods_pages_group filterType=include titlePrefix=. omitElementIDs=true titlePrefix=PAGES. >}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+_comment: Do not remove front matter.
+---
+
+## PageInner details
+
++{{< new-in 0.125.0 />}}
+
+The primary use case for `PageInner` is to resolve links and [page resources](g) relative to an included `Page`. For example, create an "include" shortcode to compose a page from multiple content files, while preserving a global context for footnotes and the table of contents:
+
+{{< code file=layouts/shortcodes/include.html >}}
+{{ with .Get 0 }}
+ {{ with $.Page.GetPage . }}
+ {{- .RenderShortcodes }}
+ {{ else }}
+ {{ errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
+ {{ end }}
+{{ else }}
+ {{ errorf "The %q shortcode requires a positional parameter indicating the logical path of the file to include. See %s" .Name .Position }}
+{{ end }}
+{{< /code >}}
+
+Then call the shortcode in your Markdown:
+
+{{< code file=content/posts/p1.md >}}
+{{%/* include "/posts/p2" */%}}
+{{< /code >}}
+
+Any render hook triggered while rendering `/posts/p2` will get:
+
+- `/posts/p1` when calling `Page`
+- `/posts/p2` when calling `PageInner`
+
+`PageInner` falls back to the value of `Page` if not relevant, and always returns a value.
+
+{{% note %}}
+The `PageInner` method is only relevant for shortcodes that invoke the [`RenderShortcodes`] method, and you must call the shortcode using the `{{%/*..*/%}}` notation.
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes/
+{{% /note %}}
+
+As a practical example, Hugo's embedded link and image render hooks use the `PageInner` method to resolve markdown link and image destinations. See the source code for each:
+
+- [Embedded link render hook]({{% eturl render-link %}})
+- [Embedded image render hook]({{% eturl render-image %}})
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes/
--- /dev/null
- linkTitle: In this section
+---
+title: Render hooks
++
+description: Create render hooks to override the rendering of Markdown to HTML.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: render-hooks-in-this-section
+ parent: render-hooks
+ weight: 10
+weight: 10
+showSectionMenu: false
+aliases: [/templates/render-hooks/]
+---
+
+Create render hooks to override the rendering of Markdown to HTML.
--- /dev/null
- {{< new-in 0.132.0 >}}
+---
+title: Blockquote render hooks
+linkTitle: Blockquotes
+description: Create a blockquote render hook to override the rendering of Markdown blockquotes to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 30
+weight: 30
+toc: true
+---
+
- {{< new-in 0.134.0 >}}
++{{< new-in 0.132.0 />}}
+
+## Context
+
+Blockquote render hook templates receive the following [context](g):
+
+###### AlertType
+
+(`string`) Applicable when [`Type`](#type) is `alert`, this is the alert type converted to lowercase. See the [alerts](#alerts) section below.
+
+###### AlertTitle
+
- {{< new-in 0.134.0 >}}
++{{< new-in 0.134.0 />}}
+
+(`template.HTML`) Applicable when [`Type`](#type) is `alert`, this is the alert title. See the [alerts](#alerts) section below.
+
+###### AlertSign
+
++{{< new-in 0.134.0 />}}
+
+(`string`) Applicable when [`Type`](#type) is `alert`, this is the alert sign. Typically used to indicate whether an alert is graphically foldable, this is one of `+`, `-`, or an empty string. See the [alerts](#alerts) section below.
+
+###### Attributes
+
+(`map`) The [Markdown attributes], available if you configure your site as follows:
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser.attribute]
+block = true
+{{< /code-toggle >}}
+
+###### Ordinal
+
+(`int`) The zero-based ordinal of the blockquote on the page.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### Position
+
+(`string`) The position of the blockquote within the page content.
+
+###### Text
+(`template.HTML`) The blockquote text, excluding the first line if [`Type`](#type) is `alert`. See the [alerts](#alerts) section below.
+
+###### Type
+
+(`bool`) The blockquote type. Returns `alert` if the blockquote has an alert designator, else `regular`. See the [alerts](#alerts) section below.
+
+## Examples
+
+In its default configuration, Hugo renders Markdown blockquotes according to the [CommonMark specification]. To create a render hook that does the same thing:
+
+[CommonMark specification]: https://spec.commonmark.org/current/
+
+{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}}
+<blockquote>
+ {{ .Text }}
+</blockquote>
+{{< /code >}}
+
+To render a blockquote as an HTML `figure` element with an optional citation and caption:
+
+{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}}
+<figure>
+ <blockquote {{ with .Attributes.cite }}cite="{{ . }}"{{ end }}>
+ {{ .Text }}
+ </blockquote>
+ {{ with .Attributes.caption }}
+ <figcaption class="blockquote-caption">
+ {{ . | safeHTML }}
+ </figcaption>
+ {{ end }}
+</figure>
+{{< /code >}}
+
+Then in your markdown:
+
+```text
+> Some text
+{cite="https://gohugo.io" caption="Some caption"}
+```
+
+## Alerts
+
+Also known as _callouts_ or _admonitions_, alerts are blockquotes used to emphasize critical information.
+
+### Basic syntax
+
+With the basic Markdown syntax, the first line of each alert is an alert designator consisting of an exclamation point followed by the alert type, wrapped within brackets. For example:
+
+{{< code file=content/example.md lang=text >}}
+> [!NOTE]
+> Useful information that users should know, even when skimming content.
+
+> [!TIP]
+> Helpful advice for doing things better or more easily.
+
+> [!IMPORTANT]
+> Key information users need to know to achieve their goal.
+
+> [!WARNING]
+> Urgent info that needs immediate user attention to avoid problems.
+
+> [!CAUTION]
+> Advises about risks or negative outcomes of certain actions.
+{{< /code >}}
+
+The basic syntax is compatible with [GitHub], [Obsidian], and [Typora].
+
+[GitHub]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
+[Obsidian]: https://help.obsidian.md/Editing+and+formatting/Callouts
+[Typora]: https://support.typora.io/Markdown-Reference/#callouts--github-style-alerts
+
+### Extended syntax
+
+With the extended Markdown syntax, you may optionally include an alert sign and/or an alert title. The alert sign is one of `+` or `-`, typically used to indicate whether an alert is graphically foldable. For example:
+
+{{< code file=content/example.md lang=text >}}
+> [!WARNING]+ Radiation hazard
+> Do not approach or handle without protective gear.
+{{< /code >}}
+
+The extended syntax is compatible with [Obsidian].
+
+{{% note %}}
+The extended syntax is not compatible with GitHub or Typora. If you include an alert sign or an alert title, these applications render the Markdown as a blockquote.
+{{% /note %}}
+
+### Example
+
+This blockquote render hook renders a multilingual alert if an alert designator is present, otherwise it renders a blockquote according to the CommonMark specification.
+
+{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}}
+{{ $emojis := dict
+ "caution" ":exclamation:"
+ "important" ":information_source:"
+ "note" ":information_source:"
+ "tip" ":bulb:"
+ "warning" ":information_source:"
+}}
+
+{{ if eq .Type "alert" }}
+ <blockquote class="alert alert-{{ .AlertType }}">
+ <p class="alert-heading">
+ {{ transform.Emojify (index $emojis .AlertType) }}
+ {{ with .AlertTitle }}
+ {{ . }}
+ {{ else }}
+ {{ or (i18n .AlertType) (title .AlertType) }}
+ {{ end }}
+ </p>
+ {{ .Text }}
+ </blockquote>
+{{ else }}
+ <blockquote>
+ {{ .Text }}
+ </blockquote>
+{{ end }}
+{{< /code >}}
+
+To override the label, create these entries in your i18n files:
+
+{{< code-toggle file=i18n/en.toml >}}
+caution = 'Caution'
+important = 'Important'
+note = 'Note'
+tip = 'Tip'
+warning = 'Warning'
+{{< /code-toggle >}}
+
+Although you can use one template with conditional logic as shown above, you can also create separate templates for each [`Type`](#type) of blockquote:
+
+```text
+layouts/
+└── _default/
+ └── _markup/
+ ├── render-blockquote-alert.html
+ └── render-blockquote-regular.html
+```
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Code block render hooks
+linkTitle: Code blocks
+description: Create a code block render hook to override the rendering of Markdown code blocks to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 40
+weight: 40
+toc: true
+---
+
+## Markdown
+
+This Markdown example contains a fenced code block:
+
+{{< code file=content/example.md lang=text >}}
+```bash {class="my-class" id="my-codeblock" lineNos=inline tabWidth=2}
+declare a=1
+echo "$a"
+exit
+```
+{{< /code >}}
+
+A fenced code block consists of:
+
+- A leading [code fence]
+- An optional [info string]
+- A code sample
+- A trailing code fence
+
+[code fence]: https://spec.commonmark.org/0.31.2/#code-fence
+[info string]: https://spec.commonmark.org/0.31.2/#info-string
+
+In the previous example, the info string contains:
+
+- The language of the code sample (the first word)
+- An optional space-delimited or comma-delimited list of attributes (everything within braces)
+
+The attributes in the info string can be generic attributes or highlighting options.
+
+In the example above, the _generic attributes_ are `class` and `id`. In the absence of special handling within a code block render hook, Hugo adds each generic attribute to the HTML element surrounding the rendered code block. Consistent with its content security model, Hugo removes HTML event attributes such as `onclick` and `onmouseover`. Generic attributes are typically global HTML attributes, but you may include custom attributes as well.
+
+In the example above, the _highlighting options_ are `lineNos` and `tabWidth`. Hugo uses the [Chroma] syntax highlighter to render the code sample. You can control the appearance of the rendered code by specifying one or more [highlighting options].
+
+[Chroma]: https://github.com/alecthomas/chroma/
+[highlighting options]: /functions/transform/highlight/#options
+
+{{% note %}}
+Although `style` is a global HTML attribute, when used in an info string it is a highlighting option.
+{{% /note %}}
+
+## Context
+
+Code block render hook templates receive the following [context](g):
+
+###### Attributes
+
+(`map`) The generic attributes from the info string.
+
+###### Inner
+
+(`string`) The content between the leading and trailing code fences, excluding the info string.
+
+###### Options
+
+(`map`) The highlighting options from the info string.
+
+###### Ordinal
+
+(`int`) The zero-based ordinal of the code block on the page.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
++{{< new-in 0.125.0 />}}
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### Position
+
+(`text.Position`) The position of the code block within the page content.
+
+###### Type
+
+(`string`) The first word of the info string, typically the code language.
+
+## Examples
+
+In its default configuration, Hugo renders fenced code blocks by passing the code sample through the Chroma syntax highlighter and wrapping the result. To create a render hook that does the same thing:
+
+[CommonMark specification]: https://spec.commonmark.org/current/
+
+{{< code file=layouts/_default/_markup/render-codeblock.html copy=true >}}
+{{ $result := transform.HighlightCodeBlock . }}
+{{ $result.Wrapped }}
+{{< /code >}}
+
+Although you can use one template with conditional logic to control the behavior on a per-language basis, you can also create language-specific templates.
+
+```text
+layouts/
+└── _default/
+ └── _markup/
+ ├── render-codeblock-mermaid.html
+ ├── render-codeblock-python.html
+ └── render-codeblock.html
+```
+
+For example, to create a code block render hook to render [Mermaid] diagrams:
+
+[Mermaid]: https://mermaid.js.org/
+
+{{< code file=layouts/_default/_markup/render-codeblock-mermaid.html copy=true >}}
+<pre class="mermaid">
+ {{- .Inner | htmlEscape | safeHTML }}
+</pre>
+{{ .Page.Store.Set "hasMermaid" true }}
+{{< /code >}}
+
+Then include this snippet at the bottom of the your base template:
+
+{{< code file=layouts/_default/baseof.html copy=true >}}
+{{ if .Store.Get "hasMermaid" }}
+ <script type="module">
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
+ mermaid.initialize({ startOnLoad: true });
+ </script>
+{{ end }}
+{{< /code >}}
+
+See the [diagrams] page for details.
+
+[diagrams]: /content-management/diagrams/#mermaid-diagrams
+
+## Embedded
+
+Hugo includes an [embedded code block render hook] to render [GoAT diagrams].
+
+[embedded code block render hook]: {{% eturl render-codeblock-goat %}}
+[GoAT diagrams]: /content-management/diagrams/#goat-diagrams-ascii
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Heading render hooks
+linkTitle: Headings
+description: Create a heading render hook to override the rendering of Markdown headings to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 50
+weight: 50
+toc: true
+---
+
+## Context
+
+Heading render hook templates receive the following [context](g):
+
+###### Anchor
+
+(`string`) The `id` attribute of the heading element.
+
+###### Attributes
+
+(`map`) The [Markdown attributes], available if you configure your site as follows:
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser.attribute]
+title = true
+{{< /code-toggle >}}
+
+###### Level
+
+(`int`) The heading level, 1 through 6.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
++{{< new-in 0.125.0 />}}
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### PlainText
+
+(`string`) The heading text as plain text.
+
+###### Text
+
+(`template.HTML`) The heading text.
+
+## Examples
+
+In its default configuration, Hugo renders Markdown headings according to the [CommonMark specification] with the addition of automatic `id` attributes. To create a render hook that does the same thing:
+
+[CommonMark specification]: https://spec.commonmark.org/current/
+
+{{< code file=layouts/_default/_markup/render-heading.html copy=true >}}
+<h{{ .Level }} id="{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}>
+ {{- .Text -}}
+</h{{ .Level }}>
+{{< /code >}}
+
+To add an anchor link to the right of each heading:
+
+{{< code file=layouts/_default/_markup/render-heading.html copy=true >}}
+<h{{ .Level }} id="{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}>
+ {{ .Text }}
+ <a href="#{{ .Anchor }}">#</a>
+</h{{ .Level }}>
+{{< /code >}}
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Image render hooks
+linkTitle: Images
+description: Create an image render to hook override the rendering of Markdown images to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 60
+weight: 60
+toc: true
+---
+
+## Markdown
+
+A Markdown image has three components: the image description, the image destination, and optionally the image title.
+
+```text
+
+ ------------ ------------------ ---------
+ description destination title
+```
+
+These components are passed into the render hook [context](g) as shown below.
+
+## Context
+
+Image render hook templates receive the following context:
+
+###### Attributes
+
+(`map`) The [Markdown attributes], available if you configure your site as follows:
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser]
+wrapStandAloneImageWithinParagraph = false
+[markup.goldmark.parser.attribute]
+block = true
+{{< /code-toggle >}}
+
+###### Destination
+
+(`string`) The image destination.
+
+###### IsBlock
+
+(`bool`) Returns true if a standalone image is not wrapped within a paragraph element.
+
+###### Ordinal
+
+(`int`) The zero-based ordinal of the image on the page.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.125.0 />}}
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### PlainText
+
+(`string`) The image description as plain text.
+
+###### Text
+
+(`template.HTML`) The image description.
+
+###### Title
+
+(`string`) The image title.
+
+## Examples
+
+{{% note %}}
+With inline elements such as images and links, remove leading and trailing whitespace using the `{{‑ ‑}}` delimiter notation to prevent whitespace between adjacent inline elements and text.
+{{% /note %}}
+
+In its default configuration, Hugo renders Markdown images according to the [CommonMark specification]. To create a render hook that does the same thing:
+
+[CommonMark specification]: https://spec.commonmark.org/current/
+
+{{< code file=layouts/_default/_markup/render-image.html copy=true >}}
+<img src="{{ .Destination | safeURL }}"
+ {{- with .PlainText }} alt="{{ . }}"{{ end -}}
+ {{- with .Title }} title="{{ . }}"{{ end -}}
+>
+{{- /* chomp trailing newline */ -}}
+{{< /code >}}
+
+To render standalone images within `figure` elements:
+
+{{< code file=layouts/_default/_markup/render-image.html copy=true >}}
+{{- if .IsBlock -}}
+ <figure>
+ <img src="{{ .Destination | safeURL }}"
+ {{- with .PlainText }} alt="{{ . }}"{{ end -}}
+ >
+ {{- with .Title }}<figcaption>{{ . }}</figcaption>{{ end -}}
+ </figure>
+{{- else -}}
+ <img src="{{ .Destination | safeURL }}"
+ {{- with .PlainText }} alt="{{ . }}"{{ end -}}
+ {{- with .Title }} title="{{ . }}"{{ end -}}
+ >
+{{- end -}}
+{{< /code >}}
+
+Note that the above requires the following site configuration:
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser]
+wrapStandAloneImageWithinParagraph = false
+{{< /code-toggle >}}
+
+## Default
+
++{{< new-in 0.123.0 />}}
+
+Hugo includes an [embedded image render hook] to resolve Markdown image destinations. Disabled by default, you can enable it in your site configuration:
+
+[embedded image render hook]: {{% eturl render-image %}}
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.renderHooks.image]
+enableDefault = true
+{{< /code-toggle >}}
+
+A custom render hook, even when provided by a theme or module, will override the embedded render hook regardless of the configuration setting above.
+
+{{% note %}}
+The embedded image render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites.
+
+[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles
+{{% /note %}}
+
+The embedded image render hook resolves internal Markdown destinations by looking for a matching [page resource](g), falling back to a matching [global resource](g). Remote destinations are passed through, and the render hook will not throw an error or warning if unable to resolve a destination.
+
+You must place global resources in the `assets` directory. If you have placed your resources in the `static` directory, and you are unable or unwilling to move them, you must mount the `static` directory to the `assets` directory by including both of these entries in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[[module.mounts]]
+source = 'assets'
+target = 'assets'
+
+[[module.mounts]]
+source = 'static'
+target = 'assets'
+{{< /code-toggle >}}
+
+Note that the embedded image render hook does not perform image processing. Its sole purpose is to resolve Markdown image destinations.
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: Link render hooks
+linkTitle: Links
+description: Create a link render hook to override the rendering of Markdown links to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 70
+weight: 70
+toc: true
+---
+
+## Markdown
+
+A Markdown link has three components: the link text, the link destination, and optionally the link title.
+
+```text
+[Post 1](/posts/post-1 "My first post")
+ ------ ------------- -------------
+ text destination title
+```
+
+These components are passed into the render hook [context](g) as shown below.
+
+## Context
+
+Link render hook templates receive the following context:
+
+###### Destination
+
+(`string`) The link destination.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
- {{< new-in 0.123.0 >}}
++{{< new-in 0.125.0 />}}
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### PlainText
+
+(`string`) The link description as plain text.
+
+###### Text
+
+(`template.HTML`) The link description.
+
+###### Title
+
+(`string`) The link title.
+
+## Examples
+
+{{% note %}}
+With inline elements such as images and links, remove leading and trailing whitespace using the `{{‑ ‑}}` delimiter notation to prevent whitespace between adjacent inline elements and text.
+{{% /note %}}
+
+In its default configuration, Hugo renders Markdown links according to the [CommonMark specification]. To create a render hook that does the same thing:
+
+[CommonMark specification]: https://spec.commonmark.org/current/
+
+{{< code file=layouts/_default/_markup/render-link.html copy=true >}}
+<a href="{{ .Destination | safeURL }}"
+ {{- with .Title }} title="{{ . }}"{{ end -}}
+>
+ {{- with .Text }}{{ . }}{{ end -}}
+</a>
+{{- /* chomp trailing newline */ -}}
+{{< /code >}}
+
+To include a `rel` attribute set to `external` for external links:
+
+{{< code file=layouts/_default/_markup/render-link.html copy=true >}}
+{{- $u := urls.Parse .Destination -}}
+<a href="{{ .Destination | safeURL }}"
+ {{- with .Title }} title="{{ . }}"{{ end -}}
+ {{- if $u.IsAbs }} rel="external"{{ end -}}
+>
+ {{- with .Text }}{{ . }}{{ end -}}
+</a>
+{{- /* chomp trailing newline */ -}}
+{{< /code >}}
+
+## Default
+
++{{< new-in 0.123.0 />}}
+
+Hugo includes an [embedded link render hook] to resolve Markdown link destinations. Disabled by default, you can enable it in your site configuration:
+
+[embedded link render hook]: {{% eturl render-link %}}
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.renderHooks.link]
+enableDefault = true
+{{< /code-toggle >}}
+
+A custom render hook, even when provided by a theme or module, will override the embedded render hook regardless of the configuration setting above.
+
+{{% note %}}
+The embedded link render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites.
+
+[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles
+{{% /note %}}
+
+The embedded link render hook resolves internal Markdown destinations by looking for a matching page, falling back to a matching [page resource](g), then falling back to a matching [global resource](g). Remote destinations are passed through, and the render hook will not throw an error or warning if unable to resolve a destination.
+
+You must place global resources in the `assets` directory. If you have placed your resources in the `static` directory, and you are unable or unwilling to move them, you must mount the `static` directory to the `assets` directory by including both of these entries in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[[module.mounts]]
+source = 'assets'
+target = 'assets'
+
+[[module.mounts]]
+source = 'static'
+target = 'assets'
+{{< /code-toggle >}}
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.132.0 >}}
+---
+title: Passthrough render hooks
+linkTitle: Passthrough
+description: Create a passthrough render hook to override the rendering of text snippets captured by the Goldmark passthrough extension.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 80
+weight: 80
+toc: true
+---
+
++{{< new-in 0.132.0 />}}
+
+## Overview
+
+Hugo uses [Goldmark] to render Markdown to HTML. Goldmark supports custom extensions to extend its core functionality. The Goldmark [passthrough extension] captures and preserves raw Markdown within delimited snippets of text, including the delimiters themselves. These are known as _passthrough elements_.
+
+[Goldmark]: https://github.com/yuin/goldmark
+[passthrough extension]: /getting-started/configuration-markup/#passthrough
+
+Depending on your choice of delimiters, Hugo will classify a passthrough element as either _block_ or _inline_. Consider this contrived example:
+
+{{< code file=content/sample.md >}}
+This is a
+
+\[block\]
+
+passthrough element with opening and closing block delimiters.
+
+This is an \(inline\) passthrough element with opening and closing inline delimiters.
+{{< /code >}}
+
+Update your site configuration to enable the passthrough extension and define opening and closing delimiters for each passthrough element type, either `block` or `inline`. For example:
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.extensions.passthrough]
+enable = true
+[markup.goldmark.extensions.passthrough.delimiters]
+block = [['\[', '\]'], ['$$', '$$']]
+inline = [['\(', '\)']]
+{{< /code-toggle >}}
+
+In the example above there are two sets of `block` delimiters. You may use either one in your Markdown.
+
+The Goldmark passthrough extension is often used in conjunction with the MathJax or KaTeX display engine to render [mathematical expressions] written in the LaTeX markup language.
+
+[mathematical expressions]: /content-management/mathematics/
+
+To enable custom rendering of passthrough elements, create a passthrough render hook.
+
+## Context
+
+Passthrough render hook templates receive the following [context](g):
+
+###### Attributes
+
+(`map`) The [Markdown attributes], available if you configure your site as follows:
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser.attribute]
+block = true
+{{< /code-toggle >}}
+
+Hugo populates the `Attributes` map for _block_ passthrough elements. Markdown attributes are not applicable to _inline_ elements.
+
+###### Inner
+(`string`) The inner content of the passthrough element, excluding the delimiters.
+
+###### Ordinal
+
+(`int`) The zero-based ordinal of the passthrough element on the page.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### Position
+
+(`string`) The position of the passthrough element within the page content.
+
+###### Type
+
+(`string`) The passthrough element type, either `block` or `inline`.
+
+## Example
+
+Instead of client-side JavaScript rendering of mathematical markup using MathJax or KaTeX, create a passthrough render hook which calls the [`transform.ToMath`] function.
+
+[`transform.ToMath`]: /functions/transform/tomath/
+
+{{< code file=layouts/_default/_markup/render-passthrough.html copy=true >}}
+{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
+{{- with try (transform.ToMath .Inner $opts) }}
+ {{- with .Err }}
+ {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }}
+ {{- else }}
+ {{- .Value }}
+ {{- $.Page.Store.Set "hasMath" true }}
+ {{- end }}
+{{- end -}}
+{{< /code >}}
+
+Then, in your base template, conditionally include the KaTeX CSS within the head element:
+
+{{< code file=layouts/_default/baseof.html copy=true >}}
+<head>
+ {{ $noop := .WordCount }}
+ {{ if .Page.Store.Get "hasMath" }}
+ <link href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" rel="stylesheet">
+ {{ end }}
+</head>
+{{< /code >}}
+
+In the above, note the use of a [noop](g) statement to force content rendering before we check the value of `hasMath` with the `Store.Get` method.
+
+Although you can use one template with conditional logic as shown above, you can also create separate templates for each [`Type`](#type) of passthrough element:
+
+```text
+layouts/
+└── _default/
+ └── _markup/
+ ├── render-passthrough-block.html
+ └── render-passthrough-inline.html
+```
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- {{< new-in 0.134.0 >}}
+---
+title: Table render hooks
+linkTitle: Tables
+description: Create a table render hook to override the rendering of Markdown tables to HTML.
+categories: [render hooks]
+keywords: []
+menu:
+ docs:
+ parent: render-hooks
+ weight: 90
+weight: 90
+toc: true
+---
+
++{{< new-in 0.134.0 />}}
+
+## Context
+
+Table render hook templates receive the following [context](g):
+
+###### Attributes
+
+(`map`) The [Markdown attributes], available if you configure your site as follows:
+
+[Markdown attributes]: /content-management/markdown-attributes/
+
+{{< code-toggle file=hugo >}}
+[markup.goldmark.parser.attribute]
+block = true
+{{< /code-toggle >}}
+
+###### Ordinal
+
+(`int`) The zero-based ordinal of the table on the page.
+
+###### Page
+
+(`page`) A reference to the current page.
+
+###### PageInner
+
+(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
+
+[`RenderShortcodes`]: /methods/page/rendershortcodes
+
+###### Position
+
+(`string`) The position of the table within the page content.
+
+###### THead
+(`slice`) A slice of table header rows, where each element is a slice of table cells.
+
+###### TBody
+(`slice`) A slice of table body rows, where each element is a slice of table cells.
+
+## Table cells
+
+Each table cell within the slice of slices returned by the `THead` and `TBody` methods has the following fields:
+
+###### Alignment
+(`string`) The alignment of the text within the table cell, one of `left`, `center`, or `right`.
+
+###### Text
+(`template.HTML`) The text within the table cell.
+
+## Example
+
+In its default configuration, Hugo renders Markdown tables according to the [GitHub Flavored Markdown specification]. To create a render hook that does the same thing:
+
+[GitHub Flavored Markdown specification]: https://github.github.com/gfm/#tables-extension-
+
+{{< code file=layouts/_default/_markup/render-table.html copy=true >}}
+<table
+ {{- range $k, $v := .Attributes }}
+ {{- if $v }}
+ {{- printf " %s=%q" $k $v | safeHTMLAttr }}
+ {{- end }}
+ {{- end }}>
+ <thead>
+ {{- range .THead }}
+ <tr>
+ {{- range . }}
+ <th
+ {{- with .Alignment }}
+ {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
+ {{- end -}}
+ >
+ {{- .Text -}}
+ </th>
+ {{- end }}
+ </tr>
+ {{- end }}
+ </thead>
+ <tbody>
+ {{- range .TBody }}
+ <tr>
+ {{- range . }}
+ <td
+ {{- with .Alignment }}
+ {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
+ {{- end -}}
+ >
+ {{- .Text -}}
+ </td>
+ {{- end }}
+ </tr>
+ {{- end }}
+ </tbody>
+</table>
+{{< /code >}}
+
+{{% include "/render-hooks/_common/pageinner.md" %}}
--- /dev/null
- linkTitle: In this section
+---
+title: Shortcodes
++
+description: Insert elements such as videos, images, and social media embeds into your content using Hugo's embedded shortcodes.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: shortcodes-in-this-section
+ parent: shortcodes
+ weight: 10
+weight: 10
+showSectionMenu: true
+---
+
+Insert elements such as videos, images, and social media embeds into your content using Hugo's embedded shortcodes.
--- /dev/null
- expiryDate: 2025-01-22 # with v0.142.0 and later use HTML comments instead
+---
+title: Comment
+description: Include hidden comments in your content with the comment shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ identifier: shortcodes-comment
+ parent: shortcodes
+ weight:
+weight:
- {{< new-in "0.137.1" >}}
++expiryDate: 2025-01-22 # deprecated 2025-02-01 in v0.143.0 and immediately removed from the documentation
+---
+
+{{% note %}}
+To override Hugo's embedded `comment` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl comment %}}
+{{% /note %}}
+
++{{< new-in 0.137.1 />}}
+
+Use the `comment` shortcode to include comments in your content. Hugo will ignore the text within these comments when rendering your site.
+
+Use it inline:
+
+```text
+{{%/* comment */%}} rewrite the paragraph below {{%/* /comment */%}}
+```
+
+Or as a block comment:
+
+```text
+{{%/* comment */%}}
+rewrite the paragraph below
+{{%/* /comment */%}}
+```
+
+Although you can call this shortcode using the `{{</* */>}}` notation, computationally it is more efficient to call it using the `{{%/* */%}}` notation as shown above.
--- /dev/null
- {{< new-in 0.140.0 >}}
+---
+title: Details
+description: Insert an HTML details element into your content using the details shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+toc: true
+---
+
++{{< new-in 0.140.0 />}}
+
+{{% note %}}
+To override Hugo's embedded `details` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl details %}}
+{{% /note %}}
+
+## Example
+
+With this markup:
+
+```text
+{{</* details summary="See the details" */>}}
+This is a **bold** word.
+{{</* /details */>}}
+```
+
+Hugo renders this HTML:
+
+```html
+<details>
+ <summary>See the details</summary>
+ <p>This is a <strong>bold</strong> word.</p>
+</details>
+```
+
+Which looks like this in your browser:
+
+{{< details summary="See the details" >}}
+This is a **bold** word.
+{{< /details >}}
+
+## Parameters
+
+summary
+: (`string`) The content of the child `summary` element rendered from Markdown to HTML. Default is `Details`.
+
+open
+: (`bool`) Whether to initially display the content of the `details` element. Default is `false`.
+
+class
+: (`string`) The `class` attribute of the `details` element.
+
+name
+: (`string`) The `name` attribute of the `details` element.
+
+title
+: (`string`) The `title` attribute of the `details` element.
+
+## Styling
+
+Use CSS to style the `details` element, the `summary` element, and the content itself.
+
+```css
+/* target the details element */
+details { }
+
+/* target the summary element */
+details > summary { }
+
+/* target the children of the summary element */
+details > summary > * { }
+
+/* target the content */
+details > :not(summary) { }
+```
--- /dev/null
- {{% note %}}
- To override Hugo's embedded `gist` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+---
+title: Gist
+description: Embed a GitHub Gist in your content using the gist shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
++expiryDate: 2027-02-01 # deprecated 2025-02-01 in v0.143.0
+---
+
- [source code]: {{% eturl gist %}}
- {{% /note %}}
++{{% deprecated-in 0.143.0 %}}
++The `gist` shortcode was deprecated in version 0.143.0 and will be removed in a future release. To continue embedding GitHub Gists in your content, you'll need to create a custom shortcode:
+
- This will display all files in the gist alphabetically by file name.
-
- {{< gist jmooring 23932424365401ffa5e9d9810102a477 >}}
-
++1. Create a new file: Create a file named `gist.html` within the `layouts/shortcodes` directory.
++2. Copy the source code: Paste the [original source code] of the gist shortcode into the newly created `gist.html` file.
++
++This will allow you to maintain the functionality of embedding GitHub Gists in your content after the deprecation of the original shortcode.
++
++[original source code]: {{% eturl gist %}}
++{{% /deprecated-in %}}
+
+To display a GitHub gist with this URL:
+
+```text
+https://gist.github.com/user/50a7482715eac222e230d1e64dd9a89b
+```
+
+Include this in your Markdown:
+
+```text
+{{</* gist user 23932424365401ffa5e9d9810102a477 */>}}
+```
+
-
- {{< gist jmooring 23932424365401ffa5e9d9810102a477 list.html >}}
+To display a specific file within the gist:
+
+```text
+{{</* gist user 23932424365401ffa5e9d9810102a477 list.html */>}}
+```
--- /dev/null
- We found a {{</* param "color" */>}} shirt.
+---
+title: Param
+description: Insert a parameter from front matter or site configuration into your content using the param shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+---
+
+{{% note %}}
+To override Hugo's embedded `param` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl param %}}
+{{% /note %}}
+
+The `param` shortcode renders a parameter from front matter, falling back to a site parameter of the same name. The shortcode throws an error if the parameter does not exist.
+
+{{< code file=example.md lang=text >}}
+---
+title: Example
+date: 2025-01-15T23:29:46-08:00
+params:
+ color: red
+ size: medium
+---
+
- {{</* param my.nested.param */>}}
++We found a {{%/* param "color" */%}} shirt.
+{{< /code >}}
+
+Hugo renders this to:
+
+```html
+<p>We found a red shirt.</p>
+```
+
+Access nested values by [chaining](g) the [identifiers](g):
+
+```text
++{{%/* param my.nested.param */%}}
+```
--- /dev/null
- {{< new-in 0.141.0 >}}
+---
+title: QR
+description: Insert a QR code into your content using the qr shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+toc: true
+---
+
- {{< qr text="https://gohugo.io" class="qrcode" />}}
++{{< new-in 0.141.0 />}}
+
+{{% note %}}
+To override Hugo's embedded `qr` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl qr %}}
+{{% /note %}}
+
+The `qr` shortcode encodes the given text into a [QR code] using the specified options and renders the resulting image.
+
+Internally this shortcode calls the `images.QR` function. Please read the [related documentation] for implementation details and guidance.
+
+[QR code]: https://en.wikipedia.org/wiki/QR_code
+[related documentation]: /functions/images/qr/
+
+## Examples
+
+Use the self-closing syntax to pass the text as an argument:
+
+```text
+{{</* qr text="https://gohugo.io" /*/>}}
+```
+
+Or insert the text between the opening and closing tags:
+
+```text
+{{</* qr */>}}
+https://gohugo.io
+{{</* /qr */>}}
+```
+
+Both of the above produce this image:
+
- {{< qr text="tel:+12065550101" class="qrcode" />}}
++{{< qr text="https://gohugo.io" class="qrcode" targetDir="images/qr" />}}
+
+To create a QR code for a phone number:
+
+```text
+{{</* qr text="tel:+12065550101" /*/>}}
+```
+
- {{< qr level="low" scale=2 alt="QR code of vCard for John Smith" class="qrcode" >}}
++{{< qr text="tel:+12065550101" class="qrcode" targetDir="images/qr" />}}
+
+To create a QR code containing contact information in the [vCard] format:
+
+[vCard]: https://en.wikipedia.org/wiki/VCard
+
+```text
+{{</* qr level="low" scale=2 alt="QR code of vCard for John Smith" */>}}
+BEGIN:VCARD
+VERSION:2.1
+N;CHARSET=UTF-8:Smith;John;R.;Dr.;PhD
+FN;CHARSET=UTF-8:Dr. John R. Smith, PhD.
+ORG;CHARSET=UTF-8:ABC Widgets
+TITLE;CHARSET=UTF-8:Vice President Engineering
+TEL;TYPE=WORK:+12065550101
+EMAIL;TYPE=WORK:jsmith@example.org
+END:VCARD
+{{</* /qr */>}}
+```
+
++{{< qr level="low" scale=2 alt="QR code of vCard for John Smith" class="qrcode" targetDir="images/qr" >}}
+BEGIN:VCARD
+VERSION:2.1
+N;CHARSET=UTF-8:Smith;John;R.;Dr.;PhD
+FN;CHARSET=UTF-8:Dr. John R. Smith, PhD.
+ORG;CHARSET=UTF-8:ABC Widgets
+TITLE;CHARSET=UTF-8:Vice President Engineering
+TEL;TYPE=WORK:+12065550101
+EMAIL;TYPE=WORK:jsmith@example.org
+END:VCARD
+{{< /qr >}}
+
+## Parameters
+
+text
+: (`string`) The text to encode, falling back to the text between the opening and closing shortcode tags.
+
+level
+: (`string`) The error correction level to use when encoding the text, one of `low`, `medium`, `quartile`, or `high`. Default is `medium`.
+
+scale
+: (`int`) The number of image pixels per QR code module. Must be greater than or equal to 2. Default is `4`.
+
+targetDir
+: (`string`) The subdirectory within the [`publishDir`] where Hugo will place the generated image.
+
+[`publishDir`]: /getting-started/configuration/#publishdir
+
+alt
+: (`string`) The `alt` attribute of the `img` element.
+
+class
+: (`string`) The `class` attribute of the `img` element.
+
+id
+: (`string`) The `id` attribute of the `img` element.
+
+title
+: (`string`) The `title` attribute of the `img` element.
--- /dev/null
- If you proivde a `class` or `title` you must use a named parameter for the `id`.
+---
+title: Vimeo
+description: Embed a Vimeo video in your content using the vimeo shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+toc: true
+---
+
+{{% note %}}
+To override Hugo's embedded `vimeo` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl vimeo %}}
+{{% /note %}}
+
+## Example
+
+To display a Vimeo video with this URL:
+
+```text
+https://vimeo.com/channels/staffpicks/55073825
+```
+
+Include this in your Markdown:
+
+```text
+{{</* vimeo 55073825 */>}}
+```
+
+Hugo renders this to:
+
+{{< vimeo 55073825 >}}
+
+## Parameters
+
+class
+: (`string`) The `class` attribute of the wrapping `div` element. Adding one or more CSS classes disables inline styling.
+
+id
+: (`string`) The `id` of the Vimeo video
+
+title
+: (`string`) The `title` attribute of the `iframe` element.
+
++If you provide a `class` or `title` you must use a named parameter for the `id`.
+
+```text
+{{</* vimeo id=55073825 class="foo bar" title="My Video" */>}}
+```
+
+## Privacy
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.vimeo />}}
+
+disable
+: (`bool`) Whether to disable the shortcode. Default is `false`.
+
+enableDNT
+: (`bool`) Whether to block the Vimeo player from tracking session data and analytics. Default is `false`.
+
+simple
+: (`bool`) Whether to enable simple mode. If `true`, the video thumbnail is fetched from Vimeo and overlaid with a play button. Clicking the thumbnail opens the video in a new Vimeo tab. Default is `false`.
+
+The source code for the simple version of the shortcode is available [here].
+
+[here]: {{% eturl vimeo_simple %}}
--- /dev/null
- {{< new-in 0.141.0 >}}
+---
+title: X
+description: Embed an X post in your content using the x shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+toc: true
+---
+
++{{< new-in 0.141.0 />}}
+
+{{% note %}}
+To override Hugo's embedded `x` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl x %}}
+{{% /note %}}
+
+## Example
+
+To display an X post with this URL:
+
+```txt
+https://x.com/SanDiegoZoo/status/1453110110599868418
+```
+
+Include this in your Markdown:
+
+```text
+{{</* x user="SanDiegoZoo" id="1453110110599868418" */>}}
+```
+
+Rendered:
+
+{{< x user="SanDiegoZoo" id="1453110110599868418" >}}
+
+## Privacy
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.x />}}
+
+disable
+: (`bool`) Whether to disable the shortcode. Default is `false`.
+
+enableDNT
+: (`bool`) Whether to prevent X from using post and embedded page data for personalized suggestions and ads. Default is `false`.
+
+simple
+: (`bool`) Whether to enable simple mode. If `true`, Hugo builds a static version of the of the post without JavaScript. Default is `false`.
+
+The source code for the simple version of the shortcode is available [here].
+
+[here]: {{% eturl x_simple %}}
+
+If you enable simple mode you may want to disable the hardcoded inline styles by setting `disableInlineCSS` to `true` in your site configuration. The default value for this setting is `false`.
+
+{{< code-toggle config=services.x />}}
--- /dev/null
- {{< new-in 0.125.0 >}}
+---
+title: YouTube
+description: Embed a YouTube video in your content using the youtube shortcode.
+categories: [shortcodes]
+keywords: []
+menu:
+ docs:
+ parent: shortcodes
+ weight:
+weight:
+toc: true
+---
+
+{{% note %}}
+To override Hugo's embedded `youtube` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+[source code]: {{% eturl youtube %}}
+{{% /note %}}
+
+## Example
+
+To display a YouTube video with this URL:
+
+```text
+https://www.youtube.com/watch?v=0RKpf3rK57I
+```
+
+Include this in your Markdown:
+
+```text
+{{</* youtube 0RKpf3rK57I */>}}
+```
+
+Hugo renders this to:
+
+{{< youtube 0RKpf3rK57I >}}
+
+## Parameters
+
+id
+: (`string`) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above.
+
+allowFullScreen
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`bool`) Whether the `iframe` element can activate full screen mode. Default is `true`.
+
+autoplay
- {{< new-in 0.125.0 >}}
++ {{< new-in 0.125.0 />}}
+: (`bool`) Whether to automatically play the video. Forces `mute` to `true`. Default is `false`.
+
+class
+: (`string`) The `class` attribute of the wrapping `div` element. When specified, removes the `style` attributes from the `iframe` element and its wrapping `div` element.
+
+controls
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`bool`) Whether to display the video controls. Default is `true`.
+
+end
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`int`) The time, measured in seconds from the start of the video, when the player should stop playing the video.
+
+loading
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`string`) The loading attribute of the `iframe` element, either `eager` or `lazy`. Default is `eager`.
+
+loop
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`bool`) Whether to indefinitely repeat the video. Ignores the `start` and `end` arguments after the first play. Default is `false`.
+
+mute
- {{< new-in 0.125.0 >}}
++{{< new-in 0.125.0 />}}
+: (`bool`) Whether to mute the video. Always `true` when `autoplay` is `true`. Default is `false`.
+
+start
++{{< new-in 0.125.0 />}}
+: (`int`) The time, measured in seconds from the start of the video, when the player should start playing the video.
+
+title
+: (`string`) The `title` attribute of the `iframe` element. Defaults to "YouTube video".
+
+Example using some of the above:
+
+```text
+{{</* youtube id=0RKpf3rK57I start=30 end=60 loading=lazy */>}}
+```
+
+## Privacy
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.youTube />}}
+
+disable
+: (`bool`) Whether to disable the shortcode. Default is `false`.
+
+privacyEnhanced
+: (`bool`) Whether to block YouTube from storing information about visitors on your website unless the user plays the embedded video. Default is `false`.
--- /dev/null
- Amazon CloudFront|See [details](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GeneratingCustomErrorResponses.html).
- Amazon S3|See [details](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CustomErrorDocSupport.html).
- Apache|See [details](https://httpd.apache.org/docs/2.4/custom-error.html).
- Azure Static Web Apps|See [details](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#response-overrides).
- Azure Storage|See [details](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website#setting-up-a-static-website).
- Caddy|See [details](https://caddyserver.com/docs/caddyfile/directives/handle_errors).
- Cloudflare Pages|See [details](https://developers.cloudflare.com/pages/configuration/serving-pages/#not-found-behavior).
- DigitalOcean App Platform|See [details](https://docs.digitalocean.com/products/app-platform/how-to/manage-static-sites/#configure-a-static-site).
- Firebase|See [details](https://firebase.google.com/docs/hosting/full-config#404).
+---
+title: Custom 404 page
+linkTitle: 404 templates
+description: Create a template to render a 404 error page.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 160
+weight: 160
+---
+
+To render a 404 error page in the root of your site, create a 404 template in the root of the `layouts` directory. For example:
+
+{{< code file=layouts/404.html >}}
+{{ define "main" }}
+ <h1>404 Not Found</h1>
+ <p>The page you requested cannot be found.</p>
+ <p>
+ <a href="{{ .Site.Home.RelPermalink }}">
+ Return to the home page
+ </a>
+ </p>
+{{ end }}
+{{< /code >}}
+
+For multilingual sites, add the language key to the file name:
+
+```text
+layouts/
+├── 404.de.html
+├── 404.en.html
+└── 404.fr.html
+```
+
+Your production server redirects the browser to the 404 page when a page is not found. Capabilities and configuration vary by host.
+
+Host|Capabilities and configuration
+:--|:--
- GitLab Pages|See [details](https://docs.gitlab.com/ee/user/project/pages/introduction.html#custom-error-codes-pages).
- NGINX|See [details](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page).
- Netlify|See [details](https://docs.netlify.com/routing/redirects/redirect-options/).
++Amazon CloudFront|See [details](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GeneratingCustomErrorResponses.html).
++Amazon S3|See [details](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CustomErrorDocSupport.html).
++Apache|See [details](https://httpd.apache.org/docs/2.4/custom-error.html).
++Azure Static Web Apps|See [details](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#response-overrides).
++Azure Storage|See [details](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website#setting-up-a-static-website).
++Caddy|See [details](https://caddyserver.com/docs/caddyfile/directives/handle_errors).
++Cloudflare Pages|See [details](https://developers.cloudflare.com/pages/configuration/serving-pages/#not-found-behavior).
++DigitalOcean App Platform|See [details](https://docs.digitalocean.com/products/app-platform/how-to/manage-static-sites/#configure-a-static-site).
++Firebase|See [details](https://firebase.google.com/docs/hosting/full-config#404).
+GitHub Pages|Redirection to is automatic and not configurable.
++GitLab Pages|See [details](https://docs.gitlab.com/ee/user/project/pages/introduction.html#custom-error-codes-pages).
++NGINX|See [details](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page).
++Netlify|See [details](https://docs.netlify.com/routing/redirects/redirect-options/).
--- /dev/null
- linkTitle: In this section
- description: Go templating, template types and lookup order, shortcodes, and data.
+---
+title: Templates
++
++description: Create templates to render your content, resources, and data.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: templates-in-this-section
+ parent: templates
+ weight: 10
+weight: 10
+aliases: [/templates/overview/,/templates/content]
+---
+
+A template is an HTML file with [template actions](g), located within the `layouts` directory of a project, theme, or module. Visit the topics below, in the order presented, to understand template selection and creation.
--- /dev/null
- ### Configure Disqus
+---
+title: Embedded templates
+description: Hugo provides embedded templates for common use cases.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 200
+weight: 200
+toc: true
+aliases: [/templates/internal]
+---
+
+## Disqus
+
+{{% note %}}
+To override Hugo's embedded Disqus template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+
+`{{ partial "disqus.html" . }}`
+
+[`partial`]: /functions/partials/include/
+[source code]: {{% eturl disqus %}}
+{{% /note %}}
+
+Hugo includes an embedded template for [Disqus], a popular commenting system for both static and dynamic websites. To effectively use Disqus, secure a Disqus "shortname" by [signing up] for the free service.
+
+[Disqus]: https://disqus.com
+[signing up]: https://disqus.com/profile/signup/
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/disqus.html" . }}
+```
+
- ### Configure Google Analytics
++### Configuration {#configuration-disqus}
+
+To use Hugo's Disqus template, first set up a single configuration value:
+
+{{< code-toggle file="hugo" >}}
+[services.disqus]
+shortname = 'your-disqus-shortname'
+{{</ code-toggle >}}
+
+Hugo's Disqus template accesses this value with:
+
+```go-html-template
+{{ .Site.Config.Services.Disqus.Shortname }}
+```
+
+You can also set the following in the front matter for a given piece of content:
+
+- `disqus_identifier`
+- `disqus_title`
+- `disqus_url`
+
++### Privacy {#privacy-disqus}
++
++Adjust the relevant privacy settings in your site configuration.
++
++{{< code-toggle config=privacy.disqus />}}
++
++disable
++: (`bool`) Whether to disable the template. Default is `false`.
++
+## Google Analytics
+
+{{% note %}}
+To override Hugo's embedded Google Analytics template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+
+`{{ partial "google_analytics.html" . }}`
+
+[`partial`]: /functions/partials/include/
+[source code]: {{% eturl google_analytics %}}
+{{% /note %}}
+
+Hugo includes an embedded template supporting [Google Analytics 4].
+
+[Google Analytics 4]: https://support.google.com/analytics/answer/10089681
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/google_analytics.html" . }}
+```
+
- ### Configure Open Graph
++### Configuration {#configuration-google-analytics}
+
+Provide your tracking ID in your configuration file:
+
+{{< code-toggle file=hugo >}}
+[services.googleAnalytics]
+id = "G-MEASUREMENT_ID"
+{{</ code-toggle >}}
+
+To use this value in your own template, access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`.
+
++### Privacy {#privacy-google-analytics}
++
++Adjust the relevant privacy settings in your site configuration.
++
++{{< code-toggle config=privacy.googleAnalytics />}}
++
++disable
++: (`bool`) Whether to disable the template. Default is `false`.
++
++respectDoNotTrack
++: (`bool`) Whether to respect the browser's "do not track" setting. Default is `false`.
++
+## Open Graph
+
+{{% note %}}
+To override Hugo's embedded Open Graph template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+
+`{{ partial "opengraph.html" . }}`
+
+[`partial`]: /functions/partials/include/
+[source code]: {{% eturl opengraph %}}
+{{% /note %}}
+
+Hugo includes an embedded template for the [Open Graph protocol](https://ogp.me/), metadata that enables a page to become a rich object in a social graph.
+This format is used for Facebook and some other sites.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/opengraph.html" . }}
+```
+
- ### Configure X (Twitter) Cards
++### Configuration {#configuration-open-graph}
+
+Hugo's Open Graph template is configured using a mix of configuration settings and [front matter](/content-management/front-matter/) on individual pages.
+
+{{< code-toggle file=hugo >}}
+[params]
+ description = 'Text about my cool site'
+ images = ['site-feature-image.jpg']
+ title = 'My cool site'
+ [params.social]
+ facebook_admin = 'jsmith'
+[taxonomies]
+ series = 'series'
+{{</ code-toggle >}}
+
+{{< code-toggle file=content/blog/my-post.md fm=true >}}
+title = "Post title"
+description = "Text about this post"
+date = 2024-03-08T08:18:11-08:00
+images = ["post-cover.png"]
+audio = []
+videos = []
+series = []
+tags = []
+{{</ code-toggle >}}
+
+Hugo uses the page title and description for the title and description metadata.
+The first 6 URLs from the `images` array are used for image metadata.
+If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
+
+Various optional metadata can also be set:
+
+- Date, published date, and last modified data are used to set the published time metadata if specified.
+- `audio` and `videos` are URL arrays like `images` for the audio and video metadata tags, respectively.
+- The first 6 `tags` on the page are used for the tags metadata.
+- The `series` taxonomy is used to specify related "see also" pages by placing them in the same series.
+
+If using YouTube this will produce a og:video tag like `<meta property="og:video" content="url">`. Use the `https://youtu.be/<id>` format with YouTube videos (example: `https://youtu.be/qtIqKaDlqXo`).
+
+## Schema
+
+{{% note %}}
+To override Hugo's embedded Schema template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+
+`{{ partial "schema.html" . }}`
+
+[`partial`]: /functions/partials/include/
+[source code]: {{% eturl schema %}}
+{{% /note %}}
+
+Hugo includes an embedded template to render [microdata] `meta` elements within the `head` element of your templates.
+
+[microdata]: https://html.spec.whatwg.org/multipage/microdata.html#microdata
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/schema.html" . }}
+```
+
+## X (Twitter) Cards
+
+{{% note %}}
+To override Hugo's embedded Twitter Cards template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+
+`{{ partial "twitter_cards.html" . }}`
+
+[`partial`]: /functions/partials/include/
+[source code]: {{% eturl twitter_cards %}}
+{{% /note %}}
+
+Hugo includes an embedded template for [X (Twitter) Cards](https://developer.x.com/en/docs/twitter-for-websites/cards/overview/abouts-cards),
+metadata used to attach rich media to Tweets linking to your site.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/twitter_cards.html" . }}
+```
+
++### Configuration {#configuration-x-cards}
+
+Hugo's X (Twitter) Card template is configured using a mix of configuration settings and [front-matter](/content-management/front-matter/) values on individual pages.
+
+{{< code-toggle file=hugo >}}
+[params]
+ images = ["site-feature-image.jpg"]
+ description = "Text about my cool site"
+{{</ code-toggle >}}
+
+{{< code-toggle file=content/blog/my-post.md >}}
+title = "Post title"
+description = "Text about this post"
+images = ["post-cover.png"]
+{{</ code-toggle >}}
+
+If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
+If no image resources with those names are found, the images defined in the [site config](/getting-started/configuration/) are used instead.
+If no images are found at all, then an image-less Twitter `summary` card is used instead of `summary_large_image`.
+
+Hugo uses the page title and description for the card's title and description fields. The page summary is used if no description is given.
+
+Set the value of `twitter:site` in your site configuration:
+
+{{< code-toggle file="hugo" copy=false >}}
+[params.social]
+twitter = "GoHugoIO"
+{{</ code-toggle >}}
+
+NOTE: The `@` will be added for you
+
+```html
+<meta name="twitter:site" content="@GoHugoIO"/>
+```
--- /dev/null
- title: Home templates
+---
- The home template is the *only* required template for building a site and therefore useful when bootstrapping a new site and template. It is also the only required template if you are developing a single-page website.
++title: Home page templates
+description: The home page of a website is often formatted differently than the other pages. For this reason, Hugo makes it easy for you to define your new site's home page as a unique template.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 60
+weight: 60
+toc: true
+aliases: [/layout/homepage/,/templates/homepage-template/,/templates/homepage/]
+---
+
- {{< youtube ut1xtRZ1QOA >}}
++## Introduction
+
- ## Home template lookup order
++A home page template is used to render your site's home page, and is the only template required for a single-page website. For example, the home page template below inherits the site's shell from the base template and renders the home page content, such as a list of other pages.
+
- See [Template Lookup](/templates/lookup-order/).
++{{< code file=layouts/_default/home.html >}}
++{{ define "main" }}
++ {{ .Content }}
++ {{ range site.RegularPages }}
++ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
++ {{ end }}
++{{ end }}
++{{< /code >}}
++
++{{% include "templates/_common/filter-sort-group.md" %}}
++
++## Lookup order
+
- ## Add content and front matter to the home page
++Hugo's [template lookup order] determines the template path, allowing you to create unique templates for any page.
+
- The home page accepts content and front matter from an `_index.md` file. This file should live at the root of your `content` directory (i.e., `content/_index.md`). You can then add body copy and metadata to your home page the way you would any other content file.
++[template lookup order]: /templates/lookup-order/#home-templates
+
- See the home template below or [Content Organization][contentorg] for more information on the role of `_index.md` in adding content and front matter to list pages.
++{{% note %}}
++You must have thorough understanding of the template lookup order when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format.
++{{% /note %}}
+
- ## Example home template
++## Content and front matter
+
- <main aria-role="main">
- <header class="home-page-header">
- <h1>{{ .Title }}</h1>
- {{ with .Params.subtitle }}
- <span class="subtitle">{{ . }}</span>
- {{ end }}
- </header>
- <div class="home-page-content">
- <!-- Note that the content for index.html, as a sort of list page, will pull from content/_index.md -->
- {{ .Content }}
- </div>
- <div>
- {{ range first 10 .Site.RegularPages }}
- {{ .Render "summary" }}
- {{ end }}
- </div>
- </main>
++The home page template uses content and front matter from an `_index.md` file located in the root of your content directory.
++
++{{< code-toggle file=content/_index.md fm=true >}}
++---
++title: The Home Page
++date: 2025-01-30T03:36:57-08:00
++draft: false
++params:
++ subtitle: The Subtitle
++---
++{{< /code-toggle >}}
++
++The home page template below inherits the site's shell from the base template, renders the subtitle and content as defined in the `_index.md` file, then renders of list of the site's [regular pages](g).
+
+{{< code file=layouts/_default/home.html >}}
+{{ define "main" }}
-
- [contentorg]: /content-management/organization/
- [lookup]: /templates/lookup-order/
++ <h3>{{ .Params.Subtitle }}</h3>
++ {{ .Content }}
++ {{ range site.RegularPages }}
++ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
++ {{ end }}
+{{ end }}
+{{< /code >}}
--- /dev/null
- **Note:**
+---
+title: Custom output formats
+description: Hugo can output content in multiple formats, including calendar events, e-book formats, Google AMP, and JSON search indexes, or any custom text format.
+categories: [templates,fundamentals]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 210
+weight: 210
+toc: true
+aliases: [/templates/outputs/,/extras/output-formats/,/content-management/custom-outputs/]
+---
+
+This page describes how to properly configure your site with the media types and output formats, as well as where to create your templates for your custom outputs.
+
+## Media types
+
+A [media type] (formerly known as a MIME type) is a two-part identifier for file formats and format contents transmitted on the internet.
+
+This is the full set of built-in media types in Hugo:
+
+{{< datatable "config" "mediaTypes" "_key" "suffixes" >}}
+
- **Note:** these media types are configured for **your output formats**. If you want to redefine one of Hugo's default output formats (e.g. `HTML`), you also need to redefine the media type. So, if you want to change the suffix of the `HTML` output format from `html` (default) to `htm`:
++Notes:
+
+- It is possible to add custom media types or change the defaults; e.g., if you want to change the suffix for `text/html` to `asp`.
+- `Suffixes` are the values that will be used for URLs and file names for that media type in Hugo.
+- The `Type` is the identifier that must be used when defining new/custom `Output Formats` (see below).
+- The full set of media types will be registered in Hugo's built-in development server to make sure they are recognized by the browser.
+
+To add or modify a media type, define it in a `mediaTypes` section in your [site configuration], either for all sites or for a given language.
+
+{{< code-toggle file=hugo >}}
+[mediaTypes]
+ [mediaTypes."text/enriched"]
+ suffixes = ["enr"]
+ [mediaTypes."text/html"]
+ suffixes = ["asp"]
+{{</ code-toggle >}}
+
+The above example adds one new media type, `text/enriched`, and changes the suffix for the built-in `text/html` media type.
+
- - A page can be output in as many output formats as you want, and you can have an infinite amount of output formats defined **as long as they resolve to a unique path on the file system**. In the above table, the best example of this is `amp` vs. `html`. `amp` has the value `amp` for `path` so it doesn't overwrite the `html` version; e.g. we can now have both `/index.html` and `/amp/index.html`.
++These media types are configured for your output formats. If you want to redefine one of Hugo's default output formats, you also need to redefine the media type. So, if you want to change the suffix of the `HTML` output format from `html` (default) to `htm`:
+
+{{< code-toggle file=hugo >}}
+[mediaTypes]
+ [mediaTypes."text/html"]
+ suffixes = ["htm"]
+
+[outputFormats]
+ [outputFormats.html]
+ mediaType = "text/html"
+{{</ code-toggle >}}
+
+{{% note %}}
+For the above to work, you also need to add an `outputs` definition in your site configuration.
+{{% /note %}}
+
+## Output format definitions
+
+Given a media type and some additional configuration, you get an **Output Format**.
+
+This is the full set of Hugo's built-in output formats:
+
+{{< datatable "config" "outputFormats" "_key" "baseName" "isHTML" "isPlainText" "mediaType" "noUgly" "path" "permalinkable" "protocol" "rel" >}}
+
- : (`bool`) If `true`, classifies the output format as HTML. Hugo uses this value to determine when to create alias redirects, when to inject the LiveReload script, etc. Default is `false`.
++- A page can be output in as many output formats as you want, and you can have an infinite amount of output formats defined as long as they resolve to a unique path on the file system. In the above table, the best example of this is `amp` vs. `html`. `amp` has the value `amp` for `path` so it doesn't overwrite the `html` version; e.g. we can now have both `/index.html` and `/amp/index.html`.
++
+- The `mediaType` must match a defined media type.
+- You can define new output formats or redefine built-in output formats; e.g., if you want to put `amp` pages in a different path.
+
+To add or modify an output format, define it in an `outputFormats` section in your site's [configuration file](/getting-started/configuration/), either for all sites or for a given language.
+
+{{< code-toggle file=hugo >}}
+[outputFormats.MyEnrichedFormat]
+mediaType = "text/enriched"
+baseName = "myindex"
+isPlainText = true
+protocol = "bep://"
+{{</ code-toggle >}}
+
+The above example is fictional, but if used for the home page on a site with `baseURL` `https://example.org`, it will produce a plain text home page with the URL `bep://example.org/myindex.enr`.
+
+### Configure output formats
+
+Use these parameters when configuring an output format:
+
+baseName
+: (`string`) The base name of the published file. Default is `index`.
+
+isHTML
- : (`bool`) If `true`, Hugo parses templates for this output format with Go's [text/template] package instead of the [html/template] package. Default is `false`.
++: (`bool`) Whether to classify the output format as HTML. Hugo uses this value to determine when to create alias redirects, when to inject the LiveReload script, etc. Default is `false`.
+
+isPlainText
- : (`bool`) If `true`, excludes this output format from the values returned by the [`AlternativeOutputFormats`] method on a `Page` object. Default is `false`.
++: (`bool`) Whether to parse templates for this output format with Go's [text/template] package instead of the [html/template] package. Default is `false`.
+
+[html/template]: https://pkg.go.dev/html/template
+[text/template]: https://pkg.go.dev/text/template
+
+mediaType
+: (`string`) The [media type] of the published file. This must match a defined media type, either [built-in](#media-types) or custom.
+
+[media type]: https://en.wikipedia.org/wiki/Media_type
+
+notAlternative
- : (`bool`) If `true`, disables ugly URLs for this output format when `uglyURLs` is `true` in your site configuration. Default is `false`.
++: (`bool`) Whether to exclude this output format from the values returned by the [`AlternativeOutputFormats`] method on a `Page` object. Default is `false`.
+
+[`AlternativeOutputFormats`]: /methods/page/alternativeoutputformats/
+
+noUgly
- : (`bool`) If `true`, files will be published to the root of the publish directory. Default is `false`.
++: (`bool`) Whether to disable ugly URLs for this output format when `uglyURLs` is `true` in your site configuration. Default is `false`.
+
+path
+: (`string`) The path to the directory containing the published files, relative to the root of the publish directory.
+
+permalinkable
+: (`bool`) If `true`, the [`Permalink`] and [`RelPermalink`] methods on a `Page` object return the rendering output format rather than main output format ([see below](#link-to-output-formats)). Enabled by default for the `html` and `amp` output formats. Default is `false`.
+
+[`Permalink`]: /methods/page/permalink/
+[`RelPermalink`]: /methods/page/relpermalink/
+
+protocol
+: (`string`) The protocol (scheme) of the URL for this output format. For example, `https://` or `webcal://`. Default is the scheme of the `baseURL` parameter in your site configuration, typically `https://`.
+
+rel
+: (`string`) If provided, you can assign this value to `rel` attributes in `link` elements when iterating over output formats in your templates. Default is `alternate`.
+
+root
- : (`bool`) If `true`, enables uglyURLs for this output format when `uglyURLs` is `false` in your site configuration. Default is `false`.
++: (`bool`) Whether to publish files to the root of the publish directory. Default is `false`.
+
+ugly
- Note that in the above examples, the _output formats_ for `section`,
++: (`bool`) Whether to enable uglyURLs for this output format when `uglyURLs` is `false` in your site configuration. Default is `false`.
+
+weight
+: (`int`) When set to a non-zero value, Hugo uses the `weight` as the first criteria when sorting output formats, falling back to the name of the output format. Lighter items float to the top, while heavier items sink to the bottom. Hugo renders output formats sequentially based on the sort order.
+
+## Output formats for pages
+
+A `Page` in Hugo can be rendered to multiple _output formats_ on the file
+system.
+
+### Default output formats
+
+Every `Page` has a [`Kind`] attribute, and the default Output
+Formats are set based on that.
+
+{{< code-toggle config=outputs />}}
+
+### Customizing output formats
+
+This can be changed by defining an `outputs` list of output formats in either
+the `Page` front matter or in the site configuration (either for all sites or
+per language).
+
+Example from site configuration file:
+
+{{< code-toggle file=hugo >}}
+[outputs]
+ home = ["html", "amp", "rss"]
+ page = ["html"]
+{{</ code-toggle >}}
+
- * The `outputs` definition is per page [`Kind`].
- * The names (e.g. `html`, `amp`) must match the `name` of a defined output format, and can be overridden per page in front matter.
++Note that in the examples above, the output formats for `section`,
+`taxonomy` and `term` will stay at their default value `['html','rss']`.
+
- __from `single.json.json`:__
++- The `outputs` definition is per page [`Kind`].
++- The names (e.g. `html`, `amp`) must match the `name` of a defined output format, and can be overridden per page in front matter.
+
+The following is an example of front matter in a content file that defines output formats for the rendered `Page`:
+
+{{< code-toggle file=content/example.md fm=true >}}
+title: Example
+outputs:
+- html
+- amp
+- json
+{{< /code-toggle >}}
+
+## List output formats
+
+Each `Page` object has both an [`OutputFormats`] method (all formats, including the current) and an [`AlternativeOutputFormats`] method, the latter of which is useful for creating a `link rel` list in your site's `<head>`:
+
+[`OutputFormats`]: /methods/page/outputformats
+[`AlternativeOutputFormats`]: /methods/page/alternativeoutputformats
+
+```go-html-template
+{{ range .AlternativeOutputFormats -}}
+ <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
+{{ end }}
+```
+
+## Link to output formats
+
+The [`Permalink`] and [`RelPermalink`] methods on a `Page` object return the first output format defined for that page (usually `HTML` if nothing else is defined). This is regardless of the template from which they are called.
+
+[`Permalink`]: /methods/page/permalink
+[`RelPermalink`]: /methods/page/relpermalink
+
- **Same template file as above with json output format's `permalinkable` set to true:**
++From `single.json.json`:
++
+```go-html-template
+{{ .RelPermalink }} → /that-page/
+{{ with .OutputFormats.Get "json" }}
+ {{ .RelPermalink }} → /that-page/index.json
+{{ end }}
+```
+
+In order for them to return the output format of the current template file instead, the given output format should have its `permalinkable` setting set to true.
+
- From content files, you can use the `ref` or `relref` shortcodes:
-
- ```go-html-template
- [Neat]({{</* ref "blog/neat.md" "amp" */>}})
- [Who]({{</* relref "about.md#who" "amp" */>}})
- ```
-
- ## Templates for your output formats
++This is the same template file as above with the `json` output format's `permalinkable` parameter set to `true`:
+
+```go-html-template
+{{ .RelPermalink }} → /that-page/index.json
+{{ with .OutputFormats.Get "html" }}
+ {{ .RelPermalink }} → /that-page/
+{{ end }}
+```
+
- Each output format requires a corresponding template conforming to the [template lookup order](/templates/lookup-order/). Hugo considers both output format and suffix when selecting a template.
++## Template lookup order
+
- For example, to generate a JSON file for the home page, the template with highest specificity is `layouts/index.json.json`.
++Each output format requires a template conforming to the [template lookup order].
+
- Hugo will now also detect the media type and output format of partials, if possible, and use that information to decide if the partial should be parsed as a plain text template or not.
++For the highest specificity in the template lookup order, include the page kind, output format, and suffix in the file name:
+
- Hugo will look for the name given, so you can name it whatever you want. But if you want it treated as plain text, you should use the file suffix and, if needed, the name of the Output Format. The pattern is as follows:
-
- ```go-html-template
- [partial name].[OutputFormat].[suffix]
++[template lookup order]: /templates/lookup-order/
+
- The partial below is a plain text template . The output format is `csv`, and since this is the only output format with the suffix `csv`, we don't need to include the output format `name`):
++```text
++[page kind].[output format].[suffix]
+```
+
- ```go-html-template
- {{ partial "mytextpartial.csv" . }}
- ```
++For example, for section pages:
+
- [lookup order]: /templates/lookup-order/
- [media type]: https://en.wikipedia.org/wiki/Media_type
++Output format|Template path
++:--|:--
++`html`|`layouts/_default/section.html.html`
++`json`|`layouts/_default/section.json.json`
++`rss`|`layouts/_default/section.rss.xml`
+
+[site configuration]: /getting-started/configuration/
+[`kind`]: /methods/page/kind/
--- /dev/null
- description: Use section templates to list members of a section.
+---
+title: Section templates
++description: Create a section template to list its members.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 80
+weight: 80
+toc: true
+aliases: [/templates/sections/,/templates/section-templates/]
+---
+
+## Add content and front matter to section templates
+
+To effectively leverage section templates, you should first understand Hugo's [content organization](/content-management/organization/) and, specifically, the purpose of `_index.md` for adding content and front matter to section and other list pages.
+
+## Section template lookup order
+
+See [Template Lookup](/templates/lookup-order/).
+
+## Example: creating a default section template
+
+{{< code file=layouts/_default/section.html >}}
+{{ define "main" }}
+ <main>
+ {{ .Content }}
+
+ {{ $pages := where site.RegularPages "Type" "posts" }}
+ {{ $paginator := .Paginate $pages }}
+
+ {{ range $paginator.Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ end }}
+
+ {{ template "_internal/pagination.html" . }}
+ </main>
+{{ end }}
+{{< /code >}}
+
+### Example: using `.Site.GetPage`
+
+The `.Site.GetPage` example that follows assumes the following project directory structure:
+
+```txt
+.
+└── content
+ ├── blog
+ │ ├── _index.md <-- title: My Hugo Blog
+ │ ├── post-1.md
+ │ ├── post-2.md
+ │ └── post-3.md
+ └── events
+ ├── event-1.md
+ └── event-2.md
+```
+
+`.Site.GetPage` will return `nil` if no `_index.md` page is found. Therefore, if `content/blog/_index.md` does not exist, the template will output the section name:
+
+```go-html-template
+<h1>{{ with .Site.GetPage "/blog" }}{{ .Title }}{{ end }}</h1>
+```
+
+Since `blog` has a section index page with front matter at `content/blog/_index.md`, the above code will return the following result:
+
+```html
+<h1>My Hugo Blog</h1>
+```
+
+If we try the same code with the `events` section, however, Hugo will default to the section title because there is no `content/events/_index.md` from which to pull content and front matter:
+
+```go-html-template
+<h1>{{ with .Site.GetPage "/events" }}{{ .Title }}{{ end }}</h1>
+```
+
+Which then returns the following:
+
+```html
+<h1>Events</h1>
+```
+
+[contentorg]: /content-management/organization/
+[lookup]: /templates/lookup-order/
+[`where`]: /functions/collections/where/
+[sections]: /content-management/sections/
--- /dev/null
- title: Create your own shortcodes
- linkTitle: Shortcode templates
- description: You can extend Hugo's embedded shortcodes by creating your own using the same templating syntax as that for single and list pages.
+---
- Shortcodes are a means to consolidate templating into small, reusable snippets that you can embed directly inside your content.
-
++title: Shortcode templates
++description: Create custom shortcodes to simplify and standardize content creation.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 130
+weight: 130
+aliases: [/templates/shortcode-templates/]
+toc: true
+---
+
- Hugo also ships with embedded shortcodes for common use cases. (See [Content Management: Shortcodes](/content-management/shortcodes/).)
- {{% /note %}}
-
- ## Create custom shortcodes
+{{% note %}}
- Hugo's embedded shortcodes cover many common, but not all, use cases. Luckily, Hugo provides the ability to easily create custom shortcodes to meet your website's needs.
-
- {{< youtube Eu4zSaKOY4A >}}
-
- ### File location
++Before creating custom shortcodes, please review the [shortcodes] page in the [content management] section. Understanding the usage details will help you design and create better templates.
+
- To create a shortcode, place an HTML template in the `layouts/shortcodes` directory. Consider the file name carefully since the shortcode name will mirror that of the file but without the `.html` extension. For example, `layouts/shortcodes/myshortcode.html` will be called with either `{{</* myshortcode /*/>}}` or `{{%/* myshortcode /*/%}}`.
++[shortcodes]: /content-management/shortcodes/
++[content management]: /content-management/shortcodes/
++{{% /note %}}
+
- You can organize your shortcodes in subdirectories, e.g. in `layouts/shortcodes/boxes`. These shortcodes would then be accessible with their relative path, e.g:
++## Introduction
++
++Hugo provides [embedded shortcodes] for many common tasks, but you'll likely need to create your own for more specific needs. Some examples of custom shortcodes you might develop include:
++
++- Audio players
++- Video players
++- Image galleries
++- Diagrams
++- Maps
++- Tables
++- And many other custom elements
++
++[embedded shortcodes]: /shortcodes/
++
++## Directory structure
++
++Create shortcode templates within the `layouts/shortcodes` directory, either at its root or organized into subdirectories.
++
++```text
++layouts/
++└── shortcodes/
++ ├── diagrams/
++ │ ├── kroki.html
++ │ └── plotly.html
++ ├── media/
++ │ ├── audio.html
++ │ ├── gallery.html
++ │ └── video.html
++ ├── capture.html
++ ├── column.html
++ ├── include.html
++ └── row.html
++```
+
- ```go-html-template
- {{</* boxes/square */>}}
++When calling a shortcode in a subdirectory, specify its path relative to the `shortcode` directory, excluding the file extension.
+
- Note the forward slash.
-
- ### Template lookup order
++```text
++{{</* media/audio path=/audio/podcast/episode-42.mp3 */>}}
+```
+
- foo|rss|en|`layouts/shortcodes/foo.en.xml`
- foo|rss|en|`layouts/shortcodes/foo.rss.xml`
- foo|rss|en|`layouts/shortcodes/foo.en.html`
- foo|rss|en|`layouts/shortcodes/foo.rss.en.xml`
- foo|rss|en|`layouts/shortcodes/foo.xml`
- foo|rss|en|`layouts/shortcodes/foo.html.en.html`
- foo|rss|en|`layouts/shortcodes/foo.html.html`
- foo|rss|en|`layouts/shortcodes/foo.html`
++## Lookup order
+
+Hugo selects shortcode templates based on the shortcode name, the current output format, and the current language. The examples below are sorted by specificity in descending order. The least specific path is at the bottom of the list.
+
+Shortcode name|Output format|Language|Template path
+:--|:--|:--|:--
+foo|html|en|`layouts/shortcodes/foo.en.html`
+foo|html|en|`layouts/shortcodes/foo.html.html`
+foo|html|en|`layouts/shortcodes/foo.html`
+foo|html|en|`layouts/shortcodes/foo.html.en.html`
+
+Shortcode name|Output format|Language|Template path
+:--|:--|:--|:--
- Note that templates provided by a theme or module always take precedence.
++foo|json|en|`layouts/shortcodes/foo.en.json`
++foo|json|en|`layouts/shortcodes/foo.json`
++foo|json|en|`layouts/shortcodes/foo.json.json`
++foo|json|en|`layouts/shortcodes/foo.json.en.json`
+
- ### Positional vs. named arguments
++## Methods
+
- You can create shortcodes using the following types of arguments:
++Use these methods in your shortcode templates. Refer to each methods's documentation for details and examples.
+
- * Positional arguments
- * Named arguments
- * Positional *or* named arguments
++{{< list-pages-in-section path=/methods/shortcode >}}
+
- In shortcodes with positional arguments, the order of the arguments is important. If a shortcode has a single required value, positional arguments require less typing from content authors.
++## Examples
+
- For more complex layouts with multiple or optional arguments, named arguments work best. While less terse, named arguments require less memorization from a content author and can be added in a shortcode declaration in any order.
++These examples range in complexity from simple to moderately advanced, with some simplified for clarity.
+
- Allowing both types of arguments is useful for complex layouts where you want to set default values that can be easily overridden by users.
++### Insert year
+
- ### Access arguments
++Create a shortcode to insert the current year:
+
- All shortcode arguments can be accessed via the `.Get` method. Whether you pass a string or a number to the `.Get` method depends on whether you are accessing a named or positional argument, respectively.
++{{< code file=layouts/shortcodes/year.html >}}
++{{- now.Format "2006" -}}
++{{< /code >}}
+
- To access an argument by name, use the `.Get` method followed by the named argument as a quoted string:
++Then call the shortcode from within your markup:
+
- ```go-html-template
- {{ .Get "class" }}
- ```
++{{< code file=content/example.md >}}
++This is {{</* year */>}}, and look at how far we've come.
++{{< /code >}}
+
- To access an argument by position, use the `.Get` followed by a numeric position, keeping in mind that positional arguments are zero-indexed:
++This shortcode can be used inline or as a block on its own line. If a shortcode might be used inline, remove the surrounding [whitespace] by using [template action](g) delimiters with hyphens.
+
- ```go-html-template
- {{ .Get 0 }}
- ```
++[whitespace]: /templates/introduction/#whitespace
+
- For the second position, you would just use:
++### Insert image
+
- ```go-html-template
- {{ .Get 1 }}
++This example assumes the following content structure, where `content/example/index.md` is a [page bundle](g) containing one or more [page resources](g).
+
- `with` is great when the output depends on a argument being set:
++```text
++content/
++├── example/
++│ ├── a.jpg
++│ └── index.md
++└── _index.md
+```
+
- ```go-html-template
- {{ with .Get "class" }} class="{{ . }}"{{ end }}
- ```
++Create a shortcode to capture an image as a page resource, resize it to the given width, convert it to the WebP format, and add an `alt` attribute:
+
- `.Get` can also be used to check if a argument has been provided. This is
- most helpful when the condition depends on either of the values, or both:
++{{< code file=layouts/shortcodes/image.html >}}
++{{- with .Page.Resources.Get (.Get "path") }}
++ {{- with .Process (printf "resize %dx wepb" ($.Get "width")) }}
++ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $.Get "alt" }}">
++ {{- end }}
++{{- end -}}
++{{< /code >}}
+
- ```go-html-template
- {{ if or (.Get "title") (.Get "alt") }} alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "title" }}{{ end }}"{{ end }}
- ```
++Then call the shortcode from within your markup:
+
- #### `.Inner`
++{{< code file=content/example/index.md >}}
++{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
++{{< /code >}}
+
- The `.Inner` method returns the content between the opening and closing shortcode tags. To check if `.Inner` returns anything other than whitespace:
++The example above uses:
+
- ```go-html-template
- {{ if strings.ContainsNonSpace .Inner }}
- Inner is not empty
- {{ end }}
- ```
++- The [`with`] statement to rebind the [context](g) after each successful operation
++- The [`Get`] method to retrieve arguments by name
++- The `$` to access the template context
+
- Any shortcode that calls the `.Inner` method must be closed or self-closed. To call a shortcode using the self-closing syntax.
++[`get`]: /methods/shortcode/get/
++[`with`]: /functions/go-template/with/
+
+{{% note %}}
- ```go-html-template
- {{</* innershortcode /*/>}}
- ```
++Make sure that you thoroughly understand the concept of context. The most common templating errors made by new users relate to context.
+
- #### `.Params`
++Read more about context in the [introduction to templating].
+
++[introduction to templating]: /templates/introduction/
+{{% /note %}}
+
- The `.Params` method in shortcodes returns the arguments passed to the shortcode for more complicated use cases. You can also access higher-scoped arguments with the following logic:
++### Insert image with error handling
++
++The previous example, while functional, silently fails if the image is missing, and does not gracefully exit if a required argument is missing. We'll add error handling to address these issues:
++
++{{< code file=layouts/shortcodes/image.html >}}
++{{ with .Get "path" }}
++ {{- with $r := $.Page.Resources.Get ($.Get "path") }}
++ {{- with $.Get "width" }}
++ {{- with $r.Process (printf "resize %dx wepb" ($.Get "width" )) }}
++ {{- $alt := or ($.Get "alt") "" }}
++ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $alt }}">
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode requires a 'width' argument: see %s" $.Name $.Position }}
++ {{- end }}
++ {{- else }}
++ {{ warnf "The %q shortcode was unable to find %s: see %s" $.Name ($.Get "path") $.Position }}
++ {{- end }}
++{{- else }}
++ {{ errorf "The %q shortcode requires a 'path' argument: see %s" .Name .Position }}
++{{- end -}}
++{{< /code >}}
+
- $.Params
- : these are the arguments passed directly into the shortcode declaration (e.g., a YouTube video ID)
++This template throws an error and gracefully fails the build if the author neglected to provide a `path` or `width` argument, and it emits a warning if it cannot find the image at the specified path. If the author does not provide an `alt` argument, the `alt` attribute is set to an empty string.
+
- $.Page.Params
- : refers to the page's parameters; the "page" in this case refers to the content file in which the shortcode is declared (e.g., a `shortcode_color` field in a content's front matter could be accessed via `$.Page.Params.shortcode_color`).
++The [`Name`] and [`Position`] methods provide helpful context for errors and warnings. For example, a missing `width` argument causes the shortcode to throw this error:
+
- $.Site.Params
- : refers to parameters defined in your site configuration.
++[`name`]: /methods/shortcode/name/
++[`position`]: /methods/shortcode/position/
+
- #### `.IsNamedParams`
++```text
++ERROR The "image" shortcode requires a 'width' argument: see "/home/user/project/content/example/index.md:7:1"
++```
+
- The `.IsNamedParams` method checks whether the shortcode declaration uses named arguments and returns a boolean value.
++### Positional arguments
+
- For example, you could create an `image` shortcode that can take either a `src` named argument or the first positional argument, depending on the preference of the content's author. Let's assume the `image` shortcode is called as follows:
++Shortcode arguments can be [named or positional]. We used named arguments previously; let's explore positional arguments. Here's the named argument version of our example:
+
- ```go-html-template
- {{</* image src="images/my-image.jpg" */>}}
- ```
++[named or positional]: /content-management/shortcodes/#arguments
+
- You could then include the following as part of your shortcode templating:
++{{< code file=content/example/index.md >}}
++{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
++{{< /code >}}
+
- ```go-html-template
- {{ if .IsNamedParams }}
- <img src="{{ .Get "src" }}" alt="">
- {{ else }}
- <img src="{{ .Get 0 }}" alt="">
- {{ end }}
- ```
++Here's how to call it with positional arguments:
+
- See the [example Vimeo shortcode][vimeoexample] below for `.IsNamedParams` in action.
++{{< code file=content/example/index.md >}}
++{{</* image a.jpg 300 "A white kitten" */>}}
++{{< /code >}}
+
- While you can create shortcode templates that accept both positional and named arguments, you *cannot* declare shortcodes in content with a mix of argument types. Therefore, a shortcode declared like `{{</* image src="images/my-image.jpg" "This is my alt text" */>}}` will return an error.
++Using the `Get` method with zero-indexed keys, we'll initialize variables with descriptive names in our template:
++
++{{< code file=layouts/shortcodes/image.html >}}
++{{- $path := .Get 0 }}
++{{- $width := .Get 1 }}
++{{- $alt := .Get 2 }}
++{{< /code >}}
+
+{{% note %}}
- Shortcodes can also be nested. In a nested shortcode, you can access the parent shortcode context with the [`.Parent`] shortcode method. This can be very useful for inheritance from the root.
++Positional arguments work well for frequently used shortcodes with one or two arguments. Since you'll use them often, the argument order will be easy to remember. For less frequently used shortcodes, or those with more than two arguments, named arguments improve readability and reduce the chance of errors.
+{{% /note %}}
+
- ### Checking for existence
++### Named and positional arguments
+
- You can check if a specific shortcode is used on a page by calling `.HasShortcode` in that page template, providing the name of the shortcode. This is useful when you want to include specific scripts or styles in the header that are only used by that shortcode.
-
- ## Custom shortcode examples
-
- The following are examples of the different types of shortcodes you can create via shortcode template files in `/layouts/shortcodes`.
-
- ### Single-word example: `year`
-
- Let's assume you would like to keep mentions of your copyright year current in your content files without having to continually review your Markdown. Your goal is to be able to call the shortcode as follows:
++You can create a shortcode that will accept both named and positional arguments, but not at the same time. Use the [`IsNamedParams`] method to determine whether the shortcode call used named or positional arguments:
+
- ```go-html-template
- {{</* year */>}}
- ```
++{{< code file=layouts/shortcodes/image.html >}}
++{{- $path := cond (.IsNamedParams) (.Get "path") (.Get 0) }}
++{{- $width := cond (.IsNamedParams) (.Get "width") (.Get 1) }}
++{{- $alt := cond (.IsNamedParams) (.Get "alt") (.Get 2) }}
++{{< /code >}}
+
- {{< code file=layouts/shortcodes/year.html >}}
- {{ now.Format "2006" }}
- {{< /code >}}
++This example uses the `cond` alias for the [`compare.Conditional`] function to get the argument by name if `IsNamedParams` returns `true`, otherwise get the argument by position.
+
- ### Single positional example: `youtube`
++[`compare.Conditional`]: /functions/compare/conditional/
++[`IsNamedParams`]: /methods/shortcode/isnamedparams/
+
- Embedded videos are a common addition to Markdown content. The following is the code used by [Hugo's built-in YouTube shortcode][youtubeshortcode]:
++### Argument collection
+
- ```go-html-template
- {{</* youtube 09jf3ow9jfw */>}}
- ```
++Use the [`Params`] method to access the arguments as a collection.
+
- Would load the template at `/layouts/shortcodes/youtube.html`:
++[`Params`]: /methods/shortcode/params/
+
- {{< code file=layouts/shortcodes/youtube.html >}}
- <div class="embed video-player">
- <iframe class="youtube-player" type="text/html" width="640" height="385" src="https://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
- </iframe>
- </div>
++When using named arguments, the `Params` method returns a map:
+
- {{< code file=youtube-embed.html >}}
- <div class="embed video-player">
- <iframe class="youtube-player" type="text/html"
- width="640" height="385"
- src="https://www.youtube.com/embed/09jf3ow9jfw"
- allowfullscreen frameborder="0">
- </iframe>
- </div>
++{{< code file=content/example/index.md >}}
++{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
+{{< /code >}}
+
- ### Single named example: `image`
-
- Let's say you want to create your own `img` shortcode rather than use Hugo's built-in [`figure` shortcode][figure]. Your goal is to be able to call the shortcode as follows in your content files:
++{{< code file=layouts/shortcodes/image.html >}}
++{{- .Params.path }} → a.jpg
++{{- .Params.width }} → 300
++{{- .Params.alt }} → A white kitten
+{{< /code >}}
+
- {{< code file=content-image.md >}}
- {{</* img src="/media/spf13.jpg" title="Steve Francia" */>}}
++ When using positional arguments, the `Params` method returns a slice:
+
- You have created the shortcode at `/layouts/shortcodes/img.html`, which loads the following shortcode template:
-
- {{< code file=layouts/shortcodes/img.html >}}
- <!-- image -->
- <figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
- {{ with .Get "link" }}<a href="{{ . }}">{{ end }}
- <img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }} />
- {{ if .Get "link" }}</a>{{ end }}
- {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }}
- <figcaption>{{ if isset .Params "title" }}
- <h4>{{ .Get "title" }}</h4>{{ end }}
- {{ if or (.Get "caption") (.Get "attr") }}<p>
- {{ .Get "caption" }}
- {{ with .Get "attrlink" }}<a href="{{ . }}"> {{ end }}
- {{ .Get "attr" }}
- {{ if .Get "attrlink" }}</a> {{ end }}
- </p> {{ end }}
- </figcaption>
- {{ end }}
- </figure>
- <!-- image -->
++{{< code file=content/example/index.md >}}
++{{</* image a.jpg 300 "A white kitten" */>}}
+{{< /code >}}
+
- Would be rendered as:
++{{< code file=layouts/shortcodes/image.html >}}
++{{- index .Params 0 }} → a.jpg
++{{- index .Params 1 }} → 300
++{{- index .Params 1 }} → A white kitten
+{{< /code >}}
+
- {{< code file=img-output.html >}}
- <figure>
- <img src="/media/spf13.jpg" />
- <figcaption>
- <h4>Steve Francia</h4>
- </figcaption>
- </figure>
- {{< /code >}}
++Combine the `Params` method with the [`collections.IsSet`] function to determine if a parameter is set, even if its value is falsy.
+
- ### Single flexible example: `vimeo`
++[`collections.IsSet`]: /functions/collections/isset/
+
- ```go-html-template
- {{</* vimeo 49718712 */>}}
- {{</* vimeo id="49718712" class="flex-video" */>}}
- ```
++### Inner content
+
- Would load the template found at `/layouts/shortcodes/vimeo.html`:
++Extract the content enclosed within shortcode tags using the [`Inner`] method. This example demonstrates how to pass both content and a title to a shortcode. The shortcode then generates a `div` element containing an `h2` element (displaying the title) and the provided content.
+
- {{< code file=layouts/shortcodes/vimeo.html >}}
- {{ if .IsNamedParams }}
- <div class="{{ if .Get "class" }}{{ .Get "class" }}{{ else }}vimeo-container{{ end }}">
- <iframe src="https://player.vimeo.com/video/{{ .Get "id" }}" allowfullscreen></iframe>
- </div>
- {{ else }}
- <div class="{{ if len .Params | eq 2 }}{{ .Get 1 }}{{ else }}vimeo-container{{ end }}">
- <iframe src="https://player.vimeo.com/video/{{ .Get 0 }}" allowfullscreen></iframe>
- </div>
- {{ end }}
++[`Inner`]: /methods/shortcode/inner/
+
- Would be rendered as:
-
- {{< code file=vimeo-iframes.html >}}
- <div class="vimeo-container">
- <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
- </div>
- <div class="flex-video">
- <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
++{{< code file=content/example.md >}}
++{{</* contrived title="A Contrived Example" */>}}
++This is a **bold** word, and this is an _emphasized_ word.
++{{</* /contrived */>}}
+{{< /code >}}
+
- ### Paired example: `highlight`
++{{< code file=layouts/shortcodes/contrived.html >}}
++<div class="contrived">
++ <h2>{{ .Get "title" }}</h2>
++ {{ .Inner | .Page.RenderString }}
+</div>
+{{< /code >}}
+
- The following is taken from `highlight`, which is a [built-in shortcode] that ships with Hugo.
++The preceding example called the shortcode using [standard notation], requiring us to process the inner content with the [`RenderString`] method to convert the Markdown to HTML. This conversion is unnecessary when calling a shortcode using [Markdown notation].
+
- {{< code file=highlight-example.md >}}
- {{</* highlight html */>}}
- <html>
- <body> This HTML </body>
- </html>
- {{</* /highlight */>}}
- {{< /code >}}
-
- The template for the `highlight` shortcode uses the following code, which is already included in Hugo:
-
- ```go-html-template
- {{ .Get 0 | highlight .Inner }}
- ```
-
- The rendered output of the HTML example code block will be as follows:
++[`RenderString`]: /methods/page/renderstring/
++[markdown notation]: /content-management/shortcodes/#markdown-notation
++[standard notation]: /content-management/shortcodes/#standard-notation
+
- {{< code file=syntax-highlighted.html >}}
- <div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672"><html></span>
- <span style="color: #f92672"><body></span> This HTML <span style="color: #f92672"></body></span>
- <span style="color: #f92672"></html></span>
- </pre></div>
- {{< /code >}}
-
- ### Nested shortcode: image gallery
++### Nesting
+
- Hugo's [`.Parent`] shortcode method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model.
++The [`Parent`] method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model.
+
- {{- $src := .Get "src" -}}
- {{- with .Parent -}}
++[`Parent`]: /methods/shortcode/parent/
+
+The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` argument:
+
+{{< code file=layouts/shortcodes/gallery.html >}}
+<div class="{{ .Get "class" }}">
+ {{ .Inner }}
+</div>
+{{< /code >}}
+
+You also have an `img` shortcode with a single named `src` argument that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`:
+
+{{< code file=layouts/shortcodes/img.html >}}
- {{- else -}}
++{{ $src := .Get "src" }}
++{{ with .Parent }}
+ <img src="{{ $src }}" class="{{ .Get "class" }}-image">
- {{- end -}}
++{{ else }}
+ <img src="{{ $src }}">
- ```go-html-template
++{{ end }}
+{{< /code >}}
+
+You can then call your shortcode in your content as follows:
+
- ```
++{{< code file=content/example.md >}}
+{{</* gallery class="content-gallery" */>}}
+ {{</* img src="/images/one.jpg" */>}}
+ {{</* img src="/images/two.jpg" */>}}
+{{</* /gallery */>}}
+{{</* img src="/images/three.jpg" */>}}
- ## Error handling in shortcodes
-
- Use the [`errorf`] template function with the [`Name`] and [`Position`] shortcode methods to generate useful error messages:
-
- {{< code file=layouts/shortcodes/greeting.html >}}
- {{ with .Get "name" }}
- <p>Hello, my name is {{ . }}.</p>
- {{ else }}
- {{ errorf "The %q shortcode requires a 'name' argument. See %s" .Name .Position }}
- {{ end }}
- {{< /code >}}
-
- When the above fails, you will see an `ERROR` message such as:
-
- ```sh
- ERROR The "greeting" shortcode requires a 'name' argument. See "/home/user/project/content/_index.md:12:1"
- ```
-
- ## Inline shortcodes
-
- You can also implement your shortcodes inline -- e.g. where you use them in the content file. This can be useful for scripting that you only need in one place.
-
- This feature is disabled by default, but can be enabled in your site configuration:
-
- {{< code-toggle file=hugo >}}
- [security]
- enableInlineShortcodes = true
- {{< /code-toggle >}}
++{{< /code >}}
++
+
+This will output the following HTML. Note how the first two `img` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `img` only uses `src`:
+
+```html
+<div class="content-gallery">
+ <img src="/images/one.jpg" class="content-gallery-image">
+ <img src="/images/two.jpg" class="content-gallery-image">
+</div>
+<img src="/images/three.jpg">
+```
+
- It is disabled by default for security reasons. The security model used by Hugo's template handling assumes that template authors are trusted, but that the content files are not, so the templates are injection-safe from malformed input data. But in most situations you have full control over the content, too, and then `enableInlineShortcodes = true` would be considered safe. But it's something to be aware of: It allows ad-hoc [Go Text templates](https://golang.org/pkg/text/template/) to be executed from the content files.
++### Other examples
+
- And once enabled, you can do this in your content files:
++For guidance, consider examining Hugo's embedded shortcodes. The source code, available on [GitHub], can provide a useful model.
+
- ```go-html-template
- {{</* time.inline */>}}{{ now }}{{</* /time.inline */>}}
- ```
++[GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/shortcodes
+
- The above will print the current date and time.
++## Detection
+
- Note that an inline shortcode's inner content is parsed and executed as a Go text template with the same context as a regular shortcode template.
-
- This means that the current page can be accessed via `.Page.Title` etc. This also means that there are no concept of "nested inline shortcodes".
++The [`HasShortcode`] method allows you to check if a specific shortcode has been called on a page. For example, consider a custom audio shortcode:
+
- The same inline shortcode can be reused later in the same content file, with different arguments if needed, using the self-closing syntax:
++{{< code file=content/example.md >}}
++{{</* audio src=/audio/test.mp3 */>}}
++{{< /code >}}
+
- ```go-html-template
- {{</* time.inline /*/>}}
- ```
++You can use the `HasShortcode` method in your base template to conditionally load CSS if the audio shortcode was used on the page:
+
- [`.Parent`]: /methods/shortcode/parent/
- [`errorf`]: /functions/fmt/errorf/
- [`Name`]: /methods/shortcode/name/
- [`Position`]: /methods/shortcode/position/
- [built-in shortcode]: /content-management/shortcodes/
- [figure]: /shortcodes/figure/
- [lookup order]: /templates/lookup-order/
- [source organization]: /getting-started/directory-structure/
- [vimeoexample]: #single-flexible-example-vimeo
- [youtubeshortcode]: /shortcodes/youtube/
++{{< code file=layouts/_default/baseof.html >}}
++<head>
++ ...
++ {{ if .HasShortcode "audio" }}
++ <link rel="stylesheet" src="/css/audio.css">
++ {{ end }}
++ ...
++</head>
++{{< /code >}}
+
++[`HasShortcode`]: /methods/page/hasshortcode/
--- /dev/null
- : (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef).
+---
+title: Sitemap templates
+description: Hugo provides built-in sitemap templates.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 140
+weight: 140
+toc: true
+aliases: [/layout/sitemap/,/templates/sitemap-template/]
+---
+
+## Overview
+
+Hugo's embedded sitemap templates conform to v0.9 of the [sitemap protocol].
+
+With a monolingual project, Hugo generates a sitemap.xml file in the root of the [`publishDir`] using the [embedded sitemap template].
+
+With a multilingual project, Hugo generates:
+
+- A sitemap.xml file in the root of each site (language) using the [embedded sitemap template]
+- A sitemap.xml file in the root of the [`publishDir`] using the [embedded sitemapindex template]
+
+[embedded sitemap template]: {{% eturl sitemap %}}
+[embedded sitemapindex template]: {{% eturl sitemapindex %}}
+
+## Configuration
+
+These are the default sitemap configuration values. They apply to all pages unless overridden in front matter.
+
+{{< code-toggle config=sitemap />}}
+
+changefreq
- disable {{< new-in 0.125.0 >}}
++: (`string`) How frequently a page is likely to change. Valid values are `always`, `hourly`, `daily`, `weekly`, `monthly`, `yearly`, and `never`. With the default value of `""` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#changefreqdef).
+
- : (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority).
++disable {{< new-in 0.125.0 />}}
+: (`bool`) Whether to disable page inclusion. Default is `false`. Set to `true` in front matter to exclude the page.
+
+filename
+: (`string`) The name of the generated file. Default is `sitemap.xml`.
+
+priority
++: (`float`) The priority of a page relative to any other page on the site. Valid values range from 0.0 to 1.0. With the default value of `-1` Hugo will omit this field from the sitemap. See [details](https://www.sitemaps.org/protocol.html#priority).
+
+## Override default values
+
+Override the default values for a given page in front matter.
+
+{{< code-toggle file=news.md fm=true >}}
+title = 'News'
+[sitemap]
+ changefreq = 'weekly'
+ disable = true
+ priority = 0.8
+{{</ code-toggle >}}
+
+## Override built-in templates
+
+To override the built-in sitemap.xml template, create a new file in either of these locations:
+
+- `layouts/sitemap.xml`
+- `layouts/_default/sitemap.xml`
+
+When ranging through the page collection, access the _change frequency_ and _priority_ with `.Sitemap.ChangeFreq` and `.Sitemap.Priority` respectively.
+
+To override the built-in sitemapindex.xml template, create a new file in either of these locations:
+
+- `layouts/sitemapindex.xml`
+- `layouts/_default/sitemapindex.xml`
+
+## Disable sitemap generation
+
+You may disable sitemap generation in your site configuration:
+
+{{< code-toggle file=hugo >}}
+disableKinds = ['sitemap']
+{{</ code-toggle >}}
+
+[`publishDir`]: /getting-started/configuration#publishdir
+[sitemap protocol]: https://www.sitemaps.org/protocol.html
--- /dev/null
- You must have thorough understanding of the [template lookup order] when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format.
-
- [template lookup order]: /templates/lookup-order/
+---
+title: Template types
+linkTitle: Template types
+description: Create templates of different types to render your content, resources, and data.
+categories: [templates]
+keywords: []
+menu:
+ docs:
+ parent: templates
+ weight: 30
+weight: 30
+toc: true
+aliases: ['/templates/lists/']
+---
+
+[](site-hierarchy.svg)
+
+## Structure
+
+Create templates in the `layouts` directory in the root of your project.
+
+Although your site may not require each of these templates, the example below is typical for a site of medium complexity.
+
+```text
+layouts/
+├── _default/
+│ ├── _markup/
+│ │ ├── render-image.html <-- render hook
+│ │ └── render-link.html <-- render hook
+│ ├── baseof.html
+│ ├── home.html
+│ ├── section.html
+│ ├── single.html
+│ ├── taxonomy.html
+│ └── term.html
+├── articles/
+│ └── card.html <-- content view
+├── partials/
+│ ├── footer.html
+│ └── header.html
+└── shortcodes/
+ ├── audio.html
+ └── video.html
+```
+
+Hugo's [template lookup order] determines the template path, allowing you to create unique templates for any page.
+
+[template lookup order]: /templates/lookup-order/
+
+{{% note %}}
- A home template renders your site's home page. For a single page site this is the only required template.
-
- For example, the home template below inherits the site's shell from the base template, and renders the home page content with a list of pages.
++You must have thorough understanding of the template lookup order when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format.
+{{% /note %}}
+
+The purpose of each template type is described below.
+
+## Base
+
+Base templates reduce duplicate code by wrapping other templates within a shell.
+
+For example, the base template below calls the [partial] function to include partial templates for the `head`, `header`, and `footer` elements of each page, and it uses the [block] function to include `home`, `single`, `section`, `taxonomy`, and `term` templates within the `main` element of each page.
+
+[block]: /functions/go-template/block/
+[partial]: /functions/partials/include/
+
+{{< code file=layouts/_default/baseof.html >}}
+<!DOCTYPE html>
+<html lang="{{ or site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}">
+<head>
+ {{ partial "head.html" . }}
+</head>
+<body>
+ <header>
+ {{ partial "header.html" . }}
+ </header>
+ <main>
+ {{ block "main" . }}{{ end }}
+ </main>
+ <footer>
+ {{ partial "footer.html" . }}
+ </footer>
+</body>
+</html>
+{{< /code >}}
+
+Learn more about [base templates](/templates/base/).
+
+## Home
+
- Learn more about [home templates](/templates/home/).
++A home page template is used to render your site's home page, and is the only template required for a single-page website. For example, the home page template below inherits the site's shell from the base template and renders the home page content, such as a list of other pages.
+
+{{< code file=layouts/_default/home.html >}}
+{{ define "main" }}
+ {{ .Content }}
+ {{ range site.RegularPages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+{{% include "templates/_common/filter-sort-group.md" %}}
+
- {{- with .Text | safeHTML }}{{ . }}{{ end -}}
++Learn more about [home page templates](/templates/home/).
+
+## Single
+
+A single template renders a single page.
+
+For example, the single template below inherits the site's shell from the base template, and renders the title and content of each page.
+
+{{< code file=layouts/_default/single.html >}}
+{{ define "main" }}
+ <h1>{{ .Title }}</h1>
+ {{ .Content }}
+{{ end }}
+{{< /code >}}
+
+Learn more about [single templates](/templates/single/).
+
+## Section
+
+A section template typically renders a list of pages within a section.
+
+For example, the section template below inherits the site's shell from the base template, and renders a list of pages in the current section.
+
+{{< code file=layouts/_default/section.html >}}
+{{ define "main" }}
+ <h1>{{ .Title }}</h1>
+ {{ .Content }}
+ {{ range .Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+{{% include "templates/_common/filter-sort-group.md" %}}
+
+Learn more about [section templates](/templates/section/).
+
+## Taxonomy
+
+A taxonomy template renders a list of terms in a [taxonomy](g).
+
+For example, the taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy.
+
+{{< code file=layouts/_default/taxonomy.html >}}
+{{ define "main" }}
+ <h1>{{ .Title }}</h1>
+ {{ .Content }}
+ {{ range .Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+{{% include "templates/_common/filter-sort-group.md" %}}
+
+Learn more about [taxonomy templates](/templates/taxonomy/).
+
+## Term
+
+A term template renders a list of pages associated with a [term](g).
+
+For example, the term template below inherits the site's shell from the base template, and renders a list of pages associated with the current term.
+
+{{< code file=layouts/_default/term.html >}}
+{{ define "main" }}
+ <h1>{{ .Title }}</h1>
+ {{ .Content }}
+ {{ range .Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+{{% include "templates/_common/filter-sort-group.md" %}}
+
+Learn more about [term templates](/templates/term/).
+
+## Partial
+
+A partial template is typically used to render a component of your site, though you may also create partial templates that return values.
+
+{{% note %}}
+Unlike other template types, you cannot create partial templates to target a particular page kind, content type, section, language, or output format. Partial templates do not follow Hugo's [template lookup order].
+
+[template lookup order]: /templates/lookup-order/
+{{% /note %}}
+
+For example, the partial template below renders copyright information.
+
+{{< code file=layouts/partials/footer.html >}}
+<p>Copyright {{ now.Year }}. All rights reserved.</p>
+{{< /code >}}
+
+Learn more about [partial templates](/templates/partial/).
+
+## Content view
+
+A content view template is similar to a partial template, invoked by calling the [`Render`] method on a `Page` object. Unlike partial templates, content view templates:
+
+- Automatically inherit the context of the current page
+- Follow a lookup order allowing you to target a given content type or section
+
+[`Render`]: /methods/page/render/
+
+For example, the home template below inherits the site's shell from the base template, and renders a card component for each page within the "articles" section of your site.
+
+{{< code file=layouts/_default/home.html >}}
+{{ define "main" }}
+ {{ .Content }}
+ <ul>
+ {{ range where site.RegularPages "Section" "articles" }}
+ {{ .Render "card" }}
+ {{ end }}
+ </ul>
+{{ end }}
+{{< /code >}}
+
+{{< code file=layouts/articles/card.html >}}
+<div class="card">
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+ {{ .Summary }}
+</div>
+{{< /code >}}
+
+Learn more about [content view templates](/templates/content-view/).
+
+## Render hook
+
+A render hook template overrides the conversion of Markdown to HTML.
+
+For example, the render hook template below adds a `rel` attribute to external links.
+
+{{< code file=layouts/_default/_markup/render-link.html >}}
+{{- $u := urls.Parse .Destination -}}
+<a href="{{ .Destination | safeURL }}"
+ {{- with .Title }} title="{{ . }}"{{ end -}}
+ {{- if $u.IsAbs }} rel="external"{{ end -}}
+>
- Call the shortcode from your content page:
++ {{- with .Text }}{{ . }}{{ end -}}
+</a>
+{{- /* chomp trailing newline */ -}}
+{{< /code >}}
+
+Learn more about [render hook templates](/render-hooks/).
+
+## Shortcode
+
+A shortcode template is used to render a component of your site. Unlike partial templates, shortcode templates are called from content pages.
+
+For example, the shortcode template below renders an audio element from a [global resource](g).
+
+{{< code file=layouts/shortcodes/audio.html >}}
+{{ with resources.Get (.Get "src") }}
+ <audio controls preload="auto" src="{{ .RelPermalink }}"></audio>
+{{ end }}
+{{< /code >}}
+
- {{</* audio src="audio/test.mp3" */>}}
++Then call the shortcode from within markup:
+
+{{< code file=content/example.md >}}
++{{</* audio src=/audio/test.mp3 */>}}
+{{< /code >}}
+
+Learn more about [shortcode templates](/templates/shortcode/).
+
+## Other
+
+Use other specialized templates to create:
+
+- [Sitemaps](/templates/sitemap)
+- [RSS feeds](/templates/rss/)
+- [404 error pages](/templates/404/)
+- [robots.txt files](/templates/robots/)
--- /dev/null
- linkTitle: In this section
- description: In addition to Hugo's powerful CLI, there is a large number of community-developed tool chains for Hugo developers.
+---
+title: Developer tools
++
++description: Third-party tools to help you create and manage sites.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: developer-tools-in-this-section
+ parent: developer-tools
+ weight: 10
+weight: 10
+---
+
+One of Hugo's greatest strengths is its passionate---and always evolving---developer community. With the exception of the `highlight` shortcode mentioned in [Syntax Highlighting][syntax], the tools and other projects featured in this section are offerings from both commercial services and open-source projects, many of which are developed by Hugo developers just like you.
+
+[See the popularity of Hugo compared with other static site generators.][staticgen]
+
+[staticgen]: https://staticgen.com
+[syntax]: /content-management/syntax-highlighting/
--- /dev/null
- : This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client-side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt, or other build-time tools except Hugo!
+---
+title: Search tools
+linkTitle: Search
+description: See some of the open-source and commercial search options for your newly created Hugo website.
+categories: [developer tools]
+keywords: [search]
+menu:
+ docs:
+ parent: developer-tools
+ weight: 40
+weight: 40
+toc: true
+---
+
+A static website with a dynamic search function? Yes, Hugo provides an alternative to embeddable scripts from Google or other search engines for static websites. Hugo allows you to provide your visitors with a custom search function by indexing your content files directly.
+
+## Open-source
+
+[Pagefind](https://github.com/cloudcannon/pagefind)
+: A fully static search library that aims to perform well on large sites, while using as little of your users' bandwidth as possible.
+
+[GitHub Gist for Hugo Workflow](https://gist.github.com/sebz/efddfc8fdcb6b480f567)
+: This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and [lunr.js](https://lunrjs.com/) to serve the search results.
+
+[hugo-lunr](https://www.npmjs.com/package/hugo-lunr)
+: A simple way to add site search to your static Hugo site using [lunr.js](https://lunrjs.com/). Hugo-lunr will create an index file of any HTML and Markdown documents in your Hugo project.
+
+[hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh)
+: A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords.
+
+[GitHub Gist for Fuse.js integration](https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae)
++: This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt, or other build-time tools except Hugo!
+
+[hugo-search-index](https://www.npmjs.com/package/hugo-search-index)
+: A library containing Gulp tasks and a prebuilt browser script that implements search. Gulp generates a search index from project Markdown files.
+
+[hugofastsearch](https://gist.github.com/cmod/5410eae147e4318164258742dd053993)
+: A usability and speed update to "GitHub Gist for Fuse.js integration" — global, keyboard-optimized search.
+
+[JS & Fuse.js tutorial](https://makewithhugo.com/add-search-to-a-hugo-site/)
+: A simple client-side search solution, using FuseJS (does not require jQuery).
+
+[Hugo Lyra](https://github.com/paolomainardi/hugo-lyra)
+: Hugo-Lyra is a JavaScript module to integrate [Lyra](https://github.com/LyraSearch/lyra) into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily.
+
+[INFINI Pizza for WebAssembly](https://github.com/infinilabs/pizza-docsearch)
+: Pizza is a super-lightweight yet fully featured search engine written in Rust. You can quickly add offline search functionality to your Hugo website in just five minutes with only three lines of code. For a step-by-step guide on integrating it with Hugo, check out [this blog tutorial](https://dev.to/medcl/adding-search-functionality-to-a-hugo-static-site-based-on-infini-pizza-for-webassembly-4h5e).
+
+## Commercial
+
+[Algolia](https://www.algolia.com/)
+: Algolia's Search API makes it easy to deliver a great search experience in your apps and websites. Algolia Search provides hosted full-text, numerical, faceted, and geolocalized search.
+
+[Bonsai](https://www.bonsai.io)
+: Bonsai is a fully-managed hosted Elasticsearch service that is fast, reliable, and simple to set up. Easily ingest your docs from Hugo into Elasticsearch following [this guide from the docs](https://bonsai.io/docs/hugo).
+
+[ExpertRec](https://www.expertrec.com/)
+: ExpertRec is a hosted search-as-a-service solution that is fast and scalable. Set-up and integration is extremely easy and takes only a few minutes. The search settings can be modified without coding using a dashboard.
--- /dev/null
- linkTitle: In this section
+---
+title: Troubleshooting
++
+description: Use these techniques when troubleshooting your site.
+categories: []
+keywords: []
+menu:
+ docs:
+ identifier: troubleshooting-in-this-section
+ parent: troubleshooting
+ weight: 10
+weight: 10
+aliases: [/templates/template-debugging/]
+---
+
+Use these techniques when troubleshooting your site.
--- /dev/null
- 1. Log an INFO message for 6 minor releases[^1]
- 1. Log a WARN message for another 6 minor releases
+---
+title: Deprecation
+description: The Hugo project follows a formal and consistent process to deprecate functions, methods, and configuration settings.
+categories: [troubleshooting]
+keywords: []
+menu:
+ docs:
+ parent: troubleshooting
+ weight: 50
+weight: 50
+---
+
+When a project _deprecates_ something, they are telling its users:
+
+1. Don't use Thing One anymore.
+1. Use Thing Two instead.
+1. We're going to remove Thing One at some point in the future.
+
+[reasons for deprecation]: https://en.wikipedia.org/wiki/Deprecation
+
+Common [reasons for deprecation]:
+
+- A feature has been replaced by a more powerful alternative.
+- A feature contains a design flaw.
+- A feature is considered extraneous, and will be removed in the future in order to simplify the system as a whole.
+- A future version of the software will make major structural changes, making it impossible or impractical to support older features.
+- Standardization or increased consistency in naming.
+- A feature that once was available only independently is now combined with its co-feature.
+
+After the project team deprecates something in code, Hugo will:
+
++1. Log an INFO message for 3 minor releases[^1]
++1. Log a WARN message for another 12 minor releases
+1. Log an ERROR message and fail the build thereafter
+
++The project team will:
++
++1. On the deprecation date, update the documentation with a note describing the deprecation and any relevant alternatives.
++1. Remove the code six or more minor releases after Hugo begins logging ERROR messages and failing the build. At that point, Hugo will throw an error, but the error message will no longer mention the deprecation.
++1. Remove the corresponding documentation two years after the deprecation date.
++
+To see the INFO messages, you must use the `--logLevel` command line flag:
+
+```text
+hugo --logLevel info
+```
+
+To limit the output to deprecation notices:
+
+```text
+hugo --logLevel info | grep deprecate
+```
+
+Run the above command every time you upgrade Hugo.
+
+[^1]: For example, v0.1.1 => v0.2.0 is a minor release.
--- /dev/null
- You may have an `index.md` file instead of an `_index.md` file. See [details](/content-management/page-bundles/).
+---
+title: Frequently asked questions
+linkTitle: FAQs
+description: These questions are frequently asked by new users.
+categories: [troubleshooting]
+keywords: [faq]
+menu:
+ docs:
+ parent: troubleshooting
+ weight: 70
+weight: 70
+---
+
+Hugo’s [forum] is an active community of users and developers who answer questions, share knowledge, and provide examples. A quick search of over 20,000 topics will often answer your question. Please be sure to read about [requesting help] before asking your first question.
+
+These are just a few of the questions most frequently asked by new users.
+
+###### An error message indicates that a feature is not available. Why? {#feature-not-available}
+
+{{% include "installation/_common/01-editions.md" %}}
+
+When you attempt to use a feature that is not available in the edition that you installed, Hugo throws this error:
+
+```go-html-template
+this feature is not available in this edition of Hugo
+```
+
+To resolve, install a different edition based on the feature table above. See the [installation] section for details.
+
+###### Why do I see "Page Not Found" when visiting the home page?
+
+In the `content/_index.md` file:
+
+ - Is `draft` set to `true`?
+ - Is the `date` in the future?
+ - Is the `publishDate` in the future?
+ - Is the `expiryDate` in the past?
+
+If the answer to any of these questions is yes, either change the field values, or use one of these command line flags: `--buildDrafts`, `--buildFuture`, or `--buildExpired`.
+
+###### Why is a given page not published?
+
+In the `content/section/page.md` file, or in the `content/section/page/index.md` file:
+
+- Is `draft` set to `true`?
+- Is the `date` in the future?
+- Is the `publishDate` in the future?
+- Is the `expiryDate` in the past?
+
+If the answer to any of these questions is yes, either change the field values, or use one of these command line flags: `--buildDrafts`, `--buildFuture`, or `--buildExpired`.
+
+###### Why can't I see any of a page's descendants?
+
- ###### What is the difference between an index.md file and an _index.md file?
++You may have an `index.md` file instead of an `_index.md` file. See [details](/content-management/page-bundles/).
+
- A directory with an `index.md file` is a [leaf bundle](g). A directory with an `_index.md` file is a [branch bundle](g). See [details](/content-management/page-bundles/).
++###### What is the difference between an `index.md` file and an `_index.md` file?
+
++A directory with an `index.md file` is a [leaf bundle](g). A directory with an `_index.md` file is a [branch bundle](g). See [details](/content-management/page-bundles/).
+
+###### Why is my partial template not rendered as expected?
+
+You may have neglected to pass the required [context](g) when calling the partial. For example:
+
+```go-html-template
+{{/* incorrect */}}
+{{ partial "_internal/pagination.html" }}
+
+{{/* correct */}}
+{{ partial "_internal/pagination.html" . }}
+```
+
+###### In a template, what's the difference between `:=` and `=` when assigning values to variables?
+
+Use `:=` to initialize a variable, and use `=` to assign a value to a variable that has been previously initialized. See [details](https://pkg.go.dev/text/template#hdr-Variables).
+
+###### When I paginate a list page, why is the page collection not filtered as specified?
+
+You are probably invoking the [`Paginate`] or [`Paginator`] method more than once on the same page. See [details](/templates/pagination/).
+
+###### Why are there two ways to call a shortcode?
+
+Use the `{{%/* shortcode */%}}` notation if the shortcode template, or the content between the opening and closing shortcode tags, contains Markdown. Otherwise use the\
+`{{</* shortcode */>}}` notation. See [details](/content-management/shortcodes/).
+
+###### Can I use environment variables to control configuration?
+
+Yes. See [details](/getting-started/configuration/#configure-with-environment-variables).
+
+###### Why am I seeing inconsistent output from one build to the next?
+
+The most common causes are page collisions (publishing two pages to the same path) and the effects of concurrency. Use the `--printPathWarnings` command line flag to check for page collisions, and create a topic on the [forum] if you suspect concurrency problems.
+
+###### Why isn't Hugo's development server detecting file changes?
+
+In its default configuration, Hugo's file watcher may not be able detect file changes when:
+
+- Running Hugo within Windows Subsystem for Linux (WSL/WSL2) with project files on a Windows partition
+- Running Hugo locally with project files on a removable drive
+- Running Hugo locally with project files on a storage server accessed via the NFS, SMB, or CIFS protocols
+
+In these cases, instead of monitoring native file system events, use the `--poll` command line flag. For example, to poll the project files every 700 milliseconds, use `--poll 700ms`.
+
+###### Why is my page Scratch or Store missing a value?
+
+The [`Scratch`] and [`Store`] methods on a `Page` object allow you to create a [scratch pad](g) on the given page to store and manipulate data. Values are often set within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are not determinate until Hugo renders the page content.
+
+If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable:
+
+```go-html-template
+{{ $noop := .Content }}
+{{ .Store.Get "mykey" }}
+```
+
+You can trigger content rendering with other methods as well. See next FAQ.
+
+[`Scratch`]: /methods/page/scratch
+[`Store`]: /methods/page/store
+
+###### Which page methods trigger content rendering?
+
+The following methods on a `Page` object trigger content rendering: `Content`, `ContentWithoutSummary`, `FuzzyWordCount`, `Len`, `Plain`, `PlainWords`, `ReadingTime`, `Summary`, `Truncated`, and `WordCount`.
+
+{{% note %}}
+For other questions please visit the [forum]. A quick search of over 20,000 topics will often answer your question. Please be sure to read about [requesting help] before asking your first question.
+
+[forum]: https://discourse.gohugo.io
+[requesting help]: https://discourse.gohugo.io/t/requesting-help/9132
+{{% /note %}}
+
+[`Paginate`]: /methods/page/paginate/
+[`Paginator`]: /methods/page/paginator/
+[forum]: https://discourse.gohugo.io
+[installation]: /installation/
+[requesting help]: https://discourse.gohugo.io/t/requesting-help/9132
--- /dev/null
--- /dev/null
++[[banners]]
++ name = "Linode"
++ link = "https://www.linode.com/"
++ logo = "images/sponsors/linode-logo.svg"
++ utm_campaign = "hugosponsor"
++ bgcolor = "#ffffff"
++
++[[banners]]
++ name = "GoLand"
++ title = "The complete IDE crafted for professional Go developers."
++ no_query_params = true
++ link = "https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo"
++ logo = "images/sponsors/goland.svg"
++ bgcolor = "#f4f4f4"
++
++[[banners]]
++ name = "Your Company?"
++ link = "https://bep.is/en/hugo-sponsor-2023-01/"
++ utm_campaign = "hugosponsor"
++ show_on_hover = true
++ bgcolor = "#4e4f4f"
++ link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'"
--- /dev/null
-
- require github.com/gohugoio/gohugoioTheme v0.0.0-20250116152525-2d382cae7743 // indirect
+module github.com/gohugoio/hugoDocs
+
+go 1.22.0
--- /dev/null
- # This his the main configuration file. There are also environment specific configuration stored in the /config directory.
-
+baseURL = "https://gohugo.io/"
+defaultContentLanguage = "en"
+enableEmoji = true
- ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"]
++ignoreLogs = ["error-missing-instagram-accesstoken"]
+languageCode = "en-us"
+pluralizeListTitles = false
+timeZone = "Europe/Oslo"
+title = "Hugo"
+
+# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below).
+disableAliases = true
+
+[pagination]
- pagerSize = 100
++ pagerSize = 100
+
+[services.googleAnalytics]
- ID = 'G-MBZGKNMDWC'
++ ID = 'G-MBZGKNMDWC'
+
- [minify]
- [minify.tdewolff]
- [minify.tdewolff.html]
- keepWhitespace = true
++[outputs]
++ home = ["html", "rss", "redir", "headers"]
++ section = ["html"]
++ page = ["html"]
++ taxonomy = ["html"]
++ term = ["html"]
+
- [module]
- [module.hugoVersion]
- min = "0.56.0"
- [[module.imports]]
- path = "github.com/gohugoio/gohugoioTheme"
++[params]
++ description = "The world’s fastest framework for building websites"
++ ghrepo = "https://github.com/gohugoio/hugoDocs/"
+
- [outputs]
- home = ["HTML", "RSS", "REDIR", "HEADERS"]
- section = ["HTML"]
++ [params.render_hooks.link]
++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
+
- [mediaTypes]
- [mediaTypes."text/netlify"]
- delimiter = ""
++[languages]
++ [languages.en]
++ languageName = "English"
++ weight = 1
++
++[security]
++ enableInlineShortcodes = false
++ [security.funcs]
++ getenv = ['^HUGO_', '^REPOSITORY_URL$', '^BRANCH$']
++ [security.http]
++ methods = ['(?i)GET|POST']
++ urls = ['.*']
+
+[outputFormats]
- [outputFormats.REDIR]
- mediatype = "text/netlify"
- baseName = "_redirects"
- isPlainText = true
- notAlternative = true
- [outputFormats.HEADERS]
- mediatype = "text/netlify"
- baseName = "_headers"
- isPlainText = true
- notAlternative = true
-
- [caches]
- [caches.getjson]
- dir = ":cacheDir/:project"
- maxAge = -1
- [caches.getcsv]
- dir = ":cacheDir/:project"
- maxAge = -1
- [caches.images]
- dir = ":cacheDir/images"
- maxAge = "1440h"
- [caches.assets]
- dir = ":resourceDir/_gen"
- maxAge = -1
- [caches.getresource]
- dir = ":cacheDir/:project"
- maxage = '1h'
-
- [related]
- threshold = 80
- includeNewer = true
- toLower = false
- [[related.indices]]
- name = "keywords"
- weight = 60
- [[related.indices]]
- # Can be used as a front matter slice to link to other page fragments (headings) using their ID.
- # This isn't particular useful in the current docs, but we're planning on getting a auto generated
- # reference section with a better ID setup.
- # For now, we just use it to give pages with same headings some similarity score.
- name = "fragmentrefs"
- type = "fragments"
- applyFilter = false
- weight = 60
- cardinalityThreshold = 50
-
- [imaging]
- # See https://github.com/disintegration/imaging
- # CatmullRom is a sharp bicubic filter which should fit the docs site well with its many screenshots.
- # Note that you can also set this per image processing.
- resampleFilter = "CatmullRom"
- # Default JPEG quality setting. Default is 75.
- quality = 75
- anchor = "smart"
-
- [taxonomies]
- category = "categories"
-
- [[cascade]]
- categories = ['commands']
- [cascade._target]
- path = '/commands/**'
++ [outputFormats.redir]
++ mediatype = "text/netlify"
++ baseName = "_redirects"
++ isPlainText = true
++ [outputFormats.headers]
++ mediatype = "text/netlify"
++ baseName = "_headers"
++ isPlainText = true
++ notAlternative = true
++
++[markup]
++ [markup.highlight]
++ style = 'solarized-dark'
++ lineNumbersInTable = true
++ noClasses = false
++ wrapperClass = 'highlight not-prose'
++
++ [markup.goldmark.renderer]
++ hardWraps = false
++ unsafe = false
++ xhtml = false
++
++ [markup.goldmark.extensions]
++ definitionList = true
++ footnote = true
++ linkify = true
++ strikethrough = true
++ table = true
++ taskList = true
++ typographer = true
++
++ [markup.goldmark.extensions.passthrough]
++ enable = true
++
++ [markup.goldmark.extensions.passthrough.delimiters]
++ block = [['\[', '\]'], ['$$', '$$']]
++ inline = [['\(', '\)']]
++
++ [markup.goldmark.parser]
++ autoHeadingID = true
++ autoHeadingIDType = "github"
++
++ [markup.goldmark.parser.attribute]
++ block = true
++ title = true
++
++[mediaTypes]
++ [mediaTypes."text/netlify"]
++ delimiter = ""
++
++[module]
++ [module.hugoVersion]
++ min = "0.141.0"
++ [[module.mounts]]
++ source = "assets"
++ target = "assets"
++ [[module.mounts]]
++ lang = 'en'
++ source = 'content/en'
++ target = 'content'
++ [[module.mounts]]
++ source = "hugo_stats.json"
++ target = "assets/notwatching/hugo_stats.json"
++ disableWatch = true
++
++[build]
++ [build.buildStats]
++ disableIDs = true
++ enable = true
++ [[build.cachebusters]]
++ source = "assets/notwatching/hugo_stats\\.json"
++ target = "css"
++ [[build.cachebusters]]
++ source = "(postcss|tailwind)\\.config\\.js"
++ target = "css"
++
++[server]
++ [[server.headers]]
++ for = "/*"
++
++ [server.headers.values]
++ X-Frame-Options = "DENY"
++ X-XSS-Protection = "1; mode=block"
++ X-Content-Type-Options = "nosniff"
++ Referrer-Policy = "no-referrer"
++
++ [[server.headers]]
++ for = "/**.{css,js}"
++
++[minify]
++ [minify.tdewolff]
++ [minify.tdewolff.html]
++ keepSpecialComments = true
++ keepWhitespace = false
++
++######## GLOBAL ITEMS TO BE SHARED WITH THE HUGO SITES ########
++[menus]
++ [[menus.global]]
++ name = 'News'
++ weight = 1
++ identifier = 'news'
++ pageRef = '/news/'
++
++ [[menus.global]]
++ name = 'Docs'
++ weight = 5
++ identifier = 'docs'
++ url = '/documentation/'
++
++ [[menus.global]]
++ name = 'Themes'
++ weight = 10
++ identifier = 'themes'
++ url = 'https://themes.gohugo.io/'
++
++ [[menus.global]]
++ name = 'Community'
++ weight = 150
++ identifier = 'community'
++ post = 'external'
++ url = 'https://discourse.gohugo.io/'
++
++ [[menus.global]]
++ name = 'GitHub'
++ weight = 200
++ identifier = 'github'
++ post = 'external'
++ url = 'https://github.com/gohugoio/hugo'
--- /dev/null
- use ../gohugoioTheme
+go 1.22.0
+
+use .
++
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ <main class="grid min-h-full place-items-center px-6 py-24 sm:py-32 lg:px-8">
++ <div class="text-center">
++ <h1
++ class="mt-4 text-5xl font-semibold tracking-tight text-balance text-gray-900 sm:text-7xl dark:text-gray-300">
++ Page not found
++ <img
++ src="{{ `images/gopher-side_color.svg` | relURL }}"
++ alt="gopher"
++ class="w-32 ml-12 float-right" />
++ </h1>
++
++ <div class="mt-10 flex items-center justify-center gap-x-6">
++ <a
++ href="{{ site.Home.RelPermalink }}"
++ class="rounded-md bg-blue-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs hover:bg-blue-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
++ >Go back home</a
++ >
++ </div>
++ </div>
++ </main>
++{{ end }}
--- /dev/null
--- /dev/null
++<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}
++ {{- if in (slice 2 3 4 6) .Level }}{{" " -}}
++ <a class="anchor" name="{{ .Anchor }}"></a>
++ <a class="inline-flex items-center" href="#{{ .Anchor | safeURL }}" aria-label="Anchor">
++ <svg class="fill-primary hover:fill-primary/70 w-4 h-4">
++ <use href="#icon--anchor"></use>
++ </svg>
++ </a>
++{{- end -}}
++</h{{ .Level }}>
--- /dev/null
- <a
+{{- /* Last modified: 2025-01-19T14:44:56-08:00 */}}
+
+{{- /*
+Copyright 2025 Veriphor LLC
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+*/}}
+
+{{- /*
+This render hook resolves internal destinations by looking for a matching:
+
+ 1. Content page
+ 2. Page resource (a file in the current page bundle)
+ 3. Section resource (a file in the current section)
+ 4. Global resource (a file in the assets directory)
+
+It skips the section resource lookup if the current page is a leaf bundle.
+
+External destinations are not modified.
+
+You must place global resources in the assets directory. If you have placed
+your resources in the static directory, and you are unable or unwilling to move
+them, you must mount the static directory to the assets directory by including
+both of these entries in your site configuration:
+
+ [[module.mounts]]
+ source = 'assets'
+ target = 'assets'
+
+ [[module.mounts]]
+ source = 'static'
+ target = 'assets'
+
+By default, if this render hook is unable to resolve a destination, including a
+fragment if present, it passes the destination through without modification. To
+emit a warning or error, set the error level in your site configuration:
+
+ [params.render_hooks.link]
+ errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
+
+When you set the error level to warning, and you are in a development
+environment, you can visually highlight broken internal links:
+
+ [params.render_hooks.link]
+ errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
+ highlightBroken = true # true or false (default)
+
+This will add a "broken" class to anchor elements with invalid src attributes.
+Add a rule to your CSS targeting the broken links:
+
+ a.broken {
+ background: #ff0;
+ border: 2px solid #f00;
+ padding: 0.1em 0.2em;
+ }
+
+This render hook may be unable to resolve destinations created with the ref and
+relref shortcodes. Unless you set the error level to ignore you should not use
+either of these shortcodes in conjunction with this render hook.
+
+@context {string} Destination The link destination.
+@context {page} Page A reference to the page containing the link.
+@context {string} PlainText The link description as plain text.
+@context {string} Text The link description.
+@context {string} Title The link title.
+
+@returns {template.html}
+*/}}
+
+{{- /* Initialize. */}}
+{{- $renderHookName := "link" }}
+
+{{- /* Verify minimum required version. */}}
+{{- $minHugoVersion := "0.141.0" }}
+{{- if lt hugo.Version $minHugoVersion }}
+ {{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }}
+{{- end }}
+
+{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}}
+{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }}
+
+{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}}
+{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }}
+
+{{- /* Validate error level. */}}
+{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }}
+ {{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }}
+{{- end }}
+
+{{- /* Determine content path for warning and error messages. */}}
+{{- $contentPath := .Page.String }}
+
+{{- /* Parse destination. */}}
+{{- $u := urls.Parse .Destination }}
+
+{{- /* Set common message. */}}
+{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }}
+
+{{- /* Set attributes for anchor element. */}}
+{{- $attrs := dict "href" $u.String }}
+{{- if eq $u.String "g" }}
+ {{- /* Destination is a glossary term. */}}
+ {{- $ctx := dict
+ "contentPath" $contentPath
+ "errorLevel" $errorLevel
+ "renderHookName" $renderHookName
+ "text" .Text
+ }}
+ {{- $attrs = partial "inline/h-rh-l/get-glossary-link-attributes.html" $ctx }}
+{{- else if $u.IsAbs }}
+ {{- /* Destination is a remote resource. */}}
+ {{- $attrs = merge $attrs (dict "rel" "external") }}
+{{- else }}
+ {{- with $u.Path }}
+ {{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }}
+ {{- /* Destination is a page. */}}
+ {{- $href := .RelPermalink }}
+ {{- with $u.RawQuery }}
+ {{- $href = printf "%s?%s" $href . }}
+ {{- end }}
+ {{- with $u.Fragment }}
+ {{- $ctx := dict
+ "contentPath" $contentPath
+ "errorLevel" $errorLevel
+ "page" $p
+ "parsedURL" $u
+ "renderHookName" $renderHookName
+ }}
+ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
+ {{- $href = printf "%s#%s" $href . }}
+ {{- end }}
+ {{- $attrs = dict "href" $href }}
+ {{- else with $.PageInner.Resources.Get $u.Path }}
+ {{- /* Destination is a page resource; drop query and fragment. */}}
+ {{- $attrs = dict "href" .RelPermalink }}
+ {{- else with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }}
+ {{- /* Destination is a section resource, and current page is not a leaf bundle. */}}
+ {{- $attrs = dict "href" .RelPermalink }}
+ {{- else with resources.Get $u.Path }}
+ {{- /* Destination is a global resource; drop query and fragment. */}}
+ {{- $attrs = dict "href" .RelPermalink }}
+ {{- else }}
+ {{- if eq $errorLevel "warning" }}
+ {{- warnf $msg }}
+ {{- if and $highlightBrokenLinks hugo.IsDevelopment }}
+ {{- $attrs = merge $attrs (dict "class" "broken") }}
+ {{- end }}
+ {{- else if eq $errorLevel "error" }}
+ {{- errorf $msg }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ {{- with $u.Fragment }}
+ {{- /* Destination is on the same page; prepend relative permalink. */}}
+ {{- $ctx := dict
+ "contentPath" $contentPath
+ "errorLevel" $errorLevel
+ "page" $.Page
+ "parsedURL" $u
+ "renderHookName" $renderHookName
+ }}
+ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
+ {{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }}
+ {{- else }}
+ {{- if eq $errorLevel "warning" }}
+ {{- warnf $msg }}
+ {{- if and $highlightBrokenLinks hugo.IsDevelopment }}
+ {{- $attrs = merge $attrs (dict "class" "broken") }}
+ {{- end }}
+ {{- else if eq $errorLevel "error" }}
+ {{- errorf $msg }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{- /* Render anchor element. */ -}}
- {{- $glossaryPath := "/getting-started/glossary" }}
++<a aria-label="{{ .PlainText }}"
+ {{- with .Title }} title="{{ . }}" {{- end }}
+ {{- range $k, $v := $attrs }}
+ {{- if $v }}
+ {{- printf " %s=%q" $k ($v | transform.HTMLEscape) | safeHTMLAttr }}
+ {{- end }}
+ {{- end -}}
+>{{ .Text }}</a>
+
+{{- define "partials/inline/h-rh-l/validate-fragment.html" }}
+ {{- /*
+ Validates the fragment portion of a link destination.
+
+ @context {string} contentPath The page containing the link.
+ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
+ @context {page} page The page corresponding to the link destination
+ @context {struct} parsedURL The link destination parsed by urls.Parse.
+ @context {string} renderHookName The name of the render hook.
+ */}}
+
+ {{- /* Initialize. */}}
+ {{- $contentPath := .contentPath }}
+ {{- $errorLevel := .errorLevel }}
+ {{- $p := .page }}
+ {{- $u := .parsedURL }}
+ {{- $renderHookName := .renderHookName }}
+
+ {{- /* Validate. */}}
+ {{- with $u.Fragment }}
+ {{- if $p.Fragments.Identifiers.Contains . }}
+ {{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
+ {{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }}
+ {{- if eq $errorLevel "warning" }}
+ {{- warnf $msg }}
+ {{- else if eq $errorLevel "error" }}
+ {{- errorf $msg }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ {{- /* Determine target path for warning and error message. */}}
+ {{- $targetPath := "" }}
+ {{- with $p.File }}
+ {{- $targetPath = .Path }}
+ {{- else }}
+ {{- $targetPath = .Path }}
+ {{- end }}
+ {{- /* Set common message. */}}
+ {{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }}
+ {{- if eq $targetPath $contentPath }}
+ {{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }}
+ {{- end }}
+ {{- /* Throw warning or error. */}}
+ {{- if eq $errorLevel "warning" }}
+ {{- warnf $msg }}
+ {{- else if eq $errorLevel "error" }}
+ {{- errorf $msg }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{- define "partials/inline/h-rh-l/get-glossary-link-attributes.html" }}
+ {{- /*
+ Returns the anchor element attributes for a link to the given glossary term.
+
+ It first checks for the existence of a glossary page for the given term. If
+ no page is found, it then checks for a glossary page for the singular form of
+ the term. If neither page exists it throws a warning or error dependent on
+ the errorLevel setting
+
+ The returned href attribute does not point to the glossary term page.
+ Instead, via its fragment, it points to an entry on the glossary page.
+
+ @context {string} contentPath The page containing the link.
+ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
+ @context {string} renderHookName The name of the render hook.
+ @context {string} text The link text.
+ */}}
+
+ {{- /* Get context.. */}}
+ {{- $contentPath := .contentPath }}
+ {{- $errorLevel := .errorLevel }}
+ {{- $renderHookName := .renderHookName }}
+ {{- $text := .text | transform.Plainify | strings.ToLower }}
+
+ {{- /* Initialize. */}}
- {{- /* Theres a better way to handle this, but it works for now. */}}
++ {{- $glossaryPath := "/quick-reference/glossary" }}
+ {{- $termGiven := $text }}
+ {{- $termActual := "" }}
+ {{- $termSingular := inflect.Singularize $termGiven }}
+
+ {{- /* Verify that the glossary page exists. */}}
+ {{- $glossaryPage := site.GetPage $glossaryPath }}
+ {{- if not $glossaryPage }}
+ {{- errorf "The %q render hook was unable to find %s: see %s" $renderHookName $glossaryPath $contentPath }}
+ {{- end }}
+
++ {{- /* There's a better way to handle this, but it works for now. */}}
+ {{- $cheating := dict
+ "chaining" "chain"
+ "localize" "localization"
+ "localized" "localization"
+ "paginating" "paginate"
+ "walking" "walk"
+ }}
+
+ {{- /* Verify that a glossary term page exists for the given term. */}}
+ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termGiven | urlize)) }}
+ {{- $termActual = $termGiven }}
+ {{- else if site.GetPage (urls.JoinPath $glossaryPath ($termSingular | urlize)) }}
+ {{- $termActual = $termSingular }}
+ {{- else }}
+ {{- $termToTest := index $cheating $termGiven }}
+ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termToTest | urlize)) }}
+ {{- $termActual = $termToTest }}
+ {{- end }}
+ {{- end }}
+
+ {{- if not $termActual }}
+ {{- errorf "The %q render hook was unable to find a glossary page for either the singular or plural form of the term %q: see %s" $renderHookName $termGiven $contentPath }}
+ {{- end }}
+
+ {{- /* Create the href attribute. */}}
+ {{- $href := ""}}
+ {{- if $termActual }}
+ {{- $href = fmt.Printf "%s#%s" $glossaryPage.RelPermalink (anchorize $termActual) }}
+ {{- end }}
+
+ {{- return (dict "href" $href) }}
+{{- end -}}
--- /dev/null
--- /dev/null
++<!doctype html>
++<html
++ class="h-full antialiased scheme-light dark:scheme-dark"
++ lang="{{ with site.Language.LanguageCode }}
++ {{ . }}
++ {{ else }}
++ en-us
++ {{ end }}
++">
++ <head>
++ <meta charset="utf-8" />
++ <title>
++ {{ .Title }}
++ </title>
++ <style>
++ [x-cloak] {
++ display: none !important;
++ }
++ </style>
++ <meta
++ name="description"
++ content="{{ .Description | default site.Params.description }}" />
++ {{ partial "layouts/head/head-js.html" . }}
++ {{ with (templates.Defer (dict "key" "global")) }}
++ {{ $t := debug.Timer "tailwindcss" }}
++ {{ with resources.Get "css/styles.css" }}
++ {{ $opts := dict
++ "inlineImports" true
++ "minify" (not hugo.IsDevelopment)
++ }}
++ {{ with . | css.TailwindCSS $opts }}
++ {{ partial "helpers/linkcss.html" (dict "r" .) }}
++ {{ end }}
++ {{ end }}
++ {{ $t.Stop }}
++ {{ end }}
++ {{ partial "layouts/head/head.html" . }}
++ </head>
++ <body class="flex flex-col min-h-full bg-white dark:bg-blue-950">
++ {{ partial "layouts/hooks/body-start.html" . }}
++ {{/* Layout. */}}
++ {{ block "header" . }}
++ {{ partial "layouts/header/header.html" . }}
++ {{ end }}
++ {{ block "hero" . }}
++ {{ end }}
++ <div class="flex w-full xl:w-6xl h-full flex-auto mx-auto">
++ <main
++ class="flex-1 mx-auto lg:mx-0 w-full max-w-3x lg:max-w-3x pt-8 lg:pt-14 pb-20 px-main">
++ {{ block "main" . }}{{ end }}
++ </main>
++ {{ block "rightsidebar" . }}
++ <aside
++ class="py-15 ml-4 xl:ml-12 w-60 hidden lg:relative lg:block lg:flex-none">
++ {{ block "rightsidebar_content" . }}{{ end }}
++ </aside>
++ {{ end }}
++ </div>
++ {{/* Common icons. */}}
++ {{ partial "layouts/icons.html" . }}
++ {{/* Footer. */}}
++ {{ block "footer" . }}
++ {{ partial "layouts/footer.html" . }}
++ {{ end }}
++ {{ partial "layouts/hooks/body-end.html" . }}
++ </body>
++</html>
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ {{ $pages := "" }}
++ {{ $showDate := false }}
++ {{ if .IsPage }}
++ {{/* We currently have a slightly odd content structure with no top level /docs section. */}}
++ {{ $pages = .CurrentSection.Pages }}
++ {{ else }}
++ {{ if eq .Section "news" }}
++ {{ $pages = partial "news/get-news-items.html" . }}
++ {{ $showDate = true }}
++ {{ else }}
++ {{ $pages = .Pages }}
++ {{ end }}
++ {{ end }}
++
++
++ <article class="">
++ {{ partial "layouts/docsheader.html" . }}
++ <div class="mt-6 sm:mt-8 grid grid-cols-2 xl:grid-cols-3 gap-4 min-h-40">
++ {{ range $pages }}
++ {{ if eq . $ }}
++ {{ continue }}
++ {{ end }}
++ <a
++ class="flex col-span-1 a--block cursor-pointer flex-col group border p-3 sm:p-4 hover:shadow-md dark:shadow-slate-800 border-gray-300 dark:border-gray-800 m-0"
++ href="{{ .RelPermalink }}">
++ {{ if $showDate }}
++ <p
++ class="text-gray-500 dark:text-gray-400 text-sm/5 md:text-base/2 mb-2 sm:mb-4">
++ {{ .Date.Format "January 2, 2006" }}
++ </p>
++ {{ end }}
++ <h3
++ class="text-lg/6 md:text-2xl tracking-tight p-0 -mt-1 sm:mt-0 mb-1 sm:mb-2 text-primary group-hover:text-primary/70 overflow-hidden">
++ {{ .LinkTitle }}
++ </h3>
++
++ {{ with .Params.action.signatures }}
++ {{/* Set in functions and methods pages. */}}
++ {{ with $signature := index . 0 }}
++ {{ if $.Params.action.returnType }}
++ {{ $signature = printf "%s ⟼ %s" $signature $.context.Params.action.returnType }}
++ {{ end }}
++ <div
++ class="font-mono font-light text-sm whitespace-nowrap mb-2 sm:mb-4 p-2 bg-slate-50 dark:bg-slate-700 border-0 mr-8 overflow-x-auto">
++ {{- $signature -}}
++ </div>
++ {{ end }}
++ {{ end }}
++ <p
++ class="text-black dark:text-gray-100 leading-6 text-sm md:text-base three-lines-ellipsis">
++ {{ if and (eq .Section "commands") .IsPage }}
++ {{ $simpleCobraCommandShort := .RawContent | strings.ReplaceRE `(?s)^##\s.+?\n\n(.+?)\n\n.*` "$1" }}
++ {{ printf "%s." $simpleCobraCommandShort }}
++ {{ else }}
++ {{ (or .Params.description .Summary) | plainify | safeHTML }}
++ {{ end }}
++ </p>
++ </a>
++ {{ end }}
++ </div>
++ </article>
++{{ end }}
++
++{{ define "rightsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ {{ $ttop := debug.Timer "single" }}
++ <article class="max-w-5xl lg:max-w-3xl">
++ {{ partial "layouts/docsheader.html" . }}
++ <div class="content" id="content">
++ {{ with .Params.description }}
++ <div class="lead">
++ {{ . | markdownify }}
++ </div>
++ {{ end }}
++
++ {{ $t := debug.Timer "single.categories" }}
++ {{ $categories := .GetTerms "categories" }}
++ {{ with $categories }}
++ <div class="mb-4 sm:mb-6 flex flex-wrap gap-2">
++ {{ range . }}
++ {{ $text := .LinkTitle }}
++ {{ $class := "" }}
++ {{ range (slice true false ) }}
++ {{ $color := partial "helpers/funcs/color-from-string.html" (dict "text" $text "dark" . "--single" "green" ) }}
++
++ {{ $prefix := "" }}
++ {{ if . }}
++ {{ $prefix = "dark:" }}
++ {{ end }}
++ {{ $class = printf "%sbg-%s-%d %stext-%s-%d border %sborder-%s-%d"
++ $prefix $color.color $color.shade1
++ $prefix $color.color $color.shade2
++ $prefix $color.color $color.shade3
++ }}
++ {{ end }}
++
++
++ <a
++ href="{{ .RelPermalink }}"
++ class="{{ $class }} text-xs h-auto tracking-widest uppercase font-light not-prose no-underline inline-block py-1 px-3 rounded-xl shadow-xs hover:opacity-80 hover:shadow-none">
++ {{ .LinkTitle }}
++ </a>
++ {{ end }}
++ </div>
++ {{ end }}
++ {{ $t.Stop }}
++
++ {{ if .Params.action.signatures }}
++ <div class="mb-4 not-prose">
++ {{- partial "docs/functions-signatures.html" . -}}
++ {{- partial "docs/functions-return-type.html" . -}}
++ {{- partial "docs/functions-aliases.html" . -}}
++ </div>
++ {{ end }}
++ {{ $t := debug.Timer "single.content" }}
++ {{ .Content }}
++ {{ $t.Stop }}
++ {{ $t := debug.Timer "single.page-edit" }}
++ {{ partial "layouts/page-edit.html" . }}
++ {{ $t.Stop }}
++ </div>
++ </article>
++ {{ $ttop.Stop }}
++{{ end }}
++
++{{ define "rightsidebar_content" }}
++ {{/* in-this-section.html depends on these being reneredc first. */}}
++ {{ $related := partial "layouts/related.html" . }}
++ {{ $toc := partial "layouts/toc.html" . }}
++ {{ if not .Params.hide_in_this_section }}
++ {{ partial "layouts/in-this-section.html" . }}
++ {{ end }}
++ {{ $related }}
++ {{ $toc }}
++{{ end }}
--- /dev/null
--- /dev/null
++/*
++ X-Frame-Options: DENY
++ X-XSS-Protection: 1; mode=block
++ X-Content-Type-Options: nosniff
++ Referrer-Policy: origin-when-cross-origin
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ <div class="flex flex-col w-full p-0 m-0">
++ {{ partial "layouts/home/opensource.html" . }}
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-14" />
++ {{ partial "layouts/home/sponsors.html" (dict "ctx" . "gtag" "home" ) }}
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-14" />
++ {{ partial "layouts/home/features.html" . }}
++ </div>
++{{ end }}
++
++{{ define "hero" }}
++ <div class="relative isolate px-6 lg:px-8">
++ <div class="mx-auto max-w-2xl pt-16">
++ <div class="text-center">
++ <img
++ src="{{ `images/hugo-logo-wide.svg`| relURL }}"
++ alt="Hugo Logo"
++ class="w-64 aspect-3/1 mx-auto mb-8" />
++ <h1
++ class="text-4xl font-bold tracking-tight text-balance text-gray-900 dark:text-gray-300 sm:text-6xl">
++ The world’s fastest framework for building websites
++ </h1>
++ <div
++ class="mt-8 text-lg font-medium text-pretty text-gray-800 dark:text-gray-400 sm:text-xl/8">
++ Hugo is one of the most popular open-source static site generators.
++ With its amazing speed and flexibility, Hugo makes building websites
++ fun again.
++ </div>
++ <div class="mt-10 flex items-center justify-center gap-x-6">
++ {{ with site.GetPage "/getting-started" }}
++ <a
++ href="{{ .RelPermalink }}"
++ class="rounded-md uppercase tracking-wide bg-blue-600 hover:bg-blue-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
++ >{{ .LinkTitle }}</a
++ >
++ {{ end }}
++ <div class="-my-5 mr-6 sm:mr-8 md:mr-0">
++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" true) }}
++ </div>
++ </div>
++ </div>
++ </div>
++ </div>
++{{ end }}
++
++{{ define "rightsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
++
++{{ define "leftsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
--- /dev/null
--- /dev/null
++# Netlify redirects. See https://www.netlify.com/docs/redirects/
++{{ range $p := .Site.Pages -}}
++{{ range .Aliases }}
++{{ . | printf "%-35s" }} {{ $p.RelPermalink -}}
++{{ end -}}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
++<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
++ <channel>
++ <title>Hugo News</title>
++ <description>Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility.</description>
++ <link>{{ .Permalink }}</link>
++ <generator>Hugo {{ hugo.Version }}</generator>
++ <language>{{ or site.Language.LanguageCode site.Language.Lang }}</language>
++ {{- with site.Copyright }}
++ <copyright>{{ . }}</copyright>
++ {{- end }}
++ {{- with .OutputFormats.Get "rss" }}
++ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
++ {{- end }}
++
++ {{- $news_items := slice }}
++
++ {{- /* Get releases from GitHub. */}}
++ {{- $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
++ {{- $releases := partial "helpers/funcs/get-remote-data.html" $u }}
++ {{- $releases = where $releases "draft" false }}
++ {{- $releases = where $releases "prerelease" false }}
++ {{- range $releases | first 20 }}
++ {{- $summary := printf
++ "Hugo %s was released on %s. See [release notes](%s) for details."
++ .tag_name
++ (.published_at | time.AsTime | time.Format "2 Jan 2006")
++ .html_url
++ }}
++ {{- $ctx := dict
++ "PublishDate" (.published_at | time.AsTime)
++ "Title" (printf "Release %s" .name)
++ "Permalink" .html_url
++ "Section" "news"
++ "Summary" ($summary | $.Page.RenderString)
++ }}
++ {{- $news_items = $news_items | append $ctx }}
++ {{- end }}
++
++ {{- /* Get content pages from news section. */}}
++ {{- range where site.RegularPages "Section" "news" }}
++ {{- $ctx := dict
++ "PublishDate" .PublishDate
++ "Title" .Title
++ "RelPermalink" .RelPermalink
++ "Section" "news"
++ "Summary" .Summary
++ "Params" (dict "description" .Description)
++ }}
++ {{- $news_items = $news_items | append $ctx }}
++ {{- end }}
++ {{- /* Sort, limit, and render lastBuildDate. */}}
++ {{- $limit := cond (gt site.Config.Services.RSS.Limit 1) site.Config.Services.RSS.Limit 999 }}
++ {{- $news_items = sort $news_items "PublishDate" "desc" | first $limit }}
++ <lastBuildDate>{{ (index $news_items 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
++
++ {{- /* Render items. */}}
++ {{- range $news_items }}
++ <item>
++ <title>{{ .Title }}</title>
++ <link>{{ .Permalink }}</link>
++ <pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
++ <guid>{{ .Permalink }}</guid>
++ <description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
++ </item>
++ {{- end }}
++ </channel>
++</rss>
--- /dev/null
--- /dev/null
++{{- with .Params.action.aliases }}
++ {{- $label := "Alias" }}
++ {{- if gt (len .) 1 }}
++ {{- $label = "Aliases" }}
++ {{- end }}
++ <p class="font-bold text-dark dark:text-light mt-2">{{ $label }}</p>
++ {{- range . }}
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- . -}}
++ </div>
++ {{- end }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- with .Params.action.returnType }}
++ <p class="font-bold text-dark dark:text-light mt-2">Returns</p>
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- . -}}
++ </div>
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- with .Params.action.signatures }}
++ <p class="font-bold text-dark dark:text-light">Syntax</p>
++ {{- range . }}
++ {{- $signature := . }}
++ {{- if $.Params.function.returnType }}
++ {{- $signature = printf "%s ⟼ %s" . $.Params.function.returnType }}
++ {{- end }}
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- $signature -}}
++ </div>
++ {{- end }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{ $colors := slice "slate" "green" "cyan" "blue" }}
++{{ with .single }}
++ {{ $colors = slice . }}
++{{ end }}
++
++{{ $shades := slice 300 400 500 }}
++{{ if not .dark }}
++ {{ $shades = slice 700 800 }}
++{{ end }}
++{{ $hash := (hash.FNV32a .text) }}
++{{ $i := mod $hash (len $colors) }}
++{{ $j := mod $hash (len $shades) }}
++{{ $color := index $colors $i }}
++{{ $shade1 := index $shades $j }}
++{{ $shade2 := 0 }}
++{{ $shade3 := 0 }}
++{{ if gt $shade1 500 }}
++ {{ $shade2 = math.Min (sub $shade1 500) 100 | int }}
++ {{ $shade3 = sub $shade1 100 }}
++{{ else }}
++ {{ $shade2 = math.Max (add $shade1 500) 700 | int }}
++ {{ $shade3 = add $shade1 200 }}
++{{ end }}
++{{ $res := dict "color" $color "shade1" $shade1 "shade2" $shade2 "shade3" $shade3 }}
++{{ return $res }}
--- /dev/null
--- /dev/null
++{{ $url := "https://api.github.com/repos/gohugoio/hugo" }}
++{{ $cacheKey := print $url (now.Format "2006-01-02") }}
++{{ $headers := dict }}
++{{ with os.Getenv "HUGO_GH_TOKEN" }}
++ {{ $headers = dict "Authorization" (printf "Bearer %s" .) }}
++{{ end }}
++{{ $opts := dict "headers" $headers "key" $cacheKey }}
++{{ $githubRepoInfo := dict }}
++{{ with try (resources.GetRemote $url $opts) }}
++ {{ with .Err }}
++ {{ warnf "Failed to get GitHub repo info: %s" . }}
++ {{ else with (.Value | transform.Unmarshal) }}
++ {{ $githubRepoInfo = dict
++ "html_url" .html_url
++ "stargazers_url" .stargazers_url
++ "watchers_count" .watchers_count
++ "stargazers_count" .stargazers_count
++ "forks_count" .forks_count
++ "contributors_url" .contributors_url
++ "releases_url" .releases_url
++ "forks_count" .forks_count
++ }}
++ {{ else }}
++ {{ errorf "Unable to get remote resource %q" $url }}
++ {{ end }}
++{{ end }}
++
++{{ return $githubRepoInfo }}
--- /dev/null
--- /dev/null
++{{/*
++Parses the serialized data from the given URL and returns a map or an array.
++
++Supports CSV, JSON, TOML, YAML, and XML.
++
++@param {string} . The URL from which to retrieve the serialized data.
++@returns {any}
++
++@example {{ partial "get-remote-data.html" "https://example.org/foo.json" }}
++*/}}
++
++{{ $url := . }}
++{{ $data := dict }}
++{{ with try (resources.GetRemote $url) }}
++ {{ with .Err }}
++ {{ errorf "%s" . }}
++ {{ else with .Value }}
++ {{ $data = .Content | transform.Unmarshal }}
++ {{ else }}
++ {{ errorf "Unable to get remote resource %q" $url }}
++ {{ end }}
++{{ end }}
++{{ return $data }}
--- /dev/null
--- /dev/null
++{{ with site.Config.Services.GoogleAnalytics.ID }}
++ <script
++ async
++ src="https://www.googletagmanager.com/gtag/js?id={{ . }}"></script>
++<script>
++ window.dataLayer = window.dataLayer || [];
++ function gtag(){dataLayer.push(arguments);}
++ gtag('js', new Date());
++
++ {{ $site := site.BaseURL | replaceRE "^https?://(www\\.)?([^/]+).*" "$2" }}
++ gtag('config', '{{ . }}', {'anonymize_ip': true, 'dimension1': '{{ $site }}', 'dimension2': '{{ getenv "BRANCH" }}'});
++
++/**
++* Function that tracks a click on an outbound link in Analytics.
++* Setting the transport method to 'beacon' lets the hit be sent
++* using 'navigator.sendBeacon' in browser that support it.
++*/
++var trackOutboundLink = function(id, url) {
++ gtag('event', 'click', {
++ 'event_category': 'outbound',
++ 'event_label': id,
++ 'transport_type': 'beacon'
++ });
++}
++
++</script>
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $r := .r }}
++{{ $attr := .attributes | default dict }}
++
++{{ if hugo.IsDevelopment }}
++ <link
++ rel="stylesheet"
++ href="{{ $r.RelPermalink }}"
++ {{ template `render-attributes` $attr }} />
++{{ else }}
++ {{ with $r | minify | fingerprint }}
++ <link
++ rel="stylesheet"
++ href="{{ .RelPermalink }}"
++ integrity="{{ .Data.Integrity }}"
++ crossorigin="anonymous"
++ {{ template `render-attributes` $attr }} />
++ {{ end }}
++{{ end }}
++
++{{ define "render-attributes" }}
++ {{- range $k, $v := . -}}
++ {{- if $v -}}
++ {{- printf ` %s=%q` $k $v | safeHTMLAttr -}}
++ {{- else -}}
++ {{- printf ` %s` $k | safeHTMLAttr -}}
++ {{- end -}}
++ {{- end -}}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $r := .r }}
++{{ $attr := .attributes | default dict }}
++{{ if hugo.IsDevelopment }}
++ <script
++ src="{{ $r.RelPermalink }}"
++ {{ template `render-attributes` $attr }}></script>
++{{ else }}
++ {{ with $r | fingerprint }}
++ <script
++ src="{{ .RelPermalink }}"
++ integrity="{{ .Data.Integrity }}"
++ crossorigin="anonymous"
++ {{ template `render-attributes` $attr }}></script>
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $image := .image }}
++{{ $width := .width | default 1000 }}
++{{ $width1x := div $width 2 }}
++{{ $imageWebp := $image.Resize (printf "%dx webp" $width) }}
++{{ $image1x := $image.Resize (printf "%dx" $width1x) }}
++{{ $image1xWebp := $image.Resize (printf "%dx webp" $width1x) }}
++{{ $class := .class | default "h-64 tablet:h-96 lg:h-full w-full object-cover lg:absolute" }}
++<picture>
++ <source
++ srcset="{{ $imageWebp.RelPermalink }}"
++ type="image/webp"
++ media="(min-width: 1200px)" />
++ <source
++ srcset="{{ $image.RelPermalink }}"
++ type="image/jpeg"
++ media="(min-width: 1200px)" />
++ <source srcset="{{ $image1xWebp.RelPermalink }}" type="image/webp" />
++ <source srcset="{{ $image1x.RelPermalink }}" type="image/jpeg" />
++ <img
++ class="{{ $class }}"
++ src="{{ $image1x.RelPermalink }}"
++ alt=""
++ width="{{ $image1x.Width }}"
++ height="{{ $image1x.Height }}" />
++</picture>
--- /dev/null
--- /dev/null
++{{ $title := .title | default "" }}
++{{ $color := .color | default "yellow" }}
++{{ $icon := .icon | default "exclamation" }}
++{{ $text := .text | default "" }}
++{{ $class := .class | default "mt-6 mb-8" }}
++<div
++ class="border-l-4 overflow-x-auto border-{{ $color }}-400 bg-{{ $color }}-50 dark:bg-{{ $color }}-950 border-1 border-{{ $color }}-100 dark:border-{{ $color }}-900 p-4 {{ $class }}">
++ <div class="flex">
++ <div class="shrink-0">
++ <svg class="fill-{{ $color }}-500 dark:fill-{{ $color }}-400 h-7 w-7">
++ <use href="#icon--{{ $icon }}"></use>
++ </svg>
++ </div>
++ <div class="ml-3">
++ {{ with $title }}
++ <h3 class="text-{{ $color }}-800">
++ {{ . }}
++ </h3>
++ {{ end }}
++ <div class="mt-2">
++ <p>
++ {{ $text }}
++ </p>
++ </div>
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++<div x-data="{open: false}">
++ <div @click="open = true">
++ {{ .modal_button }}
++ </div>
++ <div
++ x-cloak
++ x-show="open"
++ x-transition:enter.opacity.duration.200ms
++ x-transition:leave.opacity.duration.300ms
++ x-trap.inert.noscroll="open"
++ @keydown.esc.window="open = false"
++ @click.self="open = false"
++ class="fixed inset-0 z-30 flex items-end justify-center bg-black/50 pb-8 backdrop-blur-xs sm:items-center"
++ role="dialog"
++ aria-modal="true"
++ aria-label="Modal">
++ <div
++ x-show="open"
++ x-transition:enter.opacity.scale.60.origin.top.right.duration.300ms.delay.200ms
++ class="flex content-center items-center justify-center max-w-lg flex-col overflow-hidden bg-white dark:bg-blue-950 border-2 border-gray-300 dark:border-gray-800 shadow-lg sm:shadow-xl">
++ <div
++ class="border-b border-outline border-gray-300 dark:border-gray-800 p-2 lg:p-4">
++ <h3 class="text-sm font-semibold">
++ {{ .modal_title }}
++ </h3>
++ </div>
++ {{ .modal_content }}
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $documentation := site.GetPage "/documentation" }}
++
++
++<nav aria-label="breadcrumb" class="flex breadcrumbs">
++ <ol class="inline-flex items-center flex-wrap tracking-tight">
++ {{ $currentSection := .CurrentSection }}
++ {{ $ancestors := .Ancestors.Reverse }}
++ {{ range $i, $p := $ancestors }}
++ {{ $isCurrentSection := eq $p $currentSection }}
++ {{/* We currently have a slightly odd structure. */}}
++ {{ if eq $p site.Home }}
++ {{ $p = $documentation }}
++ {{ end }}
++ <li class="flex items-center">
++ {{ $isLast := eq $i (sub (len $ancestors) 1) }}
++ <a
++ href="{{ $p.RelPermalink }}"
++ class="truncate text-blue-600 hover:text-blue-500 {{ if $isCurrentSection }}
++ current-section
++ {{ end }}"
++ >{{ $p.LinkTitle }}</a
++ >
++ {{ if ne $ $documentation }}
++ {{ template "breadcrumbs-arrow" . }}
++ {{ end }}
++ </li>
++ {{ end }}
++ {{ if ne $ $documentation }}
++ {{ $isCurrentSection := eq $ $currentSection }}
++ <li
++ class="truncate text-gray-700 dark:text-gray-300 {{ if $isCurrentSection }}
++ current-section
++ {{ end }}">
++ {{ $.LinkTitle }}
++ </li>
++ {{ end }}
++ </ol>
++</nav>
++
++{{ define "breadcrumbs-arrow" }}
++ <svg class="fill-gray-500 dark:fill-gray-100 w-3 h-3 mx-2">
++ <use href="#icon--chevron-right"></use>
++ </svg>
++{{ end }}
--- /dev/null
--- /dev/null
++<header>
++ {{ partial "layouts/breadcrumbs.html" . }}
++ {{ if and .IsPage (not (eq .Layout "list")) }}
++ <h1
++ class="font-display mt-6 sm:mt-8 text-3xl tracking-tight text-slate-900 dark:text-white">
++ {{ .Title }}
++ </h1>
++ {{ end }}
++</header>
--- /dev/null
--- /dev/null
++{{/* This is currently not in use, but kept in case I change my mind. */}}
++<nav
++ role="navigation"
++ id="explorer"
++ class="overflow-x-hidden w-54"
++ x-data="explorer"
++ data-turbo-permanent
++ @turbo:load.window="onLoad()"
++ @turbo:before-render.window="onBeforeRender()"
++ x-cloak>
++ <ul class="w-full">
++ {{ $root := site.GetPage "/" }}
++ {{ template "docs-explorer-section" (dict "p" $root "level" 0 ) }}
++ </ul>
++</nav>
++
++{{ define "docs-explorer-section" }}
++ {{ $p := .p }}
++ {{ $level := .level }}
++ {{ $pleft := $level }}
++ {{ if gt $level 0 }}
++ {{ $pleft = add $level 1 }}
++ {{ end }}
++ {{ $pl := printf "pl-%d" $pleft }}
++ {{ $pages := $p.Sections }}
++
++ {{ range $pages }}
++ {{ $hasChildren := gt (len .Pages) 0 }}
++ {{ $class := cond (eq $level 0) "text-primary hover:text-primary/70" "text-gray-900 dark:text-gray-400 hover:dark:text-gray-300" }}
++ <li class="w-full">
++ <a
++ @click="toggleNode('{{ .RelPermalink }}')"
++ href="{{ .RelPermalink }}"
++ x-ref="{{ .RelPermalink }}"
++ :class="isCurrent('{{ .RelPermalink }}') ? 'font-bold underline': 'font-normal'"
++ class="block cursor-pointer {{ $pl }} {{ $class }} focus:font-bold hover:underline focus:underline tracking-tight leading-7">
++ {{ .LinkTitle }}
++ </a>
++ {{ if $hasChildren }}
++ <ul class="w-full" x-show="isOpen('{{ .RelPermalink }}')">
++ {{ template "docs-explorer-section" (dict "p" . "level" (add $level 1)) }}
++ </ul>
++ {{ end }}
++ </li>
++ {{ end }}
++
++{{ end }}
--- /dev/null
--- /dev/null
++<footer class="print:hidden bg-blue-950 mt-8 sm:mt-24 border-t-1 border-gray-800">
++ <div class="mx-auto max-w-7xl pt-16 pb-8 sm:pt-18 lg:pt-20">
++ <div class="xl:grid xl:grid-cols-3 xl:gap-8">
++ {{/* Column 1 */}}
++ <div class="flex flex-col items-center justify-between space-y-8">
++ <div class="text-gray-200">
++ By the
++ <a
++ href="https://github.com/gohugoio/hugo/graphs/contributors"
++ class="text-blue-300 hover:underline"
++ >Hugo Authors</a
++ ><br />
++ </div>
++
++ <img
++ src="/images/hugo-logo-wide.svg"
++ alt="Hugo Logo"
++ class="aspect-3/1 w-40" />
++
++ <ul class="space-y-2 text-gray-200">
++ <li class="hover:text-white">
++ <a href="https://fosstodon.org/@gohugoio" class="">@GoHugoIO</a>
++ </li>
++ <li class="hover:text-white">
++ <a href="https://twitter.com/spf13" class="">@spf13</a>
++ </li>
++ <li class="hover:text-white">
++ <a href="https://twitter.com/bepsays" class="">@bepsays</a>
++ </li>
++ <li class="mt-6">
++ <a
++ href="https://github.com/gohugoio/hugo/issues/new"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >File an issue</a
++ >
++ </li>
++ <li>
++ <a
++ href="https://discourse.gohugo.io/"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >Get help</a
++ >
++ </li>
++ <li>
++ <a
++ href="https://themes.gohugo.io/"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >Find a theme</a
++ >
++ </li>
++ </ul>
++ </div>
++
++ {{/* Sponsors */}}
++ <div
++ class="mt-16 xl:mt-0 col-span-2 text-gray-200 max-w-3xl flex items-center content-center justify-center mx-auto">
++ {{ partial "layouts/home/sponsors.html" (dict
++ "ctx" .
++ "gtag" "footer"
++
++ )
++ }}
++ </div>
++ </div>
++ <div class="mt-16 border-t border-white/10 pt-8 sm:mt-20 lg:mt-24">
++ <p class="text-sm/6 text-gray-200">
++ The Hugo logos are copyright © Steve Francia 2013–{{ now.Year }}. The
++ Hugo Gopher is based on an original work by Renée French.
++ </p>
++ </div>
++ </div>
++</footer>
--- /dev/null
--- /dev/null
++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }}
++{{ $opts := dict "minify" true }}
++{{ with resources.Get "js/head-early.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "async" "")) }}
++{{ end }}
++{{ with resources.Get "js/main.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }}
++{{ end }}
++{{ with resources.Get "js/turbo.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }}
++{{ end }}
--- /dev/null
--- /dev/null
++<meta charset="utf-8" />
++
++<meta http-equiv="X-UA-Compatible" content="IE=edge" />
++<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
++{{ hugo.Generator }}
++
++{{ if hugo.IsProduction }}
++ <meta name="robots" content="index, follow" />
++{{ else }}
++ <meta name="robots" content="noindex, nofollow" />
++{{ end }}
++
++<title>
++ {{ with .Title }}{{ . }} |{{ end }}
++ {{ .Site.Title }}
++</title>
++
++<link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png>
++<link rel=icon type=image/png href=/favicon-32x32.png sizes=32x32>
++<link rel=icon type=image/png href=/favicon-16x16.png sizes=16x16>
++<link rel=manifest href=/manifest.json>
++<link rel=mask-icon href=/safari-pinned-tab.svg color=#0594cb>
++
++<meta name="turbo-prefetch" content="true">
++<meta name="view-transition" content="same-origin">
++
++{{ range .AlternativeOutputFormats -}}
++ <link
++ rel="{{ .Rel }}"
++ type="{{ .MediaType.Type }}"
++ href="{{ .RelPermalink | safeURL }}" />
++{{ end -}}
++
++
++<meta
++ name="description"
++ content="{{ with .Description }}
++ {{ . }}
++ {{ else }}
++ {{ with .Site.Params.description }}{{ . }}{{ end }}
++ {{ end }}
++ " />
++
++
++
++{{ partial "opengraph/opengraph.html" . }}
++{{- template "_internal/schema.html" . -}}
++{{- template "_internal/twitter_cards.html" . -}}
++
++{{ if hugo.IsProduction }}
++ {{ partial "helpers/gtag.html" . }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ with partialCached "helpers/funcs/get-github-info.html" . "-" }}
++ <a
++ href="{{ .html_url | safeURL }}"
++ target="_blank"
++ class="font-normal font-mono tracking-tighter flex items-center bg-gray-100 hover:bg-gray-200 dark:bg-gray-600 dark:hover:bg-gray-700 text-sm text-black dark:text-white h-10 border-none cursor-pointer relative py-1 px-2 rounded-md"
++ aria-label="Star on GitHub">
++ <svg class="mr-[4px] fill-gray-800 dark:fill-gray-100 w-6 h-6">
++ <use href="#icon--github"></use>
++ </svg>
++ <span class="hidden md:inline mr-[3px]">Star</span>
++ <span class="hidden md:inline">{{ .stargazers_count }}</span>
++ <span class="inline md:hidden">
++ {{ printf "%0.1fk" (div .stargazers_count 1000) }}
++ </span>
++ </a>
++{{ end }}
--- /dev/null
--- /dev/null
++<header
++ x-data="navbar"
++ class="print:hidden sticky top-0 z-50 bg-blue-950 flex flex-none flex-wrap items-center justify-between px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 sm:px-6 lg:px-8 dark:shadow-none"
++ :class="$store.nav.scroll.atTop ? '': 'bg-blue-950/80'">
++ <div class="relative flex basis-0 items-cente mr-2 lg:mr-8">
++ {{ with site.Home }}
++ <a
++ class="text-white text-xl font-bold upper"
++ href="{{ .RelPermalink }}"
++ aria-label="{{ .LinkTitle }}"
++ >HUGO</a
++ >
++ {{ end }}
++ </div>
++ <div
++ class=" relative flex flex-grow basis-0 items-center min-w-24 max-w-3xl overflow-x-auto">
++ {{ range .Site.Menus.global }}
++ <a
++ href="{{ .URL }}"
++ class="font-semibold text-gray-300 hover:text-gray-400 ml-4"
++ >{{ .Name }}</a
++ >
++ {{ end }}
++
++ </div>
++
++ <div class="-my-5 pl-2 grow-0">
++ {{/* Search. */}}
++ {{ partial "layouts/search/input.html" . }}
++ </div>
++ <div
++ class="relative ml-0 md:ml-8 flex basis-0 justify-end gap-0 sm:gap-1 xl:grow-1">
++ {{/* QR code. */}}
++ {{ partial "layouts/header/qr.html" . }}
++ {{/* Theme selector. */}}
++ {{ partial "layouts/header/theme.html" . }}
++
++ {{/* Social. */}}
++ <div
++ class="hidden sm:block ml-2 sm:ml-6 h-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300">
++ {{ partial "layouts/header/githubstars.html" . }}
++ </div>
++ </div>
++</header>
--- /dev/null
--- /dev/null
++{{ $t := debug.Timer "qr" }}
++{{ $qr := partial "partials/_inline/qr" (dict
++ "page" $
++ "img_class" "w-10 bg-white view-transition-qr" )
++}}
++{{ $qrBig := partial "partials/_inline/qr" (dict "page" $ "img_class" "w-64 p-4") }}
++{{ $t.Stop }}
++<div
++ class="hidden lg:block cursor-pointer outline-2 hover:outline-3 outline-blue-500 w-10 h-10">
++ {{ partial "layouts/blocks/modal.html" (dict "modal_button" $qr "modal_content" $qrBig "modal_title" (printf "QR code linking to %s" $.Permalink )) }}
++</div>
++
++{{ define "partials/_inline/qr" }}
++ {{ $img_class := .img_class | default "w-10" }}
++ {{ with images.QR $.page.Permalink (dict "targetDir" "images/qr") }}
++
++ <img
++ src="{{ .RelPermalink }}"
++ width="{{ .Width }}"
++ height="{{ .Height }}"
++ @load="$event.target.classList.remove('_opacity-0')"
++ alt="QR code linking to {{ $.page.Permalink }}"
++ class="{{ $img_class }}" />
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++<div class="ml-2 sm:ml-6 flex items-center" x-data>
++ <button
++ @click="$store.nav.userSettings.toggleColorScheme()"
++ aria-label="Toggle color scheme"
++ id="theme-toggle"
++ type="button"
++ class="inline-flex cursor-pointer items-center p-2 bg-orange-600 hover:bg-orange-700 dark:bg-gray-600 dark:hover:bg-gray-700 border border-transparent rounded-full shadow-sm text-white hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500">
++ <svg
++ aria-hidden="true"
++ class="w-3 h-3 sm:w-5 sm:h-5"
++ fill="none"
++ stroke="currentColor"
++ viewBox="0 0 24 24"
++ xmlns="http://www.w3.org/2000/svg">
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 1"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 2"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 3"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path>
++ </svg>
++ </button>
++</div>
--- /dev/null
--- /dev/null
++{{/* icons source: https://heroicons.com/ */}}
++{{ $dataTOML := `
++ [[features]]
++ heading = "Optimized for speed"
++ copy = "Written in Go, optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a large site in seconds, often less."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z" />
++ </svg>
++ """
++ [[features]]
++ heading = "Flexible framework"
++ copy = "With its multilingual support, and powerful taxonomy system, Hugo is widely used to create documentation sites, landing pages, corporate, government, nonprofit, education, news, event, and project sites."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
++ </svg>
++ """
++ [[features]]
++ heading = "Fast assets pipeline"
++ copy = "Image processing (convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data), JavaScript bundling (tree shake, code splitting), Sass processing, great TailwindCSS support."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
++ </svg>
++ """
++ [[features]]
++ heading = "Embedded web server"
++ copy = "Use Hugo's embedded web server during development to instantly see changes to content, structure, behavior, and presentation. "
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
++ </svg>
++ """
++ `
++}}
++{{ $data := $dataTOML | transform.Unmarshal }}
++<div class="mx-auto max-w-7xl px-6 lg:px-8">
++ <div class="mx-auto max-w-2xl lg:max-w-4xl">
++ <dl
++ class="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
++ {{ range $data.features }}
++ <div class="relative pl-16">
++ <dt
++ class="text-base/7 font-semibold text-gray-900 dark:text-gray-300">
++ <div
++ class="absolute top-0 left-0 flex size-10 items-center justify-center rounded-full bg-blue-600 p-2 fill-white text-white">
++ {{ .icon | safeHTML }}
++ </div>
++ {{ .heading }}
++ </dt>
++ <dd class="mt-2 text-base/7 text-gray-600 dark:text-gray-400">
++ {{ .copy }}
++ </dd>
++ </div>
++ {{ end }}
++
++ </dl>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }}
++<div class="mx-auto max-w-7xl px-6 lg:px-8">
++ <div
++ class="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-10 lg:mx-0 lg:max-w-none lg:grid-cols-2">
++ <div class="lg:pr-8">
++ <div class="lg:max-w-lg">
++ <p
++ class="text-4xl font-bold tracking-tight text-pretty text-gray-900 dark:text-gray-300 sm:text-5xl">
++ Open source
++ </p>
++ <p class="mt-6 text-lg/8 text-gray-600 dark:text-gray-400">
++ Hugo is open source and free to use. It is distributed under the
++ Apache 2.0 License.
++ </p>
++ <dl
++ class="mt-10 max-w-xl space-y-8 text-base/7 text-gray-600 dark:text-gray-300 lg:max-w-none">
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-600"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M6 20.25h12m-7.5-3v3m3-3v3m-10.125-3h17.25c.621 0 1.125-.504 1.125-1.125V4.875c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125Z" />
++ </svg>
++ Popular.
++ </dt>
++ <dd class="inline ml-1">
++ As of writing this, Hugo has
++ {{ $githubInfo.stargazers_count }}
++ stars on GitHub. Join the crowd and hit the
++ <a
++ class="text-blue-600 hover:text-blue-700 font-semibold"
++ href="https://github.com/gohugoio/hugo"
++ >Star button</a
++ >.
++ </dd>
++ </div>
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-600"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="m20.893 13.393-1.135-1.135a2.252 2.252 0 0 1-.421-.585l-1.08-2.16a.414.414 0 0 0-.663-.107.827.827 0 0 1-.812.21l-1.273-.363a.89.89 0 0 0-.738 1.595l.587.39c.59.395.674 1.23.172 1.732l-.2.2c-.212.212-.33.498-.33.796v.41c0 .409-.11.809-.32 1.158l-1.315 2.191a2.11 2.11 0 0 1-1.81 1.025 1.055 1.055 0 0 1-1.055-1.055v-1.172c0-.92-.56-1.747-1.414-2.089l-.655-.261a2.25 2.25 0 0 1-1.383-2.46l.007-.042a2.25 2.25 0 0 1 .29-.787l.09-.15a2.25 2.25 0 0 1 2.37-1.048l1.178.236a1.125 1.125 0 0 0 1.302-.795l.208-.73a1.125 1.125 0 0 0-.578-1.315l-.665-.332-.091.091a2.25 2.25 0 0 1-1.591.659h-.18c-.249 0-.487.1-.662.274a.931.931 0 0 1-1.458-1.137l1.411-2.353a2.25 2.25 0 0 0 .286-.76m11.928 9.869A9 9 0 0 0 8.965 3.525m11.928 9.868A9 9 0 1 1 8.965 3.525" />
++ </svg>
++ Active.
++ </dt>
++ <dd class="inline ml-1">
++ Hugo has a large and active community. If you have questions or
++ need help, you can ask in the
++ <a
++ class="text-blue-600 hover:text-blue-700 font-semibold"
++ href="https://discourse.gohugo.io"
++ >Hugo forums</a
++ >.
++ </dd>
++ </div>
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-600"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h1.5C5.496 19.5 6 18.996 6 18.375m-3.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-1.5A1.125 1.125 0 0 1 18 18.375M20.625 4.5H3.375m17.25 0c.621 0 1.125.504 1.125 1.125M20.625 4.5h-1.5C18.504 4.5 18 5.004 18 5.625m3.75 0v1.5c0 .621-.504 1.125-1.125 1.125M3.375 4.5c-.621 0-1.125.504-1.125 1.125M3.375 4.5h1.5C5.496 4.5 6 5.004 6 5.625m-3.75 0v1.5c0 .621.504 1.125 1.125 1.125m0 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m1.5-3.75C5.496 8.25 6 7.746 6 7.125v-1.5M4.875 8.25C5.496 8.25 6 8.754 6 9.375v1.5m0-5.25v5.25m0-5.25C6 5.004 6.504 4.5 7.125 4.5h9.75c.621 0 1.125.504 1.125 1.125m1.125 2.625h1.5m-1.5 0A1.125 1.125 0 0 1 18 7.125v-1.5m1.125 2.625c-.621 0-1.125.504-1.125 1.125v1.5m2.625-2.625c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125M18 5.625v5.25M7.125 12h9.75m-9.75 0A1.125 1.125 0 0 1 6 10.875M7.125 12C6.504 12 6 12.504 6 13.125m0-2.25C6 11.496 5.496 12 4.875 12M18 10.875c0 .621-.504 1.125-1.125 1.125M18 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m-12 5.25v-5.25m0 5.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125m-12 0v-1.5c0-.621-.504-1.125-1.125-1.125M18 18.375v-5.25m0 5.25v-1.5c0-.621.504-1.125 1.125-1.125M18 13.125v1.5c0 .621.504 1.125 1.125 1.125M18 13.125c0-.621.504-1.125 1.125-1.125M6 13.125v1.5c0 .621-.504 1.125-1.125 1.125M6 13.125C6 12.504 5.496 12 4.875 12m-1.5 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M19.125 12h1.5m0 0c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h1.5m14.25 0h1.5" />
++ </svg>
++ Frequent releases.
++ </dt>
++ <dd class="inline ml-1">
++ Hugo has a fast
++ <a
++ class="text-blue-600 hover:text-blue-700 font-semibold"
++ href="https://github.com/gohugoio/hugo/releases"
++ >release</a
++ >
++ cycle. The project is actively maintained and new features are
++ added regularly.
++ </dd>
++ </div>
++ </dl>
++ </div>
++ </div>
++ {{ partial "helpers/picture.html" (dict
++ "image" (resources.Get "images/hugo-github-screenshot.png")
++ "alt" "Hugo GitHub Repository"
++ "width" 640
++ "class" "w-full max-w-[38rem] ring-1 shadow-xl dark:shadow-gray-500 ring-gray-400/10")
++ }}
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $gtag := .gtag | default "unknown" }}
++{{ $gtag := .gtag | default "unknown" }}
++{{ $isFooter := (eq $gtag "footer") }}
++{{ $utmSource := cond $isFooter "hugofooter" "hugohome" }}
++{{ $containerClass := .containerClass | default "mx-auto max-w-7xl px-6 lg:px-8" }}
++{{/* TODO1 prod: onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }});"
++*/}}
++{{ with .ctx.Site.Data.sponsors }}
++ <div class="{{ $containerClass }}">
++ <h2 class="font-bold text-2xl mb-6 tracking-tighter">Hugo Sponsors</h2>
++ <div class="grid grid-cols-1 lg:grid-cols-3 gap-x-8 gap-y-6">
++ {{ range .banners }}
++ <div class="max-w-64" style="background-color: {{ .bgcolor }};">
++ {{ $query_params := .query_params | default "" }}
++ {{ $url := .link }}
++ {{ if not .no_query_params }}
++ {{ $url = printf "%s?%s%s" .link $query_params (querify "utm_source" (.utm_source | default $utmSource ) "utm_medium" (.utm_medium | default "banner") "utm_campaign" (.utm_campaign | default "hugosponsor") "utm_content" (.utm_content | default "gohugoio")) | safeURL }}
++ {{ end }}
++ {{ $logo := resources.Get .logo }}
++ {{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }}
++ <a
++ href="{{ $url }}"
++ title="{{ .title | default .name }}"
++ class="group inline-block w-full h-full shadow-md dark:shadow-gray-600"
++ {{ with .link_attr }}{{ . | safeHTMLAttr }}{{ end }}>
++ <div
++ class="flex w-full h-full p-8 items-center justify-center content-center transition duration-500 hover:scale-105 {{ if .show_on_hover }}
++ invisible group-hover:visible
++ {{ end }}">
++ {{ with $logo }}
++ {{ .Content | safeHTML }}
++ {{ else }}
++ <span class="text-4xl font-bold text-white">
++ {{ .name }}
++ </span>
++ {{ end }}
++ </div>
++ </a>
++ </div>
++ {{ end }}
++ </div>
++ </div>
++{{ end }}
--- /dev/null
--- /dev/null
++{{/* Empty for now */}}
--- /dev/null
--- /dev/null
++{{ with resources.Get "js/body-start.js" | js.Build (dict "minify" true) }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "" "")) }}
++{{ end }}
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--chevron-right" viewBox="0 0 20 20">
++ <path
++ fill-rule="evenodd"
++ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
++ clip-rule="evenodd"></path>
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--search" viewBox="0 0 20 20">
++ <path
++ d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z" />
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--anchor" viewBox="0 0 24 24">
++ <path d="M0 0h24v24H0z" fill="none" />
++ <path
++ d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" />
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--exclamation" viewBox="0 0 24 24">
++ <path
++ fill-rule="evenodd"
++ d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495ZM10 5a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 10 5Zm0 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
++ clip-rule="evenodd" />
++ </symbol>
++</svg>
++
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--copy" viewBox="0 0 24 24">
++ <path
++ fill="none"
++ stroke="currentColor"
++ stroke-width="1.5"
++ aria-hidden="true"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z"></path>
++ </symbol>
++</svg>
++
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++<symbol id="icon--github" viewBox="0 0 24 24" aria-hidden="true">
++ <path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.463 2 11.97c0 4.404 2.865 8.14 6.839 9.458.5.092.682-.216.682-.48 0-.236-.008-.864-.013-1.695-2.782.602-3.369-1.337-3.369-1.337-.454-1.151-1.11-1.458-1.11-1.458-.908-.618.069-.606.069-.606 1.003.07 1.531 1.027 1.531 1.027.892 1.524 2.341 1.084 2.91.828.092-.643.35-1.083.636-1.332-2.22-.251-4.555-1.107-4.555-4.927 0-1.088.39-1.979 1.029-2.675-.103-.252-.446-1.266.098-2.638 0 0 .84-.268 2.75 1.022A9.607 9.607 0 0 1 12 6.82c.85.004 1.705.114 2.504.336 1.909-1.29 2.747-1.022 2.747-1.022.546 1.372.202 2.386.1 2.638.64.696 1.028 1.587 1.028 2.675 0 3.83-2.339 4.673-4.566 4.92.359.307.678.915.678 1.846 0 1.332-.012 2.407-.012 2.734 0 .267.18.577.688.48 3.97-1.32 6.833-5.054 6.833-9.458C22 6.463 17.522 2 12 2Z"></path>
++</symbol>
++</svg>
--- /dev/null
--- /dev/null
++{{- with .CurrentSection.RegularPages }}
++ {{ $hasTocOrRelated := or ($.Store.Get "hasToc") ($.Store.Get "hasRelated") }}
++ <div
++ class="overflow-y-auto {{ if $hasTocOrRelated }}
++ max-h-96
++ {{ else }}
++ sticky top-[8rem] max-h-[70vh]
++ {{ end }} relative mt-2 mb-8"
++ data-turbo-preserve-scroll-container="in-this-section">
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ In this section
++ </h2>
++
++ <ul id="in-sthis-section" class="mt-2">
++ {{- range . }}
++ <li>
++ <a
++ class="text-sm {{ if eq . $ }}
++ font-bold text-blue-600 focus:font-bold dark:text-blue-200
++ hover:text-blue-600 scroll-active
++ {{ else }}
++ text-blue-600 hover:text-blue-500
++ {{ end }}"
++ href="{{ .RelPermalink }}"
++ >{{ .LinkTitle }}</a
++ >
++ </li>
++ {{- end }}
++ </ul>
++ </div>
++{{- end }}
--- /dev/null
--- /dev/null
++<div class="print:hidden">
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-16" />
++
++ <div class="text-gray-800 dark:text-gray-300 font-semibold">
++ Last updated:
++ {{ .Lastmod.Format "January 2, 2006" }}{{ with .GitInfo }}
++ :
++ <a
++ class="text-blue-600 hover:text-blue-500"
++ href="{{ $.Site.Params.ghrepo }}commit/{{ .Hash }}"
++ >{{ .Subject }} ({{ .AbbreviatedHash }})</a
++ >
++ {{ end }}
++ </div>
++
++ {{ with .File }}
++ {{ $href := printf "%sedit/master/content/%s/%s" site.Params.ghrepo $.Lang .Path }}
++ <a
++ href="{{ $href }}"
++ class="mt-4 inline-block not-prose bg-blue-600 hover:bg-blue-800 text-white hover:text-white font-bold py-2 px-4 rounded">
++ Improve this page
++ </a>
++ {{ end }}
++</div>
--- /dev/null
--- /dev/null
++{{- $heading := "See also" }}
++{{- $related := slice }}
++
++{{- if .Params.action.related }}
++ {{- $related = slice }}
++ {{- range .Params.action.related }}
++ {{- $path := . | lower }}
++ {{- with or (site.GetPage $path) ($.GetPage $path) }}
++ {{- $related = $related | append . }}
++ {{- else }}
++ {{/* TODO1 make error */}}
++ {{- warnf "The 'related' partial was unable to get page %s" . }}
++ {{- end }}
++ {{- end }}
++{{- else }}
++ {{- $related = site.RegularPages.Related . }}
++{{- end }}
++{{/* Avoid repeating pages that's listed in In this section. */}}
++{{- $related = $related | complement .CurrentSection.RegularPages | first 7 }}
++{{- with $related }}
++ {{ $.Store.Set "hasRelated" true }}
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ {{ $heading }}
++ </h2>
++ <ul class="mt-2 mb-8">
++ {{- range . }}
++ <li>
++ <a
++ class="text-sm text-blue-600 hover:text-blue-500"
++ href="{{ .RelPermalink }}"
++ >{{ .LinkTitle }}</a
++ >
++ </li>
++ {{- end }}
++ </ul>
++{{- end }}
--- /dev/null
--- /dev/null
++<button
++ {{ if .standalone }}
++ x-data @click="$dispatch('search-toggle')"
++ {{ end }}
++ type="button"
++ class="grid cursor-pointer w-full text-gray-500 lg:w-56 grid-cols-[auto_1fr_auto] items-center rounded-md px-2 sm:px-4 py-2 text-left text-xs/6 lg:text-sm/6 outline-0 sm:outline-1 -outline-offset-1 outline-gray-600">
++ <svg
++ class="pointer-events-none -ml-0.5 mr-2 size-5 sm:size-4 fill-slate-400 dark:fill-slate-500">
++ <use href="#icon--search"></use>
++ </svg>
++ <span class="hidden lg:inline">Search docs</span
++ ><kbd
++ class="hidden font-sans text-xs/4 text-gray-400 dark:text-gray-400 sm:[.os-macos_&]:block"
++ ><span class="text-gray-400/70 ">⌘</span>K</kbd
++ ><kbd
++ class="hidden font-sans text-xs/4 text-gray-400 sm:not-[.os-macos_&]:block dark:text-gray-400"
++ ><span class="text-gray-400/70">Ctrl</span> K</kbd
++ >
++</button>
--- /dev/null
--- /dev/null
++<div x-data="search" class="flex w-full">
++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" false) }}
++ {{ partial "layouts/search/results.html" . }}
++</div>
--- /dev/null
--- /dev/null
++<div
++ class="fixed inset-0 overflow-hidden z-20"
++ :class="{'fixed': open}"
++ aria-label="Search docs"
++ role="dialog"
++ aria-modal="true"
++ @keydown.right="$focus.next()"
++ @keydown.left="$focus.previous()"
++ @keydown.esc="open=false"
++ x-cloak>
++ <div class="absolute inset-0 overflow-hidden z-20" x-show="open">
++ <div class="absolute inset-0" aria-hidden="true"></div>
++
++ <div
++ class="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10"
++ @click.outside="open = false">
++ <div
++ class="pointer-events-auto w-screen max-w-md"
++ x-show="open"
++ x-transition:enter="transform transition ease-in-out duration-300 sm:duration-500"
++ x-transition:enter-start="translate-x-full"
++ x-transition:enter-end="translate-x-0"
++ x-transition:leave="transform transition ease-in-out duration-300 sm:duration-500"
++ x-transition:leave-start="translate-x-0"
++ x-transition:leave-end="translate-x-full">
++ <div
++ class="flex h-full flex-col overflow-y-scroll dark:bg-blue-950/96 bg-white py-6 shadow-sm dark:shadow-gray-800">
++ <div class="px-4 sm:px-6">
++ <div class="flex items-start justify-between">
++ <input
++ x-model.debounce.100ms="query"
++ @click="search()"
++ type="search"
++ class="text-gray-800 dark:text-gray-100 bg-white/40 dark:bg-gray-900 shadow rounded border-0 p-3 w-full"
++ placeholder="Search docs"
++ x-ref="input" />
++ </div>
++ </div>
++ <div class="relative mt-6 flex-1 px-4 sm:px-6">
++ <ul
++ role="list"
++ class="divide-y divide-gray-200 dark:divide-gray-900">
++ <template
++ x-for="[group, entries] in Object.entries(result)"
++ :key="group">
++ <li class="py-4">
++ <div
++ class="mb-1 dark:text-gray-300 font-semibold uppercase tracking-widest text-sm"
++ x-text="group"></div>
++ <template x-for="entry in entries" :key="entry.objectID">
++ <a
++ class="flex flex-nowrap space-x-4 py-2 text-sm leading-5 text-gray-900 dark:text-gray-500 hover:dark:text-gray-800 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:bg-gray-50 dark:focus:bg-gray-800 cursor-pointer transition duration-150 ease-in-out"
++ :href="entry.url">
++ <span
++ class="w-1/3 text-xs text-right text-gray-500 dark:text-gray-300"
++ x-text="entry.hierarchy.lvl1">
++ </span>
++ <div class="w-2/3">
++ <h3
++ class="text-md font-bold"
++ x-html="entry.getHeadingHTML()"></h3>
++ <template
++ x-if="entry._snippetResult && entry._snippetResult.content">
++ <div class="two-lines-ellipsis mt-1">
++ <span>…</span>
++ <span x-html="entry._snippetResult.content.value">
++ </span>
++ <span>…</span>
++ </div>
++ </template>
++ </div>
++ </a>
++ </template>
++ </li>
++ </template>
++ </ul>
++ </div>
++ </div>
++ </div>
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ with .Fragments.Headings }}
++ {{ $.Store.Set "hasToc" true }}
++ <div
++ x-data="toc"
++ class="sticky top-[8rem] h-screen overflow-y-auto overflow-x-hidden">
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ On this page
++ </h2>
++ <nav class="w-56 mt-2">
++ <ul>
++ {{ template "render-toc-level" . }}
++ </ul>
++ </nav>
++ </div>
++{{ end }}
++
++{{ define "render-toc-level" }}
++ {{ range . }}
++ {{ if and .ID (or (ge .Level 2) (lt .Level 4)) }}
++ <li>
++ <a
++ href="#{{ .ID }}"
++ x-ref="{{ .ID }}"
++ @click.stop="setActive('{{ .ID }}')"
++ class="block pb-1 text-blue-600 hover:text-blue-500{{ if gt .Level 2 }}
++ ml-2 lg:ml-3 text-sm
++ {{ else }}
++ text-sm
++ {{ end }}"
++ :class="{'font-bold dark:text-blue-200 dark:hover:text-blue-300' : activeHeading === '{{ .ID }}'}">
++ {{ .Title | safeHTML }}
++ </a>
++ </li>
++ {{ end }}
++ {{ with .Headings }}
++ <ul>
++ {{ template "render-toc-level" . }}
++ </ul>
++ {{ end }}
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $news_items := slice }}
++
++{{/* Get releases from GitHub. */}}
++{{ $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
++{{ $releases := partial "helpers/funcs/get-remote-data.html" $u }}
++{{ $releases = where $releases "draft" false }}
++{{ $releases = where $releases "prerelease" false }}
++{{ range $releases | first 20 }}
++ {{ $publishDate := .published_at | time.AsTime }}
++
++ {{/* Correct the v0.138.0 release date. See https://github.com/gohugoio/hugo/issues/13066. */}}
++ {{ if eq .name "v0.138.0" }}
++ {{ $publishDate = "2024-11-06T11:22:34Z" | time.AsTime }}
++ {{ end }}
++
++ {{ $ctx := dict
++ "Date" $publishDate
++ "Title" (printf "Release %s" .name)
++ "LinkTitle" (printf "Release %s" .name)
++ "Permalink" .html_url
++ "RelPermalink" .html_url
++ "Section" "news"
++ "Summary" ""
++ }}
++ {{ $news_items = $news_items | append $ctx }}
++{{ end }}
++
++{{/* Get content pages from news section. */}}
++{{ range .Pages }}
++ {{ $ctx := dict
++ "Date" .Date
++ "Title" .Title
++ "LinkTitle" .Title
++ "RelPermalink" .RelPermalink
++ "Section" "news"
++ "Summary" .Summary
++ "Params" (dict "description" .Description)
++ }}
++ {{ $news_items = $news_items | append $ctx }}
++{{ end }}
++
++{{/* Sort by date (descending) and render. */}}
++{{ $news_items = sort $news_items "Date" "desc" }}
++
++{{ return $news_items }}
--- /dev/null
--- /dev/null
++{{ $images := $.Resources.ByType "image" }}
++{{ $featured := $images.GetMatch "*feature*" }}
++{{ if not $featured }}
++ {{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }}
++{{ end }}
++{{ if not $featured }}
++ {{ $featured = resources.Get "/opengraph/gohugoio-card-base-1.png" }}
++ {{ $size := 80 }}
++ {{ $title := $.LinkTitle }}
++ {{ if gt (len $title) 20 }}
++ {{ $size = 70 }}
++ {{ end }}
++
++ {{ $text := $title }}
++ {{ $textOptions := dict
++ "color" "#FFF"
++ "size" $size
++ "lineSpacing" 10
++ "x" 65 "y" 80
++ "font" (resources.Get "/opengraph/mulish-black.ttf")
++ }}
++
++ {{ $featured = $featured | images.Filter (images.Text $text $textOptions) }}
++{{ end }}
++
++{{ return $featured }}
--- /dev/null
--- /dev/null
++<meta property="og:title" content="{{ .Title }}" />
++<meta
++ property="og:description"
++ content="{{ with .Description }}
++ {{ . }}
++ {{ else }}
++ {{ if .IsPage }}
++ {{ .Summary }}
++ {{ else }}
++ {{ with .Site.Params.description }}{{ . }}{{ end }}
++ {{ end }}
++ {{ end }}" />
++<meta
++ property="og:type"
++ content="{{ if .IsPage }}
++ article
++ {{ else }}
++ website
++ {{ end }}" />
++<meta property="og:url" content="{{ .Permalink }}" />
++
++{{- with $.Params.images -}}
++ {{- range first 6 . }}
++ <meta property="og:image" content="{{ . | absURL }}" />
++ {{ end -}}
++{{- else -}}
++ {{- $featured := partial "opengraph/get-featured-image.html" . }}
++ {{- with $featured -}}
++ <meta property="og:image" content="{{ $featured.Permalink }}" />
++ {{- else -}}
++ {{- with $.Site.Params.images }}
++ <meta property="og:image" content="{{ index . 0 | absURL }}" />
++ {{ end -}}
++ {{- end -}}
++{{- end -}}
++
++{{- if .IsPage }}
++ {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
++ <meta property="article:section" content="{{ .Section }}" />
++ {{ with .PublishDate }}
++ <meta
++ property="article:published_time"
++ {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
++ {{ end }}
++ {{ with .Lastmod }}
++ <meta
++ property="article:modified_time"
++ {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
++ {{ end }}
++{{- end -}}
++
++{{- with .Params.audio }}<meta property="og:audio" content="{{ . }}" />{{ end }}
++{{- with .Params.locale }}
++ <meta property="og:locale" content="{{ . }}" />
++{{ end }}
++{{- with .Site.Params.title }}
++ <meta property="og:site_name" content="{{ . }}" />
++{{ end }}
++{{- with .Params.videos }}
++ {{- range . }}
++ <meta property="og:video" content="{{ . | absURL }}" />
++ {{ end }}
++
++{{ end }}
++
++{{- /* If it is part of a series, link to related articles */}}
++{{- $permalink := .Permalink }}
++{{- $siteSeries := .Site.Taxonomies.series }}
++{{ with .Params.series }}
++ {{- range $name := . }}
++ {{- $series := index $siteSeries ($name | urlize) }}
++ {{- range $page := first 6 $series.Pages }}
++ {{- if ne $page.Permalink $permalink }}
++ <meta property="og:see_also" content="{{ $page.Permalink }}" />
++ {{ end }}
++ {{- end }}
++ {{ end }}
++
++{{ end }}
++
++{{- /* Facebook Page Admin ID for Domain Insights */}}
++{{- with site.Params.social.facebook_admin }}
++ <meta property="fb:admins" content="{{ . }}" />
++{{ end }}
--- /dev/null
--- /dev/null
++<dl>
++ {{ range .Site.Data.docs.chroma.lexers }}
++ <dt>{{ .Name }}</dt>
++ <dd>{{ with .Aliases }}{{ delimit . ", " }}{{ end }}</dd>
++ {{ end }}
++ </dl>
++
--- /dev/null
--- /dev/null
++{{- /*
++ Renders syntax-highlighted configuration data in JSON, TOML, and YAML formats.
++
++ @param {string} [config] The section of site.Data.docs.config to render.
++ @param {bool} [copy=false] If true, display a copy to clipboard button.
++ @param {string} [file] The file name to display above the rendered code.
++ @param {bool} [fm=false] If true, render the code as front matter.
++ @param {bool} [skipHeader=false] If false, omit top level key(s) when rendering a section of site.Data.docs.config.
++
++ @returns {template.HTML}
++*/}}
++
++{{- /* Initialize. */}}
++{{- $config := "" }}
++{{- $dataKey := "" }}
++{{- $copy := false }}
++{{- $file := "" }}
++{{- $fm := false }}
++{{- $skipHeader := false }}
++
++{{- /* Get parameters. */}}
++{{- $config = .Get "config" }}
++{{- $dataKey = .Get "dataKey" }}
++{{- $file = .Get "file" }}
++{{- if in (slice "false" false 0) (.Get "copy") }}
++ {{- $copy = false }}
++{{- else if in (slice "true" true 1) (.Get "copy") }}
++ {{- $copy = true }}
++{{- end }}
++{{- if in (slice "false" false 0) (.Get "fm") }}
++ {{- $fm = false }}
++{{- else if in (slice "true" true 1) (.Get "fm") }}
++ {{- $fm = true }}
++{{- end }}
++{{- if in (slice "false" false 0) (.Get "skipHeader") }}
++ {{- $skipHeader = false }}
++{{- else if in (slice "true" true 1) (.Get "skipHeader") }}
++ {{- $skipHeader = true }}
++{{- end }}
++
++{{- /* Define constants. */}}
++{{- $delimiters := dict "toml" "+++" "yaml" "---" }}
++{{- $langs := slice "yaml" "toml" "json" }}
++{{- $placeHolder := "#-hugo-placeholder-#" }}
++
++{{- /* Render. */}}
++{{- $code := "" }}
++{{- if $config }}
++ {{- $file = $file | default "hugo" }}
++ {{- $sections := (split $config ".") }}
++ {{- $configSection := index $.Site.Data.docs.config $sections }}
++ {{- $code = dict $sections $configSection }}
++ {{- if $skipHeader }}
++ {{- $code = $configSection }}
++ {{- end }}
++{{- else if $dataKey }}
++ {{- $file = $file | default $dataKey }}
++ {{- $sections := (split $dataKey ".") }}
++ {{- $code = index $.Site.Data.docs $sections }}
++{{- else }}
++ {{- $code = $.Inner }}
++{{- end }}
++<div x-data class="shortcode-code not-prose relative p-0 mt-2 mb-4 sm:mb-8">
++ <svg
++ class="absolute right-2 top-0 z-30 text-blue-600 hover:text-blue-500 cursor-pointer w-8"
++ @click="$copy($refs[$store.nav.userSettings.settings.configFileType])">
++ <use href="#icon--copy"></use>
++ </svg>
++ <nav class="relative flex" aria-label="Tabs">
++ {{ with $file }}
++ <div
++ class="flex-none text-sm px-2 content-center border-b-1 border-gray-300 dark:border-gray-700"
++ aria-lbabel="Filename">
++ {{ . }}{{ if not $fm }}.{{ end }}
++ </div>
++ {{ end }}
++ {{ range $i, $lang := $langs }}
++ {{ $isLast := eq (add $i 1) (len $langs) }}
++ <button
++ x-on:click="$store.nav.userSettings.settings.configFileType = '{{ index $langs $i }}'"
++ aria-label="{{ printf `Toggle %s` . }}"
++ class="px-3 py-2 font-semibold text-black dark:text-slate-200 border-l-1 border-t-1 {{ if $isLast }}
++ border-r-1
++ {{ end }} border-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 dark:border-gray-700 cursor-pointer relative min-w-0 flex-1 overflow-hidden text-sm no-underline text-center focus:z-10 overflow-x-auto"
++ :class="$store.nav.userSettings.settings.configFileType === '{{ index $langs $i }}' ? 'border-b-0 bg-light dark:bg-dark' : 'border-b-1'">
++ <span>
++ {{ . }}
++ </span>
++ </button>
++ {{ end }}
++ </nav>
++ {{ if $code }}
++ {{ range $i, $lang := $langs }}
++ <div
++ class="max-h-96 overflow-y-auto border-l-1 border-b-1 border-r-1 border-gray-300 dark:border-gray-700"
++ x-ref="{{ $lang }}"
++ x-cloak
++ x-transition:enter.opacity.duration.300ms
++ x-show="$store.nav.userSettings.settings.configFileType === '{{ index $langs $i }}'">
++ {{- $hCode := $code | transform.Remarshal . }}
++ {{- if and $fm (in (slice "toml" "yaml") .) }}
++ {{- $hCode = printf "%s\n%s\n%s" $placeHolder $hCode $placeHolder }}
++ {{- end }}
++ {{- $hCode = $hCode | replaceRE `\n+` "\n" }}
++ {{ highlight $hCode . "" | replaceRE $placeHolder (index $delimiters .) | safeHTML }}
++ </div>
++ {{ end }}
++ {{ end }}
++</div>
--- /dev/null
--- /dev/null
++{{- $codeLang := or (.Get "lang") "" }}
++<div
++ x-data
++ class="shortcode-code font-mono not-prose relative mt-6 mb-8 border-1 border-gray-200 dark:border-gray-800 bg-light dark:bg-dark">
++ {{ if (.Get "copy") }}
++ <svg
++ class="absolute right-2 top-2 z-30 text-blue-600 hover:text-blue-500 cursor-pointer w-6 h-6"
++ @click="$copy($refs.code)">
++ <use href="#icon--copy"></use>
++ </svg>
++ {{ end }}
++ {{- with .Get "file" -}}
++ {{- if not $codeLang }}
++ {{- $ext := strings.TrimPrefix "." (path.Ext .) }}
++ {{- $codeLang = cond (eq $ext "html") "go-html-template" $ext }}
++ {{- end }}
++ <div
++ class="san-serif text-sm inline-block leading-none pl-2 py-3 bg-gray-300 dark:bg-slate-700 dark: w-full select-none
++">
++ {{ . }}
++ </div>
++ {{- end -}}
++
++
++ <div class="" x-ref="code">
++ {{ $inner := trim .Inner "\n" | safeHTML }}
++ {{ if .Get "nocode" }}
++ {{ $inner }}
++ {{ else }}
++ {{ with $codeLang }}
++ {{ highlight $inner . "" }}
++ {{ else }}
++ <pre class="overflow-x-auto p-2 w-[93%]"><code>{{ $inner }}</code>
++ </pre>
++ {{ end }}
++ {{ end }}
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $package := (index .Params 0) }}
++{{ $listname := (index .Params 1) }}
++{{ $filter := split (index .Params 2) " " }}
++{{ $filter1 := index $filter 0 }}
++{{ $filter2 := index $filter 1 }}
++{{ $filter3 := index $filter 2 }}
++
++{{ $list := (index (index .Site.Data.docs $package) $listname) }}
++{{ $fields := after 3 .Params }}
++{{ $list := where $list $filter1 $filter2 $filter3 }}
++
++<table class="table table-bordered">
++ <tr>
++ {{ range $fields }}
++ <th>{{ . }}</th>
++ {{ end }}
++ </tr>
++ {{ range $list }}
++ <tr>
++ {{ range $k, $v := . }}
++ {{ $.Scratch.Set $k $v }}
++ {{ end }}
++ {{ range $k, $v := $fields }}
++ <td>
++ {{ $tdContent := $.Scratch.Get . }}
++ {{ if eq $k 3 }}
++ {{ printf "%v" $tdContent |
++ strings.ReplaceRE `\[` "<ol><li>" |
++ strings.ReplaceRE `\s` "</li><li>" |
++ strings.ReplaceRE `\]` "</li></ol>" |
++ safeHTML }}
++ {{ else }}
++ {{ $tdContent }}
++ {{ end}}
++ </td>
++ {{ end }}
++ </tr>
++ {{ end }}
++</table>
--- /dev/null
--- /dev/null
++{{ $package := (index .Params 0) }}
++{{ $listname := (index .Params 1) }}
++{{ $list := (index (index .Site.Data.docs $package) $listname) }}
++{{ $fields := after 2 .Params }}
++
++
++<table class="table table-bordered">
++ <tr>
++ {{ range $fields }}
++ {{ $s := . }}
++ {{ if eq $s "_key" }}
++ {{ $s = "Type" }}
++ {{ end }}
++ <th>{{ $s }}</th>
++ {{ end }}
++ </tr>
++ {{ range $k1, $v1 := $list }}
++ <tr>
++ {{ range $k2, $v2 := . }}
++ {{ $.Scratch.Set $k2 $v2 }}
++ {{ end }}
++ {{ range $fields }}
++ {{ $s := "" }}
++ {{ if eq . "_key" }}
++ {{ $s = $k1 }}
++ {{ else }}
++ {{ $s = $.Scratch.Get . }}
++ {{ end }}
++ <td>{{ $s }}</td>
++ {{ end }}
++ </tr>
++ {{ end }}
++</table>
--- /dev/null
--- /dev/null
++{{ $_hugo_config := `{ "version": 1 }` }}
++
++{{ with .Get 0 }}
++ {{ $version := printf "v%v" (strings.TrimLeft "vV" .) }}
++ {{ $href := printf "https://github.com/gohugoio/hugo/releases/tag/%s" $version }}
++ {{ $text := (printf `Deprecated in <a href="%s">%s</a>.
++%s` $href $version $.Inner) | safeHTML }}
++
++ {{ partial "layouts/blocks/alert.html" (dict
++ "text" $text
++ "color" "orange"
++ "icon" "exclamation"
++ )
++}}
++{{ else }}
++ {{ errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{- /*
++Renders an absolute URL to the source code for an embedded template.
++
++Accepts either positional or named parameters, and depends on the
++embedded_templates.toml file in the data directory.
++
++@param {string} filename The embedded template's file name, excluding extension.
++
++@returns template.HTML
++
++@example {{% et robots.txt %}}
++@example {{% et filename=robots.txt %}}
++*/}}
++
++{{- /* Get parameters. */}}
++{{- $filename := "" -}}
++{{- if .IsNamedParams -}}
++ {{- $filename = .Get "filename" -}}
++{{- else -}}
++ {{- $filename = .Get 0 -}}
++{{- end -}}
++
++{{- /* Render. */}}
++{{- with $filename -}}
++ {{- with site.Data.embedded_template_urls -}}
++ {{- with index . $filename -}}
++ {{- urls.JoinPath site.Data.embedded_template_urls.base_url . -}}
++ {{- else -}}
++ {{- errorf "The %q shortcode was unable to find a URL for the embedded template named %q. Check the name. See %s" $.Name $filename $.Position -}}
++ {{- end -}}
++ {{- else -}}
++ {{- errorf "The %q shortcode was unable to find the embedded_template_urls data file in the site's data directory. See %s" $.Name $.Position -}}
++ {{- end -}}
++{{- else -}}
++ {{- errorf "The %q shortcodes requires a named or positional parameter, the file name of the embedded template, excluding its extension. See %s" .Name .Position -}}
++{{- end -}}
--- /dev/null
- {{- $path := printf "/getting-started/glossary/%s" (urlize .) }}
+{{- /*
+Renders the definition of the given glossary term.
+
+@param {string} (.Get 0) The glossary term.
+@returns {template.HTML}
+
+@example {{% glossary-term float %}}
+@example {{% glossary-term "floating point" %}}
+*/}}
+
+{{- with .Get 0 }}
- {{ .RenderShortcodes }}{{/* Do not indent. */}}
++ {{- $path := printf "/quick-reference/glossary/%s" (urlize .) }}
+ {{- with site.GetPage $path }}
- {{- end }}
++{{ .RenderShortcodes }} {{/* Do not indent. Do not remove non-breaking space. */}}
+ {{- else }}
+ {{- errorf "The glossary term (%s) shortcode was unable to find %s: see %s" $.Name $path $.Position }}
+ {{- end }}
+{{- else }}
+ {{- errorf "The glossary term (%s) shortcode requires one positional parameter: see %s" $.Name $.Position }}
++{{- end -}}
--- /dev/null
- {{- $path := "/getting-started/glossary" }}
+{{- /*
+Renders the glossary of terms.
+
+When you call this shortcode using the {{% %}} notation, the glossary terms are
+Markdown headings (level 6) which means they are members of .Page.Fragments.
+This allows the link render hook to verify links to glossary terms.
+
+Yes, the terms themselves are pages, but we don't want to link to the pages, at
+least not right now. Instead, we want to link to the fragments rendered by this
+shortcode.
+
+@returns {template.HTML}
+
+@example {{% glossary %}}
+*/}}
- {{- with $p := .Pages.ByTitle }}
++{{- $path := "/quick-reference/glossary" }}
+{{- with site.GetPage $path }}
- {{- range $p }}
+
+ {{- /* Build and render alphabetical index. */}}
+ {{- $m := dict }}
- {{- range $p }}
++ {{- range $p := .Pages.ByTitle }}
+ {{- $k := substr .Title 0 1 | strings.ToUpper }}
+ {{- if index $m $k }}
+ {{- continue }}
+ {{- end }}
+ {{- $anchor := path.BaseName .Path | anchorize }}
+ {{- $m = merge $m (dict $k $anchor) }}
+ {{- end }}
+ {{- range $k, $v := $m }}
+[{{ $k }}](#{{ $v }}) {{/* Do not indent. */}}
+ {{- end }}
+
+ {{- /* Render glossary terms. */}}
- {{- end }}
++ {{- range $p := .Pages.ByTitle }}
+###### {{ .Title }}{{/* Do not indent. */}}
+{{ .RenderShortcodes }}{{/* Do not indent. */}}
++ {{- with .Params.reference }}
++ {{- $destination := "" }}
++ {{- with $u := urls.Parse . }}
++ {{- if $u.IsAbs }}
++ {{- $destination = $u.String }}
++ {{- else }}
++ {{- with site.GetPage $u.Path -}}
++ {{- $destination = .RelPermalink }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find the reference link %s: see %s" $.Name . $p.String }}
++ {{- end }}
++ {{- end }}
++ {{- end -}}
++ See [details]({{ $destination }}).{{/* Do not indent. */}}
++ {{- end }}
+ {{- end }}
+
+{{- else }}
+ {{- errorf "The %q shortcode was unable to get %s: see %s" .Name $path .Position}}
+{{- end }}
--- /dev/null
--- /dev/null
++{{ $text := `
++ Most of the commands for **Hugo Modules** require a newer version (>= 1.18) of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ).
++ If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.19 or newer in your Environment settings.
++
++ For more information about Go Modules, see:
++
++ * https://go.dev/wiki/Modules
++ * https://blog.golang.org/using-go-modules
++ `
++}}
++
++{{ partial "layouts/blocks/alert.html" (dict "title" "Go Modules" "text" ($text | markdownify) "color" "orange" "icon" "exclamation") }}
--- /dev/null
--- /dev/null
++{{- /*
++Returns syntax-highlighted code from the given text.
++
++This is useful as a terse way to highlight inline code snippets. Calling the
++highlight shortcode for inline snippets is verbose.
++*/}}
++
++{{- $code := .Inner | strings.TrimSpace }}
++{{- $lang := or (.Get 0) "go" }}
++{{- $opts := dict "hl_inline" true "noClasses" true }}
++{{- transform.Highlight $code $lang $opts }}
--- /dev/null
--- /dev/null
++{{- /*
++Renders the given image using the given filter, if any.
++
++@param {string} src The path to the image which must be a remote, page, or global resource.
++@param {string} [filter] The filter to apply to the image (case-insensitive).
++@param {string} [filterArgs] A comma-delimited list of arguments to pass to the filter.
++@param {bool} [example=false] If true, renders a before/after example.
++@param {int} [exampleWidth=384] Image width, in pixels, when rendering a before/after example.
++
++@returns {template.HTML}
++
++@examples
++
++ {{< img src="zion-national-park.jpg" >}}
++
++ {{< img src="zion-national-park.jpg" alt="Zion National Park" >}}
++
++ {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ >}}
++
++ {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="process"
++ filterArgs="resize 400x webp"
++ >}}
++
++ {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="colorize"
++ filterArgs="180,50,20"
++ >}}
++
++ {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ example=true
++ >}}
++
++ {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ example=true
++ exampleWidth=400
++ >}}
++
++ When using the text filter, provide the arguments in this order:
++
++ 0. The text
++ 1. The horizontal offset, in pixels, relative to the left of the image (default 20)
++ 2. The vertical offset, in pixels, relative to the top of the image (default 20)
++ 3. The font size in pixels (default 64)
++ 4. The line height (default 1.2)
++ 5. The font color (default #ffffff)
++
++ {{< img
++ src="images/examples/zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="Text"
++ filterArgs="Zion National Park,25,250,56"
++ example=true
++ >}}
++
++ When using the padding filter, provide all arguments in this order:
++
++ 0. Padding top
++ 1. Padding right
++ 2. Padding bottom
++ 3. Padding right
++ 4. Canvas color
++
++ {{< img
++ src="images/examples/zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="Padding"
++ filterArgs="20,50,20,50,#0705"
++ example=true
++ >}}
++
++*/}}
++
++{{- /* Initialize. */}}
++{{- $alt := "" }}
++{{- $src := "" }}
++{{- $filter := "" }}
++{{- $filterArgs := slice }}
++{{- $example := false }}
++{{- $exampleWidth := 384 }}
++
++{{- /* Default values to use with the text filter. */}}
++{{ $textFilterOpts := dict
++ "xOffset" 20
++ "yOffset" 20
++ "fontSize" 64
++ "lineHeight" 1.2
++ "fontColor" "#ffffff"
++ "fontPath" "https://github.com/google/fonts/raw/main/ofl/lato/Lato-Regular.ttf"
++}}
++
++{{- /* Get and validate parameters. */}}
++{{- with .Get "alt" }}
++ {{- $alt = .}}
++{{- end }}
++
++{{- with .Get "src" }}
++ {{- $src = . }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a file parameter. See %s" .Name .Position }}
++{{- end }}
++
++{{- with .Get "filter" }}
++ {{- $filter = . | lower }}
++{{- end }}
++
++{{- $validFilters := slice
++ "autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither"
++ "gamma" "gaussianblur" "grayscale" "hue" "invert" "mask" "none" "opacity"
++ "overlay" "padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text"
++ "unsharpmask"
++}}
++
++{{- with $filter }}
++ {{- if not (in $validFilters .) }}
++ {{- errorf "The filter passed to the %q shortcode is invalid. The filter must be one of %s. See %s" $.Name (delimit $validFilters ", " ", or ") $.Position }}
++ {{- end }}
++{{- end }}
++
++{{- with .Get "filterArgs" }}
++ {{- $filterArgs = split . "," }}
++ {{- $filterArgs = apply $filterArgs "trim" "." " " }}
++{{- end }}
++
++{{- if in (slice "false" false 0) (.Get "example") }}
++ {{- $example = false }}
++{{- else if in (slice "true" true 1) (.Get "example")}}
++ {{- $example = true }}
++{{- end }}
++
++{{- with .Get "exampleWidth" }}
++ {{- $exampleWidth = . | int }}
++{{- end }}
++
++{{- /* Get image. */}}
++{{- $ctx := dict "page" .Page "src" $src "name" .Name "position" .Position }}
++{{- $i := partial "inline/get-resource.html" $ctx }}
++
++{{- /* Resize if rendering before/after examples. */}}
++{{- if $example }}
++ {{- $i = $i.Resize (printf "%dx" $exampleWidth) }}
++{{- end }}
++
++{{- /* Create filter. */}}
++{{- $f := "" }}
++{{- $ctx := dict "filter" $filter "args" $filterArgs "name" .Name "position" .Position }}
++{{- if eq $filter "autoorient" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.AutoOrient }}
++{{- else if eq $filter "brightness" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Brightness (index $filterArgs 0) }}
++{{- else if eq $filter "colorbalance" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage red" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage green" "argValue" (index $filterArgs 1) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage blue" "argValue" (index $filterArgs 2) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.ColorBalance (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- else if eq $filter "colorize" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "hue" "argValue" (index $filterArgs 0) "min" 0 "max" 360) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "saturation" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 2) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Colorize (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- else if eq $filter "contrast" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Contrast (index $filterArgs 0) }}
++{{- else if eq $filter "dither" }}
++ {{- $f = images.Dither }}
++{{- else if eq $filter "gamma" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "gamma" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Gamma (index $filterArgs 0) }}
++{{- else if eq $filter "gaussianblur" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.GaussianBlur (index $filterArgs 0) }}
++{{- else if eq $filter "grayscale" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Grayscale }}
++{{- else if eq $filter "hue" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "shift" "argValue" (index $filterArgs 0) "min" -180 "max" 180) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Hue (index $filterArgs 0) }}
++{{- else if eq $filter "invert" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Invert }}
++{{- else if eq $filter "mask" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }}
++ {{- $maskImage := partial "inline/get-resource.html" $ctx }}
++ {{- $f = images.Mask $maskImage }}
++{{- else if eq $filter "opacity" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "opacity" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Opacity (index $filterArgs 0) }}
++{{- else if eq $filter "overlay" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }}
++ {{- $overlayImg := partial "inline/get-resource.html" $ctx }}
++ {{- $f = images.Overlay $overlayImg (index $filterArgs 1 | float ) (index $filterArgs 2 | float) }}
++{{- else if eq $filter "padding" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 5) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Padding
++ (index $filterArgs 0 | int)
++ (index $filterArgs 1 | int)
++ (index $filterArgs 2 | int)
++ (index $filterArgs 3 | int)
++ (index $filterArgs 4)
++ }}
++{{- else if eq $filter "pixelate" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "size" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Pixelate (index $filterArgs 0) }}
++{{- else if eq $filter "process" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Process (index $filterArgs 0) }}
++{{- else if eq $filter "saturation" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Saturation (index $filterArgs 0) }}
++{{- else if eq $filter "sepia" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Sepia (index $filterArgs 0) }}
++{{- else if eq $filter "sigmoid" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 2) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "midpoint" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "factor" "argValue" (index $filterArgs 1) "min" -10 "max" 10) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Sigmoid (index $filterArgs 0) (index $filterArgs 1) }}
++{{- else if eq $filter "text" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" $textFilterOpts.fontPath "name" .Name "position" .Position }}
++ {{- $font := or (partial "inline/get-resource.html" $ctx) }}
++ {{- $fontSize := or (index $filterArgs 3 | int) $textFilterOpts.fontSize }}
++ {{- $lineHeight := math.Max (or (index $filterArgs 4 | float) $textFilterOpts.lineHeight) 1 }}
++ {{- $opts := dict
++ "x" (or (index $filterArgs 1 | int) $textFilterOpts.xOffset)
++ "y" (or (index $filterArgs 2 | int) $textFilterOpts.yOffset)
++ "size" $fontSize
++ "linespacing" (mul (sub $lineHeight 1) $fontSize)
++ "color" (or (index $filterArgs 5) $textFilterOpts.fontColor)
++ "font" $font
++ }}
++ {{- $f = images.Text (index $filterArgs 0) $opts }}
++{{- else if eq $filter "unsharpmask" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "amount" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "threshold" "argValue" (index $filterArgs 2) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.UnsharpMask (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- end }}
++
++{{- /* Apply filter. */}}
++{{- $fi := $i }}
++{{- with $f }}
++ {{- $fi = $i.Filter . }}
++{{- end }}
++
++{{- /* Render. */}}
++{{- $class := "di va b--black-20" }}
++{{- if eq $filter "mask" }}
++ {{- $class = "di va" }}
++{{- end }}
++{{- if $example }}
++ <p>Original</p>
++ <img class="{{ $class}}" style="width: initial;" src="{{ $i.RelPermalink }}" alt="{{ $alt }}">
++ <p>Processed</p>
++ <img class="{{ $class }}" style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
++{{- else -}}
++ <img class='di' style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
++{{- end }}
++
++{{- define "validate-arg-count" }}
++ {{- $msg := "When using the %q filter, the %q shortcode requires an args parameter with %d %s. See %s" }}
++ {{- if lt (len .args) .argsRequired }}
++ {{- $text := "values" }}
++ {{- if eq 1 .argsRequired }}
++ {{- $text = "value" }}
++ {{- end }}
++ {{- errorf $msg .filter .name .argsRequired $text .position }}
++ {{- end }}
++{{- end }}
++
++{{- define "validate-arg-value" }}
++ {{- $msg := "The %q argument passed to the %q shortcode is invalid. Expected a value in the range [%v,%v], but received %v. See %s" }}
++ {{- if or (lt .argValue .min) (gt .argValue .max) }}
++ {{- errorf $msg .argName .name .min .max .argValue .position }}
++ {{- end }}
++{{- end }}
++
++{{- define "partials/inline/get-resource.html" }}
++ {{- $r := "" }}
++ {{- $u := urls.Parse .src }}
++ {{- $msg := "The %q shortcode was unable to resolve %s. See %s" }}
++ {{- if $u.IsAbs }}
++ {{- with try (resources.GetRemote $u.String) }}
++ {{- with .Err }}
++ {{- errorf "%s" . }}
++ {{- else with .Value }}
++ {{- /* This is a remote resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- errorf $msg $.name $u.String $.position }}
++ {{- end }}
++ {{- end }}
++ {{- else }}
++ {{- with .page.Resources.Get (strings.TrimPrefix "./" $u.Path) }}
++ {{- /* This is a page resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- with resources.Get $u.Path }}
++ {{- /* This is a global resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- errorf $msg $.name $u.Path $.position }}
++ {{- end }}
++ {{- end }}
++ {{- end }}
++ {{- return $r}}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- /*
++Renders the given image using the given process specification.
++
++@param {string} (positional parameter 0) The path to the image, relative to the current page. The image must be a page resource.
++@param {string}} (positional parameter 1) The image processing specification.
++
++@returns template.HTML
++
++@example {{< imgproc "sunset.jpg" "resize 300x" />}}
++*/}}
++
++{{- with $.Get 0 }}
++ {{- with $i := $.Page.Resources.Get . }}
++ {{- with $spec := $.Get 1 }}
++ {{- with $i.Process . }}
++ <figure style="padding: 0.25rem; margin: 2rem 0; background-color: #cccc">
++ <img style="max-width: 100%; width: auto; height: auto;" src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
++ <figcaption>
++ <small>
++ {{- with $.Inner }}
++ {{ . }}
++ {{- else }}
++ {{ $spec }}
++ {{- end }}
++ </small>
++ </figcaption>
++ </figure>
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode requires a positional parameter (1) containing the image processing specification. See %s" $.Name $.Position }}
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a positional parameter (0) indicating the image path, relative to the current page. See %s" $.Name $.Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{- /*
++Renders the page using the RenderShortcode method on the Page object.
++
++You must call this shortcode using the {{% %}} notation.
++
++@param {string} (positional parameter 0) The path to the page, relative to the content directory.
++@returns template.HTML
++
++@example {{% include "functions/_common/glob-patterns" %}}
++*/}}
++
++{{- with .Get 0 }}
++ {{- with or ($.Page.GetPage .) (site.GetPage .) }}
++ {{- .RenderShortcodes }}
++ {{- else }}
++ {{/* TODO1 make error */}}
++ {{- warnf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a positional parameter indicating the path of the file to include. See %s" .Name .Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{- /*
++Renders a description list of the pages in the given section.
++
++Render a subset of the pages in the section by specifying a predefined filter,
++and whether to include those pages.
++
++Filters are defined in the data directory, in the file named page_filters. Each
++filter is an array of paths to a file, relative to the root of the content
++directory. Hugo will throw an error if the specified filter does not exist, or
++if any of the pages in the filter do not exist.
++
++The definition term elements (dt) have an id attribute derived from the title
++of the page. This is probably unique, because pages of the same title in the
++same section is unlikely.
++
++If you render a complete list on a page, then call the shortcode again to
++render a subset, you will generate duplicate element ids. In this case, set
++omitElementIDs to true for the subset.
++
++@param {string} path The path to the section.
++@param {string} [filter=""] The name of filter list.
++@param {string} [filterType=""] The type of filter, either include or exclude.
++@param {string} [omitElementIDs=false] Whether to omit dt element ids.
++@param {string} [titlePrefix=""] The string to prepend to the link title.
++
++@returns template.HTML
++
++@example {{< list-pages-in-section path=/methods/resources >}}
++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude >}}
++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo >}}
++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo omitElementIDs=true >}}
++*/}}
++
++{{- /* Initialize. */}}
++{{- $filter := or "" (.Get "filter" | lower)}}
++{{- $filterType := or (.Get "filterType") "none" | lower }}
++{{- $filteredPages := slice }}
++{{- $titlePrefix := or (.Get "titlePrefix") "" }}
++{{- $omitElementIDs := false }}
++
++{{- /* Get boolean parameters. */}}
++{{- if in (slice "false" false 0) (.Get "omitElementIDs") }}
++ {{- $omitElementIDs = false }}
++{{- else if in (slice "true" true 1) (.Get "omitElementIDs")}}
++ {{- $omitElementIDs = true }}
++{{- end }}
++
++{{- /* Build slice of filtered pages. */}}
++{{- with $filter }}
++ {{- with index site.Data.page_filters . }}
++ {{- range . }}
++ {{- with site.GetPage . }}
++ {{- $filteredPages = $filteredPages | append . }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find %q as specified in the page_filters data file. See %s" $.Name . $.Position }}
++ {{- end }}
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find the %q filter in the page_filters data file. See %s" $.Name . $.Position }}
++ {{- end }}
++{{- end }}
++
++{{- /* Render */}}
++{{- with $sectionPath := .Get "path" }}
++ {{- with site.GetPage . }}
++ {{- with .RegularPages }}
++ <dl>
++ {{- range $page := .ByTitle }}
++ {{- if or
++ (and (eq $filterType "include") (in $filteredPages $page))
++ (and (eq $filterType "exclude") (not (in $filteredPages $page)))
++ (eq $filterType "none")
++ }}
++ {{- $linkTitle := .LinkTitle }}
++ {{- with $titlePrefix }}
++ {{- $linkTitle = printf "%s%s" . $linkTitle }}
++ {{- end }}
++ {{- $idAttribute := "" }}
++ {{- if not $omitElementIDs }}
++ {{- $id := path.Join .File.Dir .File.ContentBaseName | replaceRE `[\|/]` ":" | lower }}
++ {{- $idAttribute = printf " id=%q" $id }}
++ {{- end }}
++ <dt {{- $idAttribute | safeHTMLAttr }}><a href="{{ $page.RelPermalink }}">{{ $linkTitle }}</a></dt>
++ <dd>{{- $page.Description | $page.RenderString }}</dd>
++ {{- end }}
++ {{- end }}
++ </dl>
++ {{- else }}
++ {{- warnf "The %q shortcode found no pages in the %q section. See %s" $.Name $sectionPath $.Position }}
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name $sectionPath $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a 'path' parameter indicating the path to the section. See %s" $.Name $.Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++Also see [Module Mounts Config](/hugo-modules/configuration/#module-configuration-mounts) for an alternative way to configure this directory.
--- /dev/null
--- /dev/null
++{{- /*
++ Renders a "new in" button indicating the version in which a feature was added.
++
++ When comparing the current version to the specified version, the "new in"
++ button will be hidden if any of the following conditions is true:
++
++ - The major version difference exceeds the majorVersionDiffThreshold
++ - The minor version difference exceeds the minorVersionDiffThreshold
++
++ @param {string} version The semantic version string, with or without a leading v.
++ @returns {template.HTML}
++
++ @examples {{< new-in 0.100.0 /
++>}}
++
++{{< new-in 0.100.0 >}}
++Some descriptive text here.
++{{< /new-in >}}
++*/}}
++{{ $_hugo_config := `{ "version": 1 }` }}
++
++{{- /* Set defaults. */}}
++{{- $majorVersionDiffThreshold := 0 }}
++{{- $minorVersionDiffThreshold := 30 }}
++{{- $displayExpirationWarning := true }}
++
++{{- /* Render. */}}
++{{- with $version := .Get 0 | strings.TrimPrefix "v" }}
++ {{- $majorVersionDiff := sub (index (split hugo.Version ".") 0 | int) (index (split $version ".") 0 | int) }}
++ {{- $minorVersionDiff := sub (index (split hugo.Version ".") 1 | int) (index (split $version ".") 1 | int) }}
++ {{- if or (gt $majorVersionDiff $majorVersionDiffThreshold) (gt $minorVersionDiff $minorVersionDiffThreshold) }}
++ {{- if $displayExpirationWarning }}
++ {{- warnf "This call to the %q shortcode should be removed: %s. The button is now hidden because the specified version (%s) is older than the display threshold." $.Name $.Position $version }}
++ {{- end }}
++ {{- else }}
++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }}
++ {{- with $.Inner }}
++ {{ $text := printf `<p class="fon-semibold">New in <a href=%q>v%s</a>.</p>%s`
++ $href $version (. | $.Page.RenderString (dict "display" "block"))
++ }}
++
++ {{ partial "layouts/blocks/alert.html" (dict
++ "text" ($text | safeHTML)
++ "color" "green"
++ "icon" "exclamation"
++ )
++ }}
++ {{- else }}
++ <span
++ class="not-prose inline-flex items-center px-2 mr-1 rounded text-sm font-medium bg-green-200 dark:bg-green-400 fill-green-600">
++ <svg class="mr-1.5 h-2 w-2" viewBox="0 0 8 8">
++ <circle cx="4" cy="4" r="3" />
++ </svg>
++ <a
++ class="text-green-800 dark:text-black hover:text-green-600 no-underline"
++ href="{{ $href }}"
++ target="_blank">
++ New in
++ v{{ $version }}
++ </a>
++ </span>
++ {{- end }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a positional parameter (version). See %s" .Name .Position }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{ $_hugo_config := `{ "version": 1 }` }}
++{{ partial "layouts/blocks/alert.html" (dict
++ "text" .Inner
++ "color" "blue"
++ "icon" "exclamation"
++ )
++}}
--- /dev/null
--- /dev/null
++{{/*
++Renders the child sections of the given top-level section, listing each child's immediate descendants.
++
++@param {string} section The top-level section to render.
++@returns template.HTML
++
++@example {{% quick-reference section="functions" %}}
++*/}}
++
++{{ $section := "" }}
++{{ with .Get "section" }}
++ {{ $section = . }}
++{{ else }}
++ {{ errorf "The %q shortcodes requires a 'section' parameter. See %s" .Name .Position }}
++{{ end }}
++
++{{/* Do not change the markdown indentation, and do not remove blank lines. */}}
++{{ with site.GetPage $section }}
++ {{ range .Sections }}
++
++## {{ .LinkTitle }}
++{{ .RawContent }}
++
++ {{ range .Pages }}
++ {{ $aliases := "" }}
++ {{ if eq .Section "functions" }}
++ {{ with .Params.action.aliases }}
++ {{ $aliases = delimit . " or " }}
++ {{ end }}
++ {{ end }}
++
++[{{ .LinkTitle }}]({{ .RelPermalink }}) {{ with $aliases }}({{ . }}){{ end }}
++: {{ .Description }}
++
++ {{ end }}
++ {{ end }}
++{{ else }}
++ {{ errorf "The %q shortcodes was unable to find the %q section. See %s" .Name $section .Position }}
++{{ end }}
--- /dev/null
--- /dev/null
++TODO readfile.html
--- /dev/null
- HUGO_VERSION = "0.142.0"
+[build]
+ publish = "public"
+ command = "hugo --gc --minify"
+
+ [build.environment]
- command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"
++ HUGO_VERSION = "0.143.1"
+
+[context.production.environment]
+ HUGO_ENV = "production"
+ HUGO_ENABLEGITINFO = "true"
+
+[context.split1]
+ command = "hugo --gc --minify --enableGitInfo"
+
+ [context.split1.environment]
+ HUGO_ENV = "production"
+
+[context.deploy-preview]
- [[redirects]]
- from = "/npmjs/*"
- to = "/npmjs/"
- status = 200
++ command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL --enableGitInfo"
+
+[context.branch-deploy]
+ command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"
+
+[context.next.environment]
+ HUGO_ENABLEGITINFO = "true"
+
++[[headers]]
++ for = "/*.jpg"
++
++ [headers.values]
++ Cache-Control = "public, max-age=31536000"
++
++[[headers]]
++ for = "/*.png"
++
++ [headers.values]
++ Cache-Control = "public, max-age=31536000"
++
++[[headers]]
++ for = "/*.css"
++
++ [headers.values]
++ Cache-Control = "public, max-age=31536000"
++
++[[headers]]
++ for = "/*.js"
++
++ [headers.values]
++ Cache-Control = "public, max-age=31536000"
++
++[[headers]]
++ for = "/*.ttf"
++
++ [headers.values]
++ Cache-Control = "public, max-age=31536000"
--- /dev/null
--- /dev/null
++{
++ "name": "hugoDocs",
++ "version": "1.0.0",
++ "description": "",
++ "main": "index.js",
++ "scripts": {
++ "test": "echo \"Error: no test specified\" && exit 1"
++ },
++ "author": "",
++ "license": "",
++ "devDependencies": {
++ "@tailwindcss/cli": "^4.0.0",
++ "@tailwindcss/typography": "^0.5.15",
++ "tailwindcss": "^4.0.0"
++ },
++ "dependencies": {
++ "@alpinejs/focus": "^3.14.8",
++ "@alpinejs/persist": "^3.14.8",
++ "@hotwired/turbo": "^8.0.12",
++ "alpinejs": "^3.14.8"
++ }
++}
--- /dev/null
--- /dev/null
++<?xml version="1.0" encoding="utf-8"?>
++<browserconfig>
++ <msapplication>
++ <tile>
++ <square150x150logo src="images/favicons/mstile-150x150.png"/>
++ <square310x310logo src="images/favicons/mstile-310x310.png"/>
++ <TileColor>#2d89ef</TileColor>
++ </tile>
++ </msapplication>
++</browserconfig>
--- /dev/null
--- /dev/null
++<svg id="gopher" width="100%" height="100%" viewBox="0 0 272 282" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
++ <g transform="matrix(1.09329,0,0,1.09329,-135.183,-11.6982)">
++ <path class="gopher-cape animated" d="M167.376,132.778C165.4,163.47 157.387,172.184 150.142,191.552C140.361,210.573 133.102,214.357 127.626,223.012C131.508,226.814 144.79,238.814 159.006,243.911C199.917,251.86 250.261,251.499 284.105,243.911C312.297,238.453 330.566,241.986 350.858,258.146C352.025,218.523 351.604,171.276 333.752,132.778" style="fill:rgb(201,23,126);stroke:rgb(201,23,126);stroke-width:4px;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M207.3,44.6C200.6,30.9 184.4,43 180.3,38.7C159.3,17.1 133.9,11.7 114,10.7L103,10.7C83,11.2 57.6,17 36.7,38.7C32.6,43 16.3,30.9 9.7,44.6C2,60.6 25.4,62.2 24.2,69.3C21.9,82.1 23.4,101.1 25.2,119.8C28,151.5 4.3,227.4 53.6,257.9C62.9,263.7 88,266.9 109.8,267.4L110,267.4C131.8,266.9 153.9,263.7 163.2,257.9C212.6,227.4 188.9,151.5 191.8,119.8C193.5,101.1 195,82.1 192.8,69.3C191.6,62.2 215,60.5 207.3,44.6Z" style="fill:rgb(140,197,231);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M143.2,54.3C109.8,58.2 114.3,93 127.2,104.3C151.2,125.3 176.2,104.3 173.4,83.1C170.9,62.7 153.6,53.1 143.2,54.3Z" style="fill:rgb(224,222,220);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path class="eyes" d="M145.5,72.9C151.792,72.9 156.9,78.008 156.9,84.3C156.9,90.592 151.792,95.7 145.5,95.7C139.208,95.7 134.1,90.592 134.1,84.3C134.1,78.008 139.208,72.9 145.5,72.9ZM71.356,72.746C77.648,72.746 82.756,77.854 82.756,84.146C82.756,90.438 77.648,95.546 71.356,95.546C65.064,95.546 59.956,90.438 59.956,84.146C59.956,77.854 65.064,72.746 71.356,72.746Z" style="fill:rgb(17,18,18);"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M142.5,75.8C144.487,75.8 146.1,77.413 146.1,79.4C146.1,81.387 144.487,83 142.5,83C140.513,83 138.9,81.387 138.9,79.4C138.9,77.413 140.513,75.8 142.5,75.8ZM74.274,75.192C76.261,75.192 77.874,76.805 77.874,78.792C77.874,80.779 76.261,82.392 74.274,82.392C72.287,82.392 70.674,80.779 70.674,78.792C70.674,76.805 72.287,75.192 74.274,75.192Z" style="fill:white;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M108.5,107C92.5,109.4 86.8,114 88,121.2C90,133 127.7,131.7 128.9,121.8C129.9,113.3 114.8,106.1 108.5,107Z" style="fill:rgb(184,147,127);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M98.2,111.8C95.5,121.6 119.9,120.1 119.3,113.8C119,110.1 115.7,105.4 107,105.6C103.6,105.7 99.4,107.2 98.2,111.8Z" style="fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M99,127.7C98.1,128.1 96.6,137.9 101.2,138.4C104.3,138.7 112.8,139.7 114.8,138.4C118.7,135.9 118.3,129.9 116.1,128.4C112.4,126 100,127.2 99,127.7ZM73.6,54.3C107,58.2 102.5,93 89.6,104.3C65.6,125.3 40.6,104.3 43.4,83.1C46,62.7 63.3,53.1 73.6,54.3Z" style="fill:rgb(224,222,220);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <circle class="eyes" cx="71.4" cy="84.3" r="11.4" style="fill:rgb(17,18,18);"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <circle cx="74.4" cy="79.4" r="3.6" style="fill:white;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M193.6,186.7C204.6,186.8 199.2,163.2 192.4,167.9C189.1,170.2 188.5,175.5 188.5,180C188.5,182.5 190.5,186.6 193.6,186.7ZM23.3,186.7C12.3,186.8 17.7,163.2 24.5,167.9C27.8,170.2 28.4,175.5 28.4,180C28.4,182.5 26.4,186.6 23.3,186.7ZM172.7,259.2C166.7,250.3 161.3,257.2 152.6,261.6C148.5,263.7 159.4,271.2 171.6,265.6C174.8,264.1 174.7,262.1 172.7,259.2ZM44.2,260.2C50.2,251.3 55.6,258.2 64.3,262.6C68.4,264.7 57.5,272.2 45.3,266.6C42.1,265.1 42.2,263.1 44.2,260.2Z" style="fill:rgb(184,147,127);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,20.0647,-11.6982)">
++ <path d="M188.6,47C188,49.1 190.7,48.8 191.7,55.3C192.1,57.7 200.7,51.8 197.2,47.5C194.3,43.9 189.1,44.9 188.6,47ZM28.3,47C28.9,49.1 26.2,48.8 25.2,55.3C24.8,57.7 16.2,51.8 19.7,47.5C22.5,43.9 27.7,44.9 28.3,47Z" style="fill:rgb(0,131,192);fill-rule:nonzero;"/>
++ </g>
++ <g transform="matrix(0.219817,0,0,0.219817,92.037,155.985)">
++ <g transform="matrix(2.08706,0,0,2.08706,-39.3863,-48.2414)">
++ <path class="gopher-badge animated" d="M119.631,36.154L203.822,85.066L203.822,181.395L119.631,229.184L35.578,181.395L35.578,85.066L119.631,36.154Z" style="fill:rgb(255,64,136);"/>
++ <path class="gopher-badge animated" d="M207.664,81.239L209.061,83.666L209.061,182.809L207.638,185.253L121.013,234.423L118.245,234.422L31.761,185.251L30.34,182.808L30.34,83.667L31.735,81.242L118.217,30.916L121.041,30.915L207.664,81.239ZM40.817,88.078L40.817,178.348L119.633,223.159L198.584,178.345L198.584,88.081L119.633,42.214L40.817,88.078Z" style="fill:rgb(201,23,126);"/>
++ </g>
++ <g transform="matrix(1.95678,0,0,2.21729,-55.1262,110.024)">
++ <path class="gopher-badge animated" d="M179.238,106.552L154.758,106.552L154.758,62.2L112.134,62.2L112.134,106.552L87.654,106.552L87.654,1.648L112.134,1.648L112.134,45.496L154.758,45.496L154.758,1.648L179.238,1.648L179.238,106.552Z" style="fill:white;fill-rule:nonzero;"/>
++ </g>
++ </g>
++ <g transform="matrix(1.09329,0,0,1.09329,-135.318,-8.1299)">
++ <path class="gopher-cape animated" d="M167.5,129.514C184.792,131.141 216.708,134.608 250.124,148.407C283.576,136.181 294.915,129.585 333.876,129.514" style="fill:none;stroke:rgb(201,23,126);stroke-width:4px;"/>
++ </g>
++ <g transform="matrix(1,0,0,1,-1.47026,0)">
++ <g transform="matrix(1.09203,0,0,1,-11.2404,3.14785)">
++ <path class="gopher-cape animated" d="M103.229,44.41C127.646,44.41 141.964,60.067 145.637,76.405C149.492,93.554 120.688,108.4 96.272,108.4C71.856,108.4 58.627,77.601 58.627,59.942C58.627,42.284 78.813,44.41 103.229,44.41ZM103.229,59.942C117.928,59.942 128.366,65.775 128.366,76.405C128.366,87.035 117.928,95.666 103.229,95.666C88.531,95.666 75.079,82.622 75.079,71.992C75.079,61.361 88.531,59.942 103.229,59.942Z" style="fill:rgb(201,23,126);"/>
++ </g>
++ <g transform="matrix(1.05263,0,0,1,75.8327,3.14785)">
++ <path class="gopher-cape animated" d="M101.398,44.41C125.814,44.41 141.107,42.439 141.107,60.097C141.107,77.755 125.814,108.4 101.398,108.4C76.982,108.4 57.159,94.063 57.159,76.405C57.159,58.747 76.982,44.41 101.398,44.41ZM98.548,60.097C113.14,60.097 125.888,60.912 125.888,71.466C125.888,82.019 113.14,95.527 98.548,95.527C83.955,95.527 72.108,86.959 72.108,76.405C72.108,65.851 83.955,60.097 98.548,60.097Z" style="fill:rgb(201,23,126);"/>
++ </g>
++ </g>
++</svg>
--- /dev/null
--- /dev/null
++<?xml version="1.0" encoding="utf-8"?>\r
++<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
++<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"\r
++ y="0px" viewBox="0 0 397.8 535.6" enable-background="new 0 0 397.8 535.6" xml:space="preserve">\r
++<g>\r
++ <path fill="#E0DEDC" d="M68.5,64c0,0-45.3-8-56.4,40.2c-11.7,50.6,27,46.7,27,46.7L68.5,64z"/>\r
++ <g>\r
++ <path fill="#040000" stroke="#040000" stroke-width="1.3483" stroke-miterlimit="10" d="M23.9,86.2c-8.5-0.3-15.5,25.8-13.1,35.2\r
++ c0.9,3.5,10,6.3,14-3.7C27.7,110.4,34.5,86.5,23.9,86.2z"/>\r
++ <path fill="#FFFFFF" d="M17.6,94c-1.9-0.6-4,4.5-4.7,6.3c-1.8,5.3,2.1,5.1,4.4,2C18.5,100.7,19.5,94.7,17.6,94z"/>\r
++ </g>\r
++ <path fill="#B8937F" d="M46.3,487.8c5.2,7.3,41.6,6.4,46.1-1.3c4.2-7.1-21.4-14.9-30.7-16.1C47.6,468.6,42.6,482.5,46.3,487.8z"/>\r
++ <path fill="#B8937F" d="M351,446c5.2,7.3,29.4,3.7,34-4c4.2-7.1-9.3-12.2-18.6-13.4C352.3,426.8,347.3,440.7,351,446z"/>\r
++ <path fill="#8CC5E7" d="M189.6,13.4c0,0-182.1-8.9-161,217.6c6.3,68-43.8,182.8,29.2,239.8c0,0,102.1,61.7,238.9,41.5\r
++ c20-3,45.5-10,63.2-57.1c22.3-59.5,6.6-121.5-13.2-165.5c-22.3-49.7-21.2-105.8-19.6-115.3C354.3,14.2,189.6,13.4,189.6,13.4z"/>\r
++ <path fill="#8CC5E7" d="M282.3,38.8c19.2-5,32.6-10.5,43.4-5c30.5,15.7-4.9,45.4-12.4,51C302.3,93.2,268.4,42.4,282.3,38.8z"/>\r
++ <path fill="#3C89BF" d="M306,40.5c-18.8,4.2-19.6,13.7-14.8,16.4c2.8,1.6,0.8-8.1,13.6-3.8c5.2,1.7-2.5,14.3,12.1,0.2\r
++ C324.7,45.6,310.1,39.6,306,40.5z"/>\r
++ <path fill="#E0DEDC" d="M137.9,29.2c-22.9,1.7-76.1,28.5-50,94.2c9.1,23,104.6,10.3,105.8-54C194.1,42.6,158.1,27.7,137.9,29.2z"/>\r
++ <path fill="#040000" stroke="#040000" stroke-width="1.3483" stroke-miterlimit="10" d="M109.9,51.8C88.5,53.7,83.3,84,91.3,91.1\r
++ c4.5,4,20.1,8.6,28.5-19C122.5,63.3,117.8,51,109.9,51.8z"/>\r
++ <path fill="#FFFFFF" d="M101.7,57.4c-3.1-0.9-8.8,7-7.1,10.3c0.6,1.2,3.2,2.9,5.3,1.3C102.2,67.2,107.8,59.1,101.7,57.4z"/>\r
++ <path fill="#B8937F" d="M74.6,130.1C34.9,122.3,30,165,43.9,172.3c10.1,5.4,38.8-3.5,43.6-13.4C92.2,148.9,95,134.1,74.6,130.1z"/>\r
++ <path fill="#040000" d="M48,126.4c-12.5,4.3-11.8,25.4-5.1,26c7.6,0.7,21-14.7,24.2-20.9C69.5,126.9,53,124.7,48,126.4z"/>\r
++ <path fill="#E0DEDC" d="M52.5,169.9c-3.2,1.4-2.9,18.8,3.3,21.5c19.6,8.3,20.9-20.4,17.1-24.9C70,162.9,54.7,168.9,52.5,169.9z"/>\r
++ <path fill="#B8937F" d="M272,269.2c-11.2,0.5-19.7,23.3-16.9,34.3c1.5,5.9,12.9,5,11.3,9.6c-2.7,7.6,17.4,12.9,21.2,4.7\r
++ C306.9,277,282.3,268.8,272,269.2z"/>\r
++ <path fill="#B8937F" d="M251.8,497.4c-39.7-4.3-51.7,14.7-44.4,21.8c7.7,7.5,38.1,5.3,54.7,3.9\r
++ C268.7,522.6,261.8,498.5,251.8,497.4z"/>\r
++</g>\r
++</svg>\r
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" stroke-width="27" aria-label="Logo" viewBox="0 0 1493 391">
++ <path fill="#ebb951" stroke="#fcd804" d="M1345.211 24.704l112.262 64.305a43 43 0 0 1 21.627 37.312v142.237a40 40 0 0 1-20.702 35.037l-120.886 66.584a42 42 0 0 1-41.216-.389l-106.242-61.155a57 57 0 0 1-28.564-49.4V138.71a64 64 0 0 1 31.172-54.939l98.01-58.564a54 54 0 0 1 54.54-.503z"/>
++ <path fill="#33ba91" stroke="#00a88a" d="M958.07 22.82l117.31 66.78a41 41 0 0 1 20.72 35.64v139.5a45 45 0 0 1-23.1 39.32L955.68 369.4a44 44 0 0 1-43.54-.41l-105.82-61.6a56 56 0 0 1-27.83-48.4V140.07a68 68 0 0 1 33.23-58.44l98.06-58.35a48 48 0 0 1 48.3-.46z"/>
++ <path fill="#0594cb" stroke="#0083c0" d="M575.26 20.97l117.23 68.9a40 40 0 0 1 19.73 34.27l.73 138.67a48 48 0 0 1-24.64 42.2l-115.13 64.11a45 45 0 0 1-44.53-.42l-105.83-61.6a55 55 0 0 1-27.33-47.53V136.52a63 63 0 0 1 29.87-53.59l99.3-61.4a49 49 0 0 1 50.6-.56z"/>
++ <path fill="#ff4088" stroke="#c9177e" d="M195.81 24.13l114.41 66.54a44 44 0 0 1 21.88 38.04v136.43a48 48 0 0 1-24.45 41.82L194.1 370.9a49 49 0 0 1-48.48-.23L41.05 310.48a53 53 0 0 1-26.56-45.93V135.08a55 55 0 0 1 26.1-46.8l102.8-63.46a51 51 0 0 1 52.42-.69z"/>
++ <path fill="#fff" d="M1320.72 89.15c58.79 0 106.52 47.73 106.52 106.51 0 58.8-47.73 106.52-106.52 106.52-58.78 0-106.52-47.73-106.52-106.52 0-58.78 47.74-106.51 106.52-106.51zm0 39.57c36.95 0 66.94 30 66.94 66.94a66.97 66.97 0 0 1-66.94 66.94c-36.95 0-66.94-29.99-66.94-66.94a66.97 66.97 0 0 1 66.93-66.94h.01zm-283.8 65.31c0 47.18-8.94 60.93-26.81 80.58-17.87 19.65-41.57 27.57-71.1 27.57-27 0-48.75-9.58-67.61-26.23-20.88-18.45-36.08-47.04-36.08-78.95 0-31.37 11.72-58.48 32.49-78.67 18.22-17.67 45.34-29.18 73.3-29.18 33.77 0 68.83 15.98 90.44 47.53l-31.73 26.82c-13.45-25.03-32.94-33.46-60.82-34.26-30.83-.88-64.77 28.53-62.25 67.75 1.4 21.94 11.65 59.65 60.96 66.57 25.9 3.63 55.36-24.02 55.36-39.04H944.4v-37.5h92.5V194l.02.03zm-562.6-94.65h42.29v112.17c0 17.8.49 29.33 1.47 34.61 1.69 8.48 4.81 14.37 11.17 19.5 6.37 5.13 13.8 6.59 24.84 6.59 11.2 0 14.96-1.74 20.66-6.6 5.69-4.85 9.12-9.46 10.28-16.53 1.15-7.07 3.07-18.8 3.07-35.18V99.38h42.28v108.78c0 24.86-1.07 42.43-3.21 52.69-2.14 10.27-6.08 18.93-11.82 26-5.74 7.06-13.42 12.69-23.03 16.88-9.62 4.19-22.16 6.28-37.65 6.28-18.7 0-32.87-2.28-42.52-6.85-9.66-4.57-17.3-10.5-22.9-17.8-5.61-7.3-9.3-14.95-11.08-22.96-2.58-11.86-3.88-29.38-3.88-52.55V99.38h.03zM93.91 299.92V92.7h43.35v75.48h71.92V92.7h43.48v207.22h-43.48v-90.61h-71.92v90.61z"/>
++</svg>
--- /dev/null
--- /dev/null
++{
++ "name": "Hugo",
++ "short_name": "Hugo",
++ "icons": [
++ {
++ "src": "/android-chrome-36x36.png",
++ "sizes": "36x36",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-48x48.png",
++ "sizes": "48x48",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-72x72.png",
++ "sizes": "72x72",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-96x96.png",
++ "sizes": "96x96",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-144x144.png",
++ "sizes": "144x144",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-192x192.png",
++ "sizes": "192x192",
++ "type": "image/png"
++ },
++ {
++ "src": "/android-chrome-256x256.png",
++ "sizes": "256x256",
++ "type": "image/png"
++ }
++ ],
++ "start_url": "./?utm_source=web_app_manifest",
++ "theme_color": "#0A1922",
++ "background_color": "#FFF",
++ "display": "standalone"
++}
--- /dev/null
--- /dev/null
++<?xml version="1.0" standalone="no"?>
++<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
++ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
++<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
++ width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
++ preserveAspectRatio="xMidYMid meet">
++<metadata>
++Created by potrace 1.11, written by Peter Selinger 2001-2013
++</metadata>
++<g transform="translate(0.000000,16.000000) scale(0.006250,-0.006250)"
++fill="#000000" stroke="none">
++<path d="M1118 2481 c-76 -45 -139 -81 -141 -81 -3 0 -53 -29 -112 -65 -59
++-36 -108 -65 -110 -65 -2 0 -32 -17 -67 -37 -35 -21 -79 -47 -99 -58 -239
++-133 -399 -233 -414 -258 -16 -26 -17 -84 -17 -637 0 -493 3 -613 14 -636 13
++-28 166 -131 196 -133 6 -1 12 -5 12 -11 0 -5 4 -10 9 -10 5 0 91 -48 192
++-106 101 -59 200 -116 219 -127 19 -10 124 -71 232 -134 245 -142 248 -143
++360 -78 45 26 97 56 116 66 44 25 334 195 375 219 18 11 41 24 52 29 74 34
++433 254 449 274 17 23 18 57 18 640 0 569 -1 618 -17 645 -13 21 -65 57 -173
++118 -254 146 -349 201 -689 398 -111 64 -216 119 -235 122 -28 4 -54 -7 -170
++-75z"/>
++</g>
++</svg>
--- /dev/null
--- /dev/null
++/* Empty for now. */