easy_svg_icon()
Print an icon from the Easy SVG library as inline SVG in any theme template, with the right accessibility attributes and an optional CSS class.
Function · Easy SVG · Status: Stable
easy_svg_icon() gives you one icon from the site's icon library as inline SVG markup, ready to echo in a template. You pass the icon's name, and optionally a CSS class and a label. Without a label the icon is treated as decoration and hidden from screen readers; with a label it is announced as an image with that name.
Usage
easy_svg_icon( string $name, array $args = array() ): string
When to use it
- In a classic or hybrid theme template (
header.php, a template part, afunctions.phphelper) where you want an icon next to a link or a heading. - In a block's
render.phpor arender_callback, where you build HTML in PHP. - In a page builder widget or a custom field output that runs PHP.
- On WordPress older than 7.1: the function reads the stored icon directly and needs no core icon registry.
When not to use it:
- Inside post content written by editors. Use the
[easy_svg_icon]shortcode or the core Icon block with theeasy-svgcollection instead. - When you need the drawing core's Icon block shows. The block draws what was handed to the icon registry at
init, which can differ from the stored markup (shapes rewritten to paths, strokes carried as classes).easy_svg_icon()prints the stored markup itself.
Parameters
The icon to print. Either the bare slug (heart) or the collection-qualified name (easy-svg/heart); both resolve the same icon. Everything before the first slash is the collection, everything after it is the slug. A slug is lowercase letters, digits, hyphens and underscores, starting and ending with a letter or digit (the pattern in EASY_SVG_ICON_NAME_PATTERN). The slug is the one shown in the library and in its copy button. If a name was already taken when the icon was added, WordPress appended -2, so check the library rather than guessing from the label.
Optional settings. Unknown keys are ignored.
class(string): CSS classes for the rootsvgelement, escaped withesc_attr(). Empty means no class attribute is added.label(string): the accessible name. A non-empty label makes the icon meaningful:role="img",focusable="false"andaria-labelare added. The label is attribute-escaped, so quotes, angle brackets,$and backslashes arrive intact and harmless.decorative(bool): overrides the default in either direction.truehides the icon (aria-hidden="true",focusable="false") even when a label is given, and drops the label.falsekeeps it meaningful even without a label; the name then falls back to the icon's stored title, then to its slug read as words (arrow-leftbecomesArrow left).
Default: array(), which renders a decorative icon with no class.
Return value
The icon's SVG markup with the class and accessibility attributes inserted into the root svg tag, ready to echo. An empty string when the icon does not exist, when its collection is not easy-svg and no easy_svg_icon_markup filter supplies it, or when that filter returns an empty string. If the markup has no svg root tag at all (only possible through the filter), it is returned unchanged without any added attributes.
Default
$args | Result on the root svg |
|---|---|
| none | aria-hidden="true" focusable="false" |
label set | role="img" focusable="false" aria-label="..." |
label set, decorative true | aria-hidden="true" focusable="false", no label |
decorative false, no label | role="img" focusable="false" aria-label="Stored title" |
Examples
A decorative icon next to text
The link already says what it does, so the icon is decoration and stays hidden from screen readers.
<a class="site-cart" href="<?php echo esc_url( home_url( '/cart/' ) ); ?>">
<?php echo easy_svg_icon( 'cart', array( 'class' => 'site-cart__icon' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php esc_html_e( 'Cart', 'mytheme' ); ?>
</a>
An icon-only button with a label
There is no visible text, so the icon carries the name. Translate the label.
<button type="button" class="menu-toggle" aria-expanded="false">
<?php
echo easy_svg_icon( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'easy-svg/menu',
array(
'class' => 'menu-toggle__icon',
'label' => __( 'Open menu', 'mytheme' ),
)
);
?>
</button>
A theme helper that survives a missing plugin
The theme keeps working when Easy SVG is deactivated or the icon was deleted, and falls back to a text marker.
function mytheme_icon( $name, $args = array() ) {
if ( ! function_exists( 'easy_svg_icon' ) ) {
return '';
}
$svg = easy_svg_icon( $name, $args );
if ( '' === $svg ) {
return '<span class="mytheme-icon-missing" aria-hidden="true">•</span>';
}
return '<span class="mytheme-icon">' . $svg . '</span>';
}
// In a template:
echo mytheme_icon( 'phone', array( 'class' => 'contact__icon' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
Meaningful without writing a label
decorative false names the icon after its title in the library, which is handy when the title is already good text.
echo easy_svg_icon( 'award', array( 'decorative' => false ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
// aria-label is the stored title, for example "Award"
The return value is printed without escaping on purpose: running wp_kses_post() or esc_html() over it would destroy the SVG. That is safe for the plugin's own icons, because the stored markup went through the site's SVG sanitizer and a second hardening pass (no scripts, no style elements, no animation elements, no event handlers, no external href) when it was added. It is only as safe as your easy_svg_icon_markup filters: anything a filter returns is printed as it is.
How it works
- The name is split at the first slash into collection and slug. Without a slash the collection is
easy-svg. easy_svg_icon_markup()looks up theesw_iconpost with that slug throughget_page_by_path()(only for theeasy-svgcollection) and takes itspost_content. Any other collection starts with an empty string.- The
easy_svg_icon_markupfilter runs on that markup, with slug and collection. - An empty result ends here and returns an empty string. No empty wrapper is invented.
- The class and the accessibility attributes are built and spliced into the first real
svgtag (a tag likesvgfoois skipped). They are inserted as text, not withpreg_replace(), so a label likePrice $20is not mangled.
Caching: there is no cache of its own. get_page_by_path() keeps its answer in the object cache group post-queries until any post changes, so repeated calls for the same icon in one request cost one database query. With a persistent object cache the lookup survives between requests too. The library switch under Icons, Settings does not matter here: the function is always loaded and reads the posts directly, even while the switch is off.
Pitfalls
- Size. The function adds no
widthorheight. An SVG with only aviewBoxgrows to the width of its container. Give the class a size, for examplewidth: 1em; height: 1em;. - Colour. The markup is printed as stored. The icon follows the text colour only if the SVG itself uses
currentColor(or leavesfillunset and your CSS setsfill: currentColor). Hard-coded colours in the file stay hard-coded. - Duplicate attributes. The class and ARIA attributes are inserted, not merged. If the stored root already has a
class, the root ends up with two, and browsers keep the first one, which is yours. Put all classes you need intoclass. - Label
"0". A label of0counts as empty in PHP, so the icon stays decorative unless you passdecorativefalse. - Renamed slug. Renaming an icon in the library keeps its slug, so templates keep working. Deleting an icon and adding it again can give a new slug (
heart-2), and every call then returns an empty string. - Not the block's drawing. Changes made with
easy_svg_registrable_iconsonly reach the Icon block andwp_get_icon(), never this function.