Examples
Basic
The simplest usage — pass a name in set:slug form. The icon
defaults to medium size and is hidden from screen readers.
Icon sets
Same API, four sources: fa, fa-regular,
fa-brands, and pficon. The set prefix maps to the vendored
directory under web/vendor/icons/.
fa:circle-check
fa-regular:envelope
fa-brands:github
pficon:cluster
Sizes
PF v6 ships six standalone size modifiers — sm, md,
lg, xl, 2xl,
3xl — that resolve to global icon-size tokens.
sm
md
lg
xl
2xl
3xl
Body sizes
Body-relative sizes (body-sm, body-default,
body-lg) match the surrounding body text's icon-size token. Use these when an icon sits
beside body copy.
body-sm icon.
Default body text with a
body-default icon.
Large body text with a
body-lg icon.
Heading sizes
Heading-relative sizes (heading-sm through heading-3xl)
match the surrounding heading's icon-size token. Use these when an icon sits beside heading copy.
heading-sm icon.
heading-md icon.
heading-lg icon.
heading-xl icon.
heading-2xl icon.
heading-3xl icon.
Sizing within container
Pass iconSize to size the icon glyph independently of its
size container. iconSize applies
pf-m-{iconSize} to .pf-v6-c-icon__content while
size stays on the wrapper.
size("3xl").iconSize("sm")
size("3xl").iconSize("md")
size("3xl").iconSize("lg")
size("3xl").iconSize("xl")
size("3xl").iconSize("3xl")
Inline
Set inline=true so the icon inherits the surrounding font size and color via PF's
pf-m-inline modifier. Useful inside running prose.
Inline icons inherit the surrounding font size and color. For example, this
check icon and this
warning icon flow with the text — no extra
size needed.
Status colors
Pass status to color the icon via PF v6 semantic tokens:
info, success, warning,
danger, or custom.
info
success
warning
danger
custom
In progress
inProgress=true adds pf-m-in-progress on the wrapper and
renders a __progress overlay containing the PF v6 spinner. PF's CSS hides
__content and shows __progress via opacity — no JS involved.
inProgress(), the wrapper gets
pf-m-in-progress and an additional __progress overlay is
rendered containing the PF v6 spinner. PF's CSS hides __content (opacity 0) and shows
__progress (opacity 1) — no JavaScript involved.
Custom in-progress icon
Pass progressIcon to render a Font Awesome / pficon glyph inside the
__progress overlay instead of the default PF v6 spinner.
Icon.of("fa:download") with
inProgress().progressIcon("fa:hourglass-half")
— the hourglass glyph renders inside __progress instead of the default PF spinner.
progressIcon — falls back to the default
components/feedback/spinner inside __progress.
With accessible label
Pass label to expose the icon to assistive technology — the rendered
<svg> gets role="img" and the matching
aria-label. Without a label, the SVG is marked
aria-hidden="true".
label to expose the icon to assistive tech. The rendered
<svg> gets role="img" and the matching
aria-label.
label, the SVG is marked aria-hidden="true" —
appropriate when the icon is purely decorative or sits next to text that already conveys the meaning.
Documentation
Icon component props
Parameters accepted by {#include components/icon ... /}. Model mode: pass
iconModel=<Icon> built in Java instead — the Java tab on each example shows the
builder. All are passed as Qute named parameters.
| Name | Type | Default | Description |
|---|---|---|---|
* name
|
String "set:slug"
|
— |
Icon identifier. set is one of fa,
fa-regular, fa-brands,
pficon. slug is the icon's filename without the
.svg.
|
size
|
"sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "body-sm" | "body-default" | "body-lg" | "heading-sm" |
"heading-md" | "heading-lg" | "heading-xl" | "heading-2xl" | "heading-3xl"
|
— |
Renders pf-m-{size} on the icon wrapper. Standalone sizes (sm–3xl) use fixed tokens; body-* and
heading-* inherit the matching text-relative token.
|
iconSize
|
Same union as size
|
— |
Sizes the icon glyph independently from its container. Applies
pf-m-{iconSize} to
.pf-v6-c-icon__content while size stays on the
wrapper.
|
status
|
"info" | "success" | "warning" | "danger" | "custom"
|
— |
Adds pf-m-{status} to the icon's
__content element, coloring the glyph via the matching semantic color
token.
|
inline
|
boolean |
false
|
When truthy, applies pf-m-inline so the icon inherits the surrounding font
size and color.
|
inProgress
|
boolean |
false
|
Adds pf-m-in-progress on the wrapper and renders an additional
__progress overlay alongside __content. PF v6 CSS
swaps which is visible via opacity — no JavaScript involved.
|
progressIcon
|
String "set:slug"
|
PF v6 spinner (components/feedback/spinner)
|
Glyph rendered inside the __progress overlay when
inProgress=true. Omit to use the dedicated PF v6 spinner component; pass a name
to override with a Font Awesome / pficon glyph. Has no effect when
inProgress is falsy.
|
label
|
String | — |
Accessible label. When provided, the <svg> renders with
role="img" and aria-label; otherwise it gets
aria-hidden="true".
|
icons:svg() arguments
The icons Qute namespace exposes the raw resolver. Use it when you need just the
<svg> without PF's .pf-v6-c-icon chrome — for
example, inside a pf-v6-c-tree-view__node-toggle-icon or a button's
pf-v6-c-button__icon. Always chain .raw so Qute doesn't
HTML-escape the SVG.
| Position | Type | Description |
|---|---|---|
* 1 — name
|
String "set:slug"
|
Same identifier as the component's name param. An unknown name renders a
visible red placeholder marked data-missing.
|
2 — label
|
String (optional) |
Accessible label. Same semantics as the component's label: when present the
SVG gets role="img" + aria-label, otherwise
aria-hidden="true".
|
Returns a Qute RawString, so the usage is
{icons:svg('fa:check').raw} or
{icons:svg('pficon:cluster', 'Cluster overview').raw}.
Usage
Component vs. raw namespace. Prefer the
{#include components/icon /} component whenever you want the full PF v6 icon chrome
— size modifiers, status colors, inline / in-progress flags. Reach for
{icons:svg(...).raw} only when you need a bare SVG inside markup that supplies its
own chrome (tree-view toggles, button icon slots, code-editor controls).
Where the icons live. SVGs are vendored under
runtime/.../META-INF/resources/web/vendor/icons/, one subdirectory per set:
| Set prefix | Vendor directory | Source |
|---|---|---|
fa
|
vendor/icons/fa-solid/
|
Font Awesome 7 Solid |
fa-regular
|
vendor/icons/fa-regular/
|
Font Awesome 7 Regular |
fa-brands
|
vendor/icons/fa-brands/
|
Font Awesome 7 Brands |
pficon
|
vendor/icons/pficon/
|
PatternFly v6 pficons |
Missing icons. A typo like fa:doesnotexist renders a red square
placeholder carrying data-missing and logs one WARN per unique missing
name. The smoke tests assert that data-missing never appears in any
rendered route — so a bad name fails CI loudly rather than shipping silently.
Caching. Each SVG is read from the classpath once, parsed to extract its
viewBox and inner markup, and cached for the JVM's lifetime. Missing names are cached
too — repeated lookups don't re-walk the classpath.
Accessibility. When you pass a label, the SVG renders with
role="img" and aria-label. Omit
label for icons that are purely decorative or that sit next to text already conveying
the meaning — they'll get aria-hidden="true" and stay out of the accessibility tree.
Design — why two APIs?
Why icons: (plural) and not icon:?
The namespace name marks the catalog; the method name is a single lookup into it — same convention as
users.find(id) in OO code. Reading
{icons:svg('fa:check')} as "from the icons collection, get the SVG for fa:check"
matches the mental model better than treating the namespace as a singular noun. The cost is a one-letter
inconsistency with
{#include components/icon /}
(singular path) — we accepted that to keep the catalog metaphor.
Why a component and a namespace function? The two surfaces exist because PatternFly markup has two contexts:
-
Standalone icons need PF's full chrome —
.pf-v6-c-iconwrapper for size / inline / in-progress modifiers, plus.pf-v6-c-icon__contentfor status color and iconSize. The{#include components/icon ... /}component is that chrome, parameterised. It uses Qute's named include parameters (e.g.size="2xl" status="success" inProgress=true) because the component takes eight optional inputs, and named params keep call sites readable. -
PatternFly-supplied slots already provide their own chrome —
.pf-v6-c-button__icon,.pf-v6-c-tree-view__node-toggle-icon, and friends. They expect a bare<svg>inside; wrapping in another.pf-v6-c-iconcontainer would nest chrome inside chrome and break the layout. The{icons:svg(name).raw}namespace returns just the SVG — positional args (name, optionallabel) are enough because there's no chrome to configure.
Could it be unified? A single {icons:svg(name).chrome} accessor
looks tempting, but Qute namespace functions are positional. Chrome with eight optional inputs would force either an
unreadable positional call (icons:svg('fa:save', '2xl', null, 'success', false, true, null, 'Saving')) or a fluent builder Qute's grammar wasn't built for. The include's named parameters are the right fit for chrome
configuration; the namespace function is the right fit for "just the SVG". That's why they coexist.
Rule of thumb. If you're authoring a standalone icon, reach for the component. If PatternFly's CSS
already gives you an icon slot, reach for icons:svg(...).raw.