hugolify-theme-icons
Icons are a module of their own, hugolify-theme-icons. It renders Lucide for UI and content icons, and Simple Icons for brands.
The module is opt-in: a project that does not import it renders no icons. It ships no framework CSS and completes hugolify-theme-design-system, which bundles no icon of its own.
Not compatible with hugolify-theme-bootstrap
For now the module targets hugolify-theme-design-system only. hugolify-theme-bootstrap comes with its own icons — the Bootstrap Icons webfont — and both define a.icon class: importing the two together makes them collide.Install
/config/_default/module.yaml
imports:
- path: github.com/hugolify/hugolify-theme/v2
- path: github.com/hugolify/hugolify-theme-design-system # styling module
- path: github.com/hugolify/hugolify-theme-icons # icons
The module imports Lucide and Simple Icons as Hugo modules and mounts them on role-based paths (assets/icons/ui/, assets/icons/brands/), so swapping an icon set is a one-line change and no icon file is committed to your project.
Requires Hugo >= 0.128.0 (templates.Defer).
Usage
{{ partial "icon" "map-pin" }} {{/* UI icon — Lucide name, as-is */}}
{{ partial "icon" "brand:github" }} {{/* brand icon — Simple Icons */}}
The name is the filename: there is no mapping table and no alias layer. Browse the Lucide icon list to find a name.
The rendered DOM is a single element, no inline SVG:
<i class="icon icon-map-pin" aria-hidden="true"></i>
Approach
Icons are rendered via CSS mask-image from inline SVG data-URIs. No icon font, no SVG sprite, no request per icon.
.icon {
background-color: var(--icon-color, currentColor);
display: inline-block;
height: var(--icon-size, 1em);
mask: var(--icon-glyph) center / contain no-repeat;
vertical-align: -0.125em;
width: var(--icon-size, 1em);
}
Each icon only differs by its --icon-glyph. The SVG is used as an alpha mask, so its own colors are irrelevant: the icon inherits the current text color via currentColor and scales with the font size.
Size and color are overridden with the two custom properties:
.main-menu .icon {
--icon-color: var(--color-brand);
--icon-size: var(--size-24);
}
Brand icons render monochrome — the norm for social rows. A colored logo needs an inline SVG instead of a mask.
Build
There is no project-side build step and no Node script. The subset ships natively:
partial "icon"registers each name used during the render.- After the full render,
templates.Deferresolves the union of those names. - One stylesheet is emitted (minified and fingerprinted in production) with the base
.iconrule plus one--icon-glyphper icon actually used.
Nothing to run, and nothing to commit: there is no yarn build:icons step as with the Bootstrap Icons font, and no generated font file in the project.
An unknown name logs a build warning and renders nothing — the default glyph is an empty SVG, so a missing icon is invisible rather than a solid square.
Missing brands
Some brands are dropped by both Simple Icons and Lucide. The module ships curated SVGs in its own assets/icons/brands/, and local assets take precedence over the imported modules — so you can add a missing brand in your project at the same path:
assets/
└── icons/
└── brands/
└── linkedin.svg