Using icons in front matter via "icon: mdi inbox-full" does not work as expected

I can successfully find out what text is required to use Font Awesome icons in the front matter for my project just looking at the theme docsy’s source code. I would like to also not need to guess how to use other icon sets such as mdi.
This documentation does not describe the method that works, but does describe methods that do not work.
Example that works but only for Font Awesome icons:

---
title: Dashboard
linkTitle: Dashboard
icon: fa fa-gauge
type: docs

Example based on the documentation which definitely doesn’t work (shortcode in the front matter section). It would be nice if this worked though!

---
title: Welcome to omis docs
linkTitle: omis docs
icon:
  "{ < icons/icon mdi inbox > }": null

How can we determine the secret words for mdi icon module usage in front matter? The documentation implies it is supported just like Font Awesome is supported but the method that works doesn’t appear where one would expect it to appear in the documentation, namely under “Usage”.

Just reviewing how this is implemented in that documentation site menu itself I see the advanced method has the unfortunate side effect of making the source code unreadable/learnable. Not as elegant a solution from my novice perspective. I’llassume it was done in service to load time improvement. In my case this “advanced” method currently is slowing me down.

{{ $res := dict "vendor" "font awesome" "name" "inbox-full" }}
2{{ with partialCached "icons/functions/svg-resource" $res $res }}
3  <img src="{{ .RelPermalink }}" />
4{{ end }}

Based on this support post it looks like I need to search the project for text containting “Params.Icon”. Which leads me to docs/themes/docsy/layouts/partials/sidebar-tree.html as well as /docs/themes/assets/vendor/boostrap/site/layouts/partials/docs-navbar.html.where we find the word Bootstrap.

Based on this other support post I need to duplicate some unknown partial from the docsy theme and put in the relevant information for mdi icons…

But when I look at the docsy repo, and search for “awesome”, I see quite a bit more than I expect if the use of another icon set is as direct and supported as the documentation for Hugo makes it out to be.

Viewing this post suggests something will work that might not otherwise work unless the modules are loaded in a special order. Not sure thats true but I put the module for mdi above the others just to see.
No change…

However mdi is appearing successfully outside of front matter using short codes and it automagically does it as an inline svg. I guess that is the point of the icon set being called an inline svg icon set.

Hi there,

I’m successfully using svg icons in titles, and just pushed a demo: This is a title with icons everywhere | Audio.phoni.es

Note that I’m using inline SVG icons instead of Font Awesome, explainations in this blog post.

1 Like

I was just checking out Utkarsh’s repo! And that set you point out does contain the icons I need. Thanks!

1 Like

Unfortunately I don’t really know what you mean on your post when you say use Markdownify in a template.

<h2>{{ .Params.title | markdownify }}</h2>

I can only assume you are talking about creating some additional file that is a copy of the file that docsy uses to create the menu in the sidebar and then locating somewhere inside that partial where the menu item is created and substituting your code in there. I would not really know what to copy out of the docsy repo other than perhaps the sidebar-tree.html partial but where exactly is beyond me at the moment. Can I just create a file in layouts called icon.html? What I definitely cannot do is this:

---
title: Reports
linkTitle: Reports
icon: {{< ico "inbox-full" "material" >}}
type: docs
tags:
  - intro
weight: 18
---

I get:

failed to unmarshal YAML: yaml: invalid map key: map[interface {}]interface {}{“< ico "inbox-full" "material" >”:interface {}(nil)}

You have to put your Hugo code in quotes. YAML does not work with curly braces.

Thanks @chrillek I am a bit closer. Now I tried:

---
title: Reports
linkTitle: Reports
icon: "{{< ico "inbox-full" "material" >}}"
type: docs
tags:
  - intro
weight: 18
---

And that generates:

failed to unmarshal YAML: yaml: line 2: did not find expected key

I think I need to stop using shortcodes and create a template somewhere called something that has something like what is demonstrated at This is a title with svg icons.
I just need to know what they are exactly talking about and where when they write:

Use icons in template files

Default icons can be used in theme files too, with the following partial:

{{ partial "ico" "star" }}

So to clarify:

  1. Default icons means non-default icons cannot be used or is this just a simple example so they say default to keep it simple?
  2. What theme files are they referring to.

In other words do they mean create a folder in the project’s layouts folder called partials and in that folder create a file called something.html, or does it have to be ico.html which is what I find at https://github.com/RoneoOrg/hugo-shortcode-roneo-collection/tree/main/layouts/partials
And do I just copy blindyly the entirety of those two files or what exactly?
In an effort to solve this I created an issue for it on github

icon: "{{< ico "inbox-full" "material" >}}"

must fail in YAML because the value for the key icon is "{{<ico ", followed by some more strings. Not possible.

I can’t answer any of your questions, and I guess they’d better be directed to the authors of the theme. I don’t use things like Font Awesome nor mdi icons.

and yet the blog post claims this works:

Hints:

  • Install this shortcodes collection
  • Your template should use markdownify
    (something like <h2>{{ .Params.title | markdownify }}</h2>)
  • Your front matter can then include icons:
---
title: "This is a title svg {{< ico moon >}} icons"
date: 2023-07-25T08:12:30+10:00
---

But I see now that the partial filename is referenced in the code described on this page:

When he says “partial” what he means is an html file template stored in a folder called partials and the template name is whatever is referenced in the code plus “.html”. In the blog entry the example is:

{{ partial "svg" "address-book" }}

and what is in svg.html? Well he doesn’t say exactly but then he prints some code that I am guessing is supposed to be the contents of svg.html:

{{ $svg := . }}
{{ $class := print $svg "-icon" }}
{{ $match := "<svg (.*)?>(.*)</svg>" }}

{{ $replaceWith := printf `<svg class="%s" ${1}>${2}</svg>` $class }}
{{ return (replaceRE $match $replaceWith (printf "/assets/images/%s.svg" $svg | readFile) | safeHTML) }}

So to expand on the explanation here, the reader is expected to understand and be able to extrapolate from this single line of code:

{{< ico "coffee" "boxicons" >}}

that the filename is ico.html and it is located in /layouts/partials/.
the content of ico.html is probably the content found in the repo version of ico.html
that file basically just hauls in content for another file /layouts/partials/_ico.html
I do not know how to make use of this to then modify one of those files according to this blog post:

  • Your template should use markdownify
    (something like <h2>{{ .Params.title | markdownify }}</h2>)

but I suspect there are two solutions, either put every svg for the icons into an /assets/svg folder and use the rewrite method from above in a file called svg.html or figure out what the other writer is talking about when he/she says "Your template should use ‘markdownify’ and then use something like this to have a sidebar menu with icons:

---
title: "{{< ico inbox-full material>}} <-- Sidebar menu item icon"
---

Incidentally, I feel like I shouldn’t have to create any files at all, the git submodule should pull in the repo’s own layouts/partials/ content. Isn’t that the point?

I am unable to resolve the differences between the two blog posts:

  • One says write it like this:
{{/* Adding an icon using SVG icon system with Hugo. */}}
{{ partial "svg" "address-book" }}

The other says write it like this:

---
title: "This is a title svg {{< ico moon >}} icons"
date: 2023-07-25T08:12:30+10:00
---
  • One is a shortcode and the other one is a partial
  • One (shortcode) uses the repo’s own /layouts/partials/ files: ico.html and _ico.html and the other (partial) uses /layouts/partials/svg.html

Neither one provides enough information to actually solve my problen at this time.
From what I can gather this should eventually work but can’t because I have no idea what to do to the ico.html file so that I can “markdownify” it, whatever that means:

---
title: "{{ <ico inbox-full material> }} Reports"
linkTitle: Reports
type: docs
tags:
  - intro
weight: 18
---

OK it looks like this only works if you dump your icons as svg files into /assets/svg/ and create your own template file in /layouts/partials/svg.html. I don’t know what that template should have in it.
Can you help out with that template file @iaeiou ?

Your syntax is wrong. This one is correct:

title: "{{< ico inbox-full material >}} Reports"

Use {{< instead of {{ <
(see the empty space)

You don’t need to do that, the step 2 of installation process is enough

Can that document be updated to reflect the changes in Hugo since version 0.115.1 which expects a config file to be found in hugo.toml, and not config.toml?

@iaeiou If we assume the method works, where would one expect to find what is displayed as " themes/hugo-shortcode-roneo-collection/assets/svg" on the instruction page, within one’s own project. For example in my project, after adding

theme = ['hugo-shortcode-roneo-collection', 'Docsy']

I do not have any folder in Themes other than Docsy. The site builds but never pulls the theme from roneo.
If I were to guess I would guess the theme = [‘hugo-shortcode-roneo-collection’, ‘Docsy’] is ignored and only the submodule directive is used for Docsy, but not for the roneo collection. If I try to duplicate the usage via a submodule I also do not get the folder in the themes directory.
As modules in hugo.toml:

  [module.hugoVersion]
    extended = true
    min = "0.115.1"
  [[module.imports]]
    path = "github.com/google/docsy"
    disable = false
  [[module.imports]]
    path = "github.com/google/docsy/dependencies"
    disable = false
  [[module.imports]]
    path = "github.com/RoneoOrg/hugo-shortcode-roneo-collection"
    disable = false

After cloning the repo into the themes directory I list the repo as a module in hugo.toml. The only caveat is that it doesn’t actually work, but it does successfully build the site without breaking it. It renders the following front matter:

---
title: "{{< ico inbox-full material >}} Reports"
linkTitle: Reports
type: docs
tags:
  - intro
weight: 18
lastmod: 2023-07-26T12:00:20.526Z
---

And it looks like this:

{{< ico inbox-full material >}} Reports

And in the text body of the markdown document I only see blank space where I expect the icon:

This is a placeholder for material icon short code here –>

The install documentation reads:

Install as Git submodule:

git submodule add https://gitlab.com/Roneo/hugo-shortcode-roneo-collection.git themes/hugo-shortcode-roneo-collection

I recommend Git submodules, as I’m not familiar with Hugo modules

OK I can report that following the installation method works in the sense that it does install.
The page does have a syntax error that would definitely break the build process.

{{< ico "moon" >}}

should be:

{{<ico "moon">}}

Fixing that means the site doesn’t throw an error when it builds.
However if one successfully follows the 2 step install process and corrects the syntax error one does not get any icons in any part (Front matter or body) of a hugo site if that site is minimum hugo_extended version 0.115.1

So as an example the following code:

{{% pageinfo %}}
On this page we are testing shortcodes imported from a theme.

{{ <ico "moon"> }} <-- There should be something there.

{{% /pageinfo %}}

Where you use a different and erroneous syntax again… Check out what you just posted above.

1 Like

This breaks the site if used in the body of the page:

{{< ico inbox-full material >}}

And although the ico.html file is most definitely in /themes/roneo…/layouts/shortcodes/ico.html the server generates an error message:

ERROR Rebuild failed: assemble: “/workspaces/doctool.dev.container/docs/content/en/docs/Main Menu/Reports/_index.md:16:1”: failed to extract shortcode: template for shortcode “ico” not found

This occurs for default icons as well, such as, {{< ico “heart” >}}

I’m sure there is a meaningful difference between when to use a shortcode and when to use a partial and I don’t know what that is, so I tried both and both don’t work, but shortcodes break the build and partials don’t. Is that even relevant?

The following in _index.md will successfully build but not generate an icon:

{{ partial “ico” “star” }} <– There should be something there.

Submitted an issue to the repository for these shortcodes