Skip to main content

How to use <details> <summary> expandable content with Hugo

··811 words·4 mins
Race Dorsey
Author
Race Dorsey
Table of Contents
Learn how to create a details shortcode in Hugo

In HTML <detail> and <summary> tags can be used to collapse sections of text that a reader can choose to expand. This is useful to include technical details or other content that not every user may appreciate but the information will be available for those who are interested. These tags, however, do not work natively in markdown meaning Hugo can’t use <detail> and <summary>. To solve this we will be creating our own details shortcode.

Here is an example of what we will be building:

Details:

This is the first paragraph of detailed content. This is the second paragraph of even more detailed content.

  • You can also include lists
  • Or other markdown elements

Create details.html
#

Create the following file in the specified directory relative to your project folder.

layouts/shortcodes/details.html:

<details {{ if eq (.Get "open" | default "false") "true" }}open{{ end }}>
    <summary>
        {{ .Get "summary" | default "Details:" | markdownify }}
    </summary>
    {{ .Inner | markdownify }}
</details>

Parameters:
#

When using this shortcode there are two parameters:

  1. summary. Default = “Details:”. This is the text that appears for users to click on.
  2. open. Default = ‘false’. This specifies if the details tag is open or closed when the page loads.

Usage:
#

Within your markdown, you can now use this as a shortcode as follows:

{{< details >}}
This is the first paragraph of detailed content.
This is the second paragraph of even more detailed content.
- You can also include lists
- Or other markdown elements
{{< /details >}}
Details:

This is the first paragraph of detailed content. This is the second paragraph of even more detailed content.

  • You can also include lists
  • Or other markdown elements

It is important to remember to call the shortcode, type your text, and then close the shortcode.

Here is an example with specifying the summary name.

{{< details summary="Super Secret Text" >}}
Enter your super secrets here
{{< /details >}}
Super Secret Text Enter your super secrets here

And an example specifying the content to be expanded when the page loads.

{{< details summary="Super Secret Text" open="true" >}}
Oh no, my secrets are out! 
{{< /details >}}
Super Secret Text Oh no, my secrets are out!

An Alternative
#

I wanted something a little more advanced and I wanted to be able to specify an alternative summary when the content was opened. For this option I used positional arguments instead of named arguments.

layouts/shortcodes/details.html:

<details {{ if eq (.Get 1 | default "closed") "open" }}open{{ end }}>
    <summary onclick="this.textContent = this.parentNode.open ? '{{ with .Get 0}}{{ . | default "Details:" }}{{ else }}Details:{{ end }}' : '{{ with .Get 2 }}{{ . }}{{ else }}{{ with .Get 0}}{{ . | default "Details:" }}{{ else }}Details:{{ end }}{{ end }}';">
        {{ with .Get 0}}{{ . | default "Details:" }}{{ else }}Details:{{ end }}
    </summary>
    {{ .Inner | markdownify }}
</details>

Positional Parameters
#

This shortcode has 3 optional parameters: Summary, Open, Alternative Summary

1. Summary
#

This is the text that appears for users to click on and is the first positional argument.

For example:

{{< details "Super Secret Text" >}}
Enter your super secrets here
{{< /details >}}
Super Secret Text Enter your super secrets here

If no arguments are given then this defaults to “Details:”.

2. Open
#

This specifies if the expandable section is open or closed when the page is loaded. This is the second positional argument and defaults to “closed”. To specify the expandable section as open you must specify “open” exactly or the default will be applied.

Example usage:

{{< details "Super Secret Text" "open" >}}
Oh no, my secrets are out! 
{{< /details >}}
Super Secret Text Oh no, my secrets are out!

3. Alternative Summary
#

The third positional argument is an alternative name when the expandable section is open. If left blank then the summary text will be the same when open and closed. Here is an example usage:

{{< details "Super Secret Text" "closed" "click to close before anyone sees!" >}}
Oh no, my secrets are out! 
{{< /details >}}
Super Secret Text Oh no, my secrets are out!

One caveat is that if you specify “open” with a summary name when closed, then the summary name won’t render correctly until it has been clicked on twice. I believe this could be resolved with an event listener or through css but I opted for simplicity given I don’t see myself running into that edge case. I.e. if I’m going to have the details open by default then I won’t be changing the name.

Example of what it looks like if you do use with “open”:

{{< details "Super Secret Text" "open" "Alternative Text" >}}
Oh no, my secrets are out! 
{{< /details >}}
Super Secret Text Oh no, my secrets are out!