Iconseasy_svg_icon()

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, a functions.php helper) where you want an icon next to a link or a heading.
  • In a block's render.php or a render_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 the easy-svg collection 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

body
$namestring
Required

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.

body
$argsarray

Optional settings. Unknown keys are ignored.

  • class (string): CSS classes for the root svg element, escaped with esc_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" and aria-label are added. The label is attribute-escaped, so quotes, angle brackets, $ and backslashes arrive intact and harmless.
  • decorative (bool): overrides the default in either direction. true hides the icon (aria-hidden="true", focusable="false") even when a label is given, and drops the label. false keeps 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-left becomes Arrow left).

Default: array(), which renders a decorative icon with no class.

Return value

returnstring

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

$argsResult on the root svg
nonearia-hidden="true" focusable="false"
label setrole="img" focusable="false" aria-label="..."
label set, decorative truearia-hidden="true" focusable="false", no label
decorative false, no labelrole="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">&bull;</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

  1. The name is split at the first slash into collection and slug. Without a slash the collection is easy-svg.
  2. easy_svg_icon_markup() looks up the esw_icon post with that slug through get_page_by_path() (only for the easy-svg collection) and takes its post_content. Any other collection starts with an empty string.
  3. The easy_svg_icon_markup filter runs on that markup, with slug and collection.
  4. An empty result ends here and returns an empty string. No empty wrapper is invented.
  5. The class and the accessibility attributes are built and spliced into the first real svg tag (a tag like svgfoo is skipped). They are inserted as text, not with preg_replace(), so a label like Price $20 is 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 width or height. An SVG with only a viewBox grows to the width of its container. Give the class a size, for example width: 1em; height: 1em;.
  • Colour. The markup is printed as stored. The icon follows the text colour only if the SVG itself uses currentColor (or leaves fill unset and your CSS sets fill: 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 into class.
  • Label "0". A label of 0 counts as empty in PHP, so the icon stays decorative unless you pass decorative false.
  • 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_icons only reach the Icon block and wp_get_icon(), never this function.