This collection of Hugo shortcodes and render hooks is not meant to be an exhaustive list of components you might need in your Markdown content, rather it's a few examples that illustrate various techinques that will help you build out your own system. These techinques include: validating parameters (button), handling arbitrary parameters (img), using a partial within the shortcode so layout and content can use the component (icon), using conditional content (ifparam), and passing parameters from a child shortcode to the parent for rendering (tabpane).
To see the output of these shortcodes and render hooks, run:
hugo serverThen visit http://localhost:1313 in your browser.
Requires Hugo v0.147.0 or later.
This render hook overrides the rendering of Markdown blockquotes to HTML.
> QuoteIn the render hook example, you can add an author, citation, or caption to your blockquote by passing them as Markdown attributes.
> Most human beings have an almost infinite capacity for taking things for granted.
{author="Aldous Huxley" cite="https://www.huxley.net/bnw/" caption="Brave New World"}To add an alert to your Markdown content, you can add an alert designator consisting of an exclamation point followed by the alert type, wrapped within brackets.
> [!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.
> [!CAUTION]
> Advises about risks or negative outcomes of certain actions.
> [!WARNING]
> Urgent info that needs immediate user attention to avoid problems.Learn more about the blockquote render hook.
This render hook overrides the rendering of Markdown code blocks to HTML.
In the render hook example, all code blocks will have line numbers by default.
```bash
declare a=1
echo "$a"
exit
```Learn more about the codeblock render hook.
This render hook overrides the rendering of Markdown headings to HTML.
In the render hook example, headings h1 through h4 will automatically have an anchor link injected.
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6Learn more about the heading render hook.
This render hook overrides the rendering of Markdown images to HTML.
This is an inline  image.In the render hook example, standalone images will be rendered within a figure element.
Learn more about the image render hook.
This render hook overrides the rendering of Markdown links to HTML.
In the render hook example, links with external destinations will automatically open in a new window.
This is a [link](/).
This is an [external link](https://github.com/).Learn more about the link render hook.
This render hook overrides the rendering of Markdown tables to HTML.
In the render hook example, tables will automatically be striped.
| Month | Amount |
| :------- | -----: |
| January | $10 |
| February | $100 |
| March | $1000 |Learn more about the table render hook.
- accordion
- alert
- blockquote
- button
- collapse
- command-output
- details
- file-list
- icon
- ifparam
- img
- include
- labeled-highlight
- md
- param
- resource
- siteparam
- tabpane
If you want to add an accordion to your content, you can use the accordion shortcode.
{{< accordion name="my-accordion" >}}
{{< details summary="Accordion 1" open="true" >}}
Lorem ipsum dolor sit amet.
{{< /details >}}
{{< details summary="Accordion 2" >}}
Lorem ipsum dolor sit amet.
{{< /details >}}
{{< /accordion >}}| Name | Value | Description |
|---|---|---|
0: name |
String | Accordion name |
To only have one details element open at a time, the name parameter needs to be set.
<div class="accordion">
<details name="my-accordion" open>
<summary>Accordion 1</summary>
<p>Lorem ipsum dolor sit amet.</p>
</details>
<details name="my-accordion">
<summary>Accordion 2</summary>
<p>Lorem ipsum dolor sit amet.</p>
</details>
</div>If you want to add an alert banner to your content, you can use the alert shortcode.
{{< alert severity="warning" size="small" >}}
**Warning:** This is a small warning alert.
{{< /alert >}}| Name | Value | Description |
|---|---|---|
0: severity |
info (default), success, warning, error |
Variant of alert |
1: size |
small |
Size of alert; Defaults to none |
2: hideIcon |
true |
Hides icon; Defaults to false |
<div class="alert alert--warning alert--small">
<div class="alert__icon">
<svg class="icon icon--alert icon--small">...</svg>
</div>
<div class="alert__body">
<strong>Warning:</strong> This is a small warning alert.
</div>
</div>If you want to add a blockquote to your content, you can use the blockquote shortcode.
{{< blockquote author="Aldous Huxley" cite="https://www.huxley.net/bnw/" caption="Brave New World" >}}
Most human beings have an almost infinite capacity for taking things for granted.
{{< /blockquote >}}| Name | Value | Description |
|---|---|---|
0: author |
String | Author name |
1: cite |
URL | Source URL |
2: caption |
String | Source name |
<figure>
<blockquote cite="https://www.huxley.net/bnw/">
<p>
Most human beings have an almost infinite capacity for taking things for granted.
</p>
<figcaption>
Aldous Huxley, <cite><a href="https://www.huxley.net/bnw/">Brave New World</a></cite>
</figcaption>
</blockquote>
</figure>If you want to add a button to your content, you can use the button shortcode.
{{< button href="https://github.com/" variant="primary" size="large" >}}
Learn more
{{< /button >}}| Name | Value | Description |
|---|---|---|
0: href (Required) |
URL | Page link |
1: variant |
primary, secondary, info, success, warning, error |
Variant of button; Defaults to none |
2: size |
small, medium, large |
Size of button; Defaults to medium |
3: disabled |
disabled or true |
Disable button; Defaults to none |
4: class |
String | Additional class name |
If href begins with "http", then the link will open in a new window.
<a class="button button--primary button--small button--disabled">
Learn more
</a>If you want to collapse a block of content and show an expand button to reveal the full content, you can use the collapse shortcode.
{{< collapse maxHeight="100" >}}
Markdown
{{< /collapse >}}| Name | Value | Description |
|---|---|---|
0: maxHeight |
Number | The max-height of the content when it's collapsed; Defaults to 200px |
<div class="collapse">
<input class="collapse__input" type="checkbox" id="collapse-00">
<label class="collapse__label" for="collapse-00"></label>
<div class="collapse__content">
Markdown
</div>
</div>The collapse shortcode doesn't reliably work when nested in a tabpane shortcode. The expand button may still be visible when it's not needed. This is because the CSS display property of the inactive tabpane panel is set to none, so the height of the content cannot be determined on page load.
If you want to display a command with output in a highlighted code block, you can use the command-output shortcode.
The command prompt and the output are separated from the command so it can be copied and ran without alteration.
Starting with the first line in the code block, every line that begins with the prompt is considered to be part of the command. On the first line without the prompt, all remaining lines are considered output and will be rendered in a plaintext code block (even if they also begin with the prompt).
The label is displayed above the output, which defaults to "Example output:".
{{< command-output >}}
```bash
% ls -Flh
total 4
drwxr-xr-x 6 username staff 256B Jan 02 15:04 assets/
drwxr-xr-x 4 username staff 256B Jan 02 15:04 config/
drwxr-xr-x 8 username staff 256B Jan 02 15:04 content/
drwxr-xr-x 8 username staff 256B Apr 02 15:04 layouts/
```
{{< /command-output >}}If you have a multi-line command, and not every line of the command has a prompt, you can set the marker parameter to separate the command and output. Starting with the first line in the code block, every line is considered to be part of the command until there's a line starting with the marker. All other lines after the marker are considered output, and will be rendered in a plaintext code block.
If label is not set, then the text on the same line after the marker will be used as the text above the output. If there is not any text after the marker, then the text will default to "Example output:". If label is set, then the marker will be considered output.
{{< command-output marker="#" >}}
```bash
% hugo \
--gc \
--cleanDestinationDir \
--minify
# You should see something like:
Start building sites …
hugo v0.160.0-xxx darwin/amd64 BuildDate=2026-01-01T00:00:00Z VendorInfo=gohugoio
```
{{< /command-output >}}More examples
If you just want to use the default label, include the whole line as the marker:
{{< command-output marker="###" >}}
```bash
% command \
--flag
###
output
```
{{< /command-output >}}If you want a comment to designate the beginning of the output and you also want the it to appear in the output code block, just set the label parameter.
{{< command-output label="You should see:" marker="#" >}}
```bash
% command \
--flag
# Some comment you want displayed with the output
output
```
{{< /command-output >}}| Name | Value | Description |
|---|---|---|
0: label |
String | The text to display above the output code block; Defaults to "Example output:" |
1: prompt |
String | The prompt that precedes the command; Defaults to "%" |
2: marker |
String | The marker that designates the beginning of the output |
Code fence options are preserved on the command code block, but are not passed to the output code block.
<div class="command-output">
<div class="command-output__command">
<div class="highlight">
<pre>
<code class="language-bash" data-lang="bash">
<span class="prompt" data-prompt="%">command</span>
</code>
</pre>
</div>
</div>
<div class="command-output__label">Example output:</div>
<div class="command-output__output">
<div class="highlight">
<pre>
<code class="language-plaintext" data-lang="plaintext">
<span>output</span>
</code>
</pre>
</div>
</div>
</div>This shortcode overrides Hugo’s embedded details shortcode (added in Hugo v0.140.0), so it can be nested in the accordion shortcode.
{{< details "Summary" >}}
Lorem ipsum dolor sit amet.
{{< /details >}}| Name | Value | Description |
|---|---|---|
0: summary |
String | Summary content |
1: open |
Boolean | Whether to initially display details; Defaults to false |
2: class |
String | Class attribute |
3: name |
String | Name attribute |
4: title |
String | Title attribute |
<details>
<summary>Summary</summary>
<p>Lorem ipsum dolor sit amet.</p>
</details>If you want to display a list of links as a file list, you can use the file-list shortcode.
{{< file-list >}}
- [Page 1](page-1)
- [Page 2](page-2)
- [Page 3](page-3)
{{< /file-list >}}| Name | Value | Description |
|---|---|---|
0: icon |
String | Icon name; Defaults to "file" |
1: variant |
String | Icon variant; Defaults to "secondary" |
The shortcode inner content must be an unordered list of anchor links.
<ul class="file-list">
<li>
<a href="page-1"><svg class="icon">...</svg> Page 1</a>
</li>
<li>
<a href="page-2"><svg class="icon">...</svg> Page 2</a>
</li>
<li>
<a href="page-3"><svg class="icon">...</svg> Page 3</a>
</li>
</ul>If you want to add an icon to your content, you can use the icon shortcode.
{{< icon name="alert" variant="primary" size="small" >}}| Name | Value | Description |
|---|---|---|
0: name (Required) |
String | Icon name |
1: variant |
primary, secondary, info, success, warning, error, current |
Variant of icon; Defaults to none |
2: size |
small, medium large |
Size of icon; Defaults to medium |
3: class |
String | Additional class name |
The icon file must be an svg, located in the /assets/icons/ directory.
<svg class="icon icon--primary icon--small">...</svg>If you want to conditionally print some text based on a boolean parameter set in frontmatter, you can use the ifparam shortcode.
Let's say you have this parameter set in your frontmatter...
---
some_param: true
---In your Markdown, you can conditionally print some text based on this parameter.
{{< ifparam "some_param" "enabled" "disabled" >}}You can also leave the false value empty, and the shortcode will only print the text if the parameter is true.
If you want to add an image in your content, but need to set additional attributes not supported by Markdown image syntax, or you want to apply a Hugo .Process to the image, you can use the img shortcode. When using positional parameters, only alt, src, and process parameters are supported. To set additional attributes, set each attribute as a named parameter.
{{< img "Alt text" "image.png" "resize 600x" >}}{{< img src="image.png" alt="Alt text" width="300" height="200" class="image" style="border: solid 1px red" process="fit 600x400" >}}| Name | Value | Description |
|---|---|---|
0: alt (Required) |
String | Image alt |
1: src (Required) |
URL | Image path |
2: process |
String | Process specification |
To use image processing, the image must be a page resource, not a global resource or a static image.
<img src="/image_xxx.png" alt="Alt text" width="300" height="200" class="image" style="border: solid 1px red">If you have HTML or Markdown that you would like to externally include in your content files, you can place the file under the current working directory. Then, you can use the include shortcode to pull in this file into your content.
{{< include "_includes/file.md" >}}- You must use
{{< >}}shortcode delimiters to render the included content correctly. - All included files under the
contentdirectory must havedraft:trueorbuild: { list: never, publishResources: false, render: never }set asfrontmatterparams. - Only relative paths under the page including the file are supported. Relative paths traversing up the directory are not supported. For files outside the current working directory you can use an absolute path starting with
/. - When editing an included file in local development, the page including the file is not automatically updated. Restarting the server is required to see any changes.
- The headings of included files will not be displayed in Hugo's
TableOfContents.
Hugo automatically highlights content in code fences, and also provides a built-in highlight shortcode.
However, Hugo does not provide an option to display a title or filename.
If you need to label the code block, you can use the labeled-highlight shortcode.
{{< labeled-highlight label="users.json" lang="json" options="lineNos=true" >}}
{
"name": "John",
"age": 30
}
{{< /labeled-highlight >}}You can also use a code fence as the content of the shortcode. The language and options of the code fence will be honored, and the lang and options parameters will be ignored.
{{< labeled-highlight "users.yaml" >}}
```yaml
name: "John"
age: 30
```
{{< /labeled-highlight >}}| Name | Value | Description |
|---|---|---|
0: label |
String | The text to display above the code block |
1: lang |
String | The language of the code to highlight |
2: options |
String | Additional options, formatted as "lineNos=table, style=api" |
<div class="labeled-highlight">
<div class="labeled-highlight__label">
<code>Label</code>
</div>
<div class="highlight">
...
</div>
</div>Rather than using a shortcode, an alternate solution is to add a title with Markdown attribute syntax to the code fence:
json {title="users.json",linenos=true}
Then add styles to display the title attribute:
.highlight[title] {
&::before {
content: attr(title);
...
}
}While this method avoids needing to use a shortcode, the shortcode allows for more control of the markup used to display the label.
If you have some html content pages, and can't use Markdown for some reason, but you want to make use of render hooks, you can use the md shortcode.
For example, let's say you had this html:
<article>
<h3>Heading</h3>
<img src="image.jpg" alt="image">
<p>This is an <a href="https://gohugo.io/">external link</a></p>
</article>You can utilize the Markdown render hooks by using the md shortcode:
<article>
{{< md "### Heading" />}}
{{< md "" />}}
{{< md >}}
This is an [external link](https://gohugo.io/)
{{< /md >}}
</article>Which could potentially output this markup, based on your render hook implementation:
<article>
<h3 id="heading">Heading <a href="#heading">#</a></h3>
<figure>
<img src="/path/to/image.jpg" alt="image">
</figure>
<p>This is an <a href="https://gohugo.io/" target="_blank" rel="noopener">external link</a></p>
</article>You can either pass the Markdown content as an attribute:
{{< md "Markdown" />}}Or as content between the opening and closing tags:
{{< md >}}
- One
- Two
- Three
{{< /md >}}If you need to print a frontmatter parameter in your Markdown, you can use the param shortcode.
Let's say you have this param set in your frontmatter:
---
title: Hugo shortcodes and render hooks
---Then in your Markdown, you can print the value of this parameter:
{{< param "title" >}}You can also pass a second optional value that will only be returned if the parameter is empty.
{{< param "param_name" "default value" >}}If you want to include a page resource or a global resource in your Markdown, you can use the resource shortcode.
{{< resource "image.*" >}}This shortcode will first look for a page resource matching the file path, and if it was not found, it will then look for a global resource.
If the resource is a raster image (webp, jpg, png, ...), then you can pass an optional process specification.
{{< resource "image.webp" "fill 200x200 jpg q80 lanczos" >}}If the resource is a JavaScript or stylesheet file, the file contents will be printed on the page as text. If you would like to link to the file as an external resource, then you can pass an optional "external" param.
{{< resource "script.js" "external" >}}Output
<script src="script.js"></script>| Type | Description |
|---|---|
| application (json, yaml, ...) | Renders raw content of resource; to nest output in a codeblock, use {{% %}} shortcode delimiters |
| audio (mp3, ogg, ...) | Renders audio tag referencing resource URL |
| video (mp4, ogg, ...) | Renders video tag referencing resource URL |
| image (jpg, png, svg, ...) | Renders img tag referencing resource URL |
| page (Markdown, HTML) | Renders resource content as HTML |
| javascript | Renders raw content or script tag referencing resource URL |
| stylesheet | Renders raw content or link tag referencing resource URL |
| text | Renders raw content of resource |
If you need to print a site parameter in your Markdown, you can use the siteparam shortcode.
{{< siteparam "param_name" >}}You can also pass a second optional value that will only be returned if the site parameter is empty.
{{< siteparam "param_name" "default value" >}}You can also access the site parameter by chaining the identifiers
{{< siteparam "a.b.c" >}}If you want to add tabs to your content, you can use the tabpane shortcode.
{{< tabpane >}}
{{< tab label="Tab 1" >}}
Markdown
{{< /tab >}}
{{< tab label="Tab 2" selected="true" >}}
Markdown
{{< /tab >}}
{{< tab label="Tab 3" >}}
Markdown
{{< /tab >}}
{{< /tabpane >}}| Name | Value | Description |
|---|---|---|
0: label |
String | The text displayed in the tab button |
1: selected |
Boolean | Defaults to false |
<div class="tabpane">
<input type="radio" name="tabpane-00" id="tabpane-00-00" class="tabpane__input">
<label class="tabpane__label" for="tabpane-00-00">
Tab 1
</label>
<div class="tabpane__panel">
Markdown
</div>
<input type="radio" name="tabpane-00" id="tabpane-00-01" class="tabpane__input">
<label class="tabpane__label" for="tabpane-00-01">
Tab 2
</label>
<div class="tabpane__panel">
Markdown
</div>
<input type="radio" name="tabpane-00" id="tabpane-00-02" class="tabpane__input">
<label class="tabpane__label" for="tabpane-00-02">
Tab 3
</label>
<div class="tabpane__panel">
Markdown
</div>
</div>This project is licensed under the MIT License. See LICENSE for details.