Introduction

WordPress is the world’s most widely used content management system (CMS), powering everything from personal blogs to large-scale government and enterprise websites. Like other CMSs, it provides a flexible framework for creating, managing, and publishing digital content without requiring deep technical knowledge.

Across content management systems (CMSs), icons play a key role in making navigation intuitive and content more scannable. They improve usability, enhance visual appeal, and convey information at a glance. While WordPress does not yet include a native icon block, there are several plugins that fill the gap. One of the most versatile is the Icon Block plugin.

This plugin is easy to use out of the box—it includes default icons from the WordPress icons library, allows you to insert your own SVGs, and gives you options for rotation, colour, alignment, and more. In this guide, we’ll show you how to build your own custom icon library, link it with your theme, and even load icons dynamically for scalable, maintainable WordPress projects.

 

 Screenshot of a WordPress icon library interface. Icons are displayed in a grid with categories like Amenities, Bed, Business, Checklist, Concierge, Contact, Education, Facebook, Facilities, Fitness, Graduation hat, Landmark, LinkedIn, Location, Map, Offerings, Services, Shuttle, Twitter, Umbrella, Values, and WiFi. A search bar and filter options appear on the left side
The WordPress icon library provides designers and content editors with a consistent set of visual symbols—such as maps, services, fitness, and social media icons—that can be scaled, customized, and reused across a site.

Build your own icon library

The default WordPress icons are useful, but in most cases, you’ll want to include your own. For one-off usage, you can paste SVG code directly into the Custom Icon option. However, if you need icons across multiple pages, it’s more efficient to create a custom icon library.

Refer to the following steps to build your own icon library:

  1. Create registerIcons.js file in your theme & add the following code
  2. Enqueue the JS file in your functions.php file
  3. (Optional) Add JSON file in theme to load icons dynamically

Step 1: Create registerIcons.js file & add the following code

// Add custom icons to the Icon Block.
wp.domReady( () => {

	const { __ } = wp.i18n;
	const { addFilter } = wp.hooks;

	function addCustomIcons( icons ) {

		const customIcons = [
			{
				isDefault: true,
				name: 'bookmark',
				title: __( 'Bookmark', 'icon-block' ),
				icon: '<your svg code>',
				categories: [ 'category-one' ],
			},
			{
				name: 'cloud',
				title: __( 'Cloud', 'icon-block' ),
				icon: '<your svg code>',
				categories: [ 'category-two' ],
			},
		];

		const customIconCategories = [
			{
				name: 'category-one',
				title: __( 'Category One', 'your-theme' ),
			},
			{
				name: 'category-two',
				title: __( 'Category Two', 'your-theme' ),
			},
		];

		const customIconType = [
			{
				isDefault: true,
				type: 'example-icons',
				title: __( 'Example Icons', 'your-theme' ),
				icons: customIcons,
				categories: customIconCategories,
			},
		];

		// append custom icons to WordPress icons
		const allIcons = [].concat( icons, customIconType );

		return allIcons;
	}

	addFilter(
		'iconBlock.icons',
		'your-theme/example-custom-icons',
		addCustomIcons
	);
});

Step 2: Enqueue the JS file in your functions.php file

function theme_enqueue_scripts() {
    wp_enqueue_script(
        'theme-script', // Handle
        get_template_directory_uri() . '/assets/js/registerIcons.js', // File path
        '1.0.0', // Version (optional)
        true // Load in footer (true) or head (false)
    );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_scripts' );

The above steps would add a new Icon group called Example Icons & 2 categories inside it. These would be available in addition to the WordPress Icons. If you want to only have the custom icons, you can skip concat & directly return customIconType instead of allIcons.

Dynamically load icons from your theme files

To make this more reusable across different projects, we made a mini plugin that fetches icons added in a JSON file to make the process more dynamic & seamless.

Following is the structure of the plugin:

Step 1: In your plugin’s php file, add the following code: 

/**
 * Enqueue the editor script and pass custom icons from JSON.
 */
function theme_custom_icons_script(): void {
	// Path to the custom-icons.json file in the active theme directory.
	$json_path = get_stylesheet_directory() . '/custom-icons.json';
	$json_data = [];

	if ( file_exists( $json_path ) ) {
		$json_content = file_get_contents( $json_path );
		$json_data = json_decode( $json_content, true );
	}

	wp_enqueue_script(
		'custom-icon-loader-editor',
		plugin_dir_url( __FILE__ ) . 'build/editor.js',
		['wp-blocks', 'wp-element', 'wp-hooks', 'wp-i18n'],
		1,
		true
	);

	// Pass the decoded JSON icons to JavaScript as a global variable.
	wp_localize_script('custom-icon-loader-editor', 'CustomIcons', [
		'icons' => $json_data
	]);
}

add_action( 'enqueue_block_editor_assets', 'theme_custom_icons_script' );

Step 2: Create editor.js file

// Add custom icons to the Icon Block.
wp.domReady( () => {
	const { __ } = wp.i18n;
	const { addFilter } = wp.hooks;

	function addCustomIcons( icons ) {
		const customIcons = (CustomIcons && Array.isArray(CustomIcons.icons)) ? CustomIcons.icons : [];

		// Create Icons array from localized custom-icons.json file.
		const formattedIcons = customIcons.map(icon => ({
			isDefault: icon.isDefault || false,
			name: icon.name,
			title: icon.title,
			icon: icon.svg,
			categories: icon.categories
		}));
		// Create Icon categories array from localized custom-icons.json file.
		const customIconCategories = [
			...new Set(CustomIcons.icons.flatMap(item => item.categories))
		].map(category => ({
			name: category,
			title: category[0].toUpperCase() + category.slice(1)
		}));

		const customIconType = [
			{
				isDefault: true,
				type: 'custom-icons',
				title: 'Custom Icons',
				icons: formattedIcons,
				categories: customIconCategories,
			},
		];

		return [].concat( icons, customIconType );
	}

	addFilter(
		'iconBlock.icons',
		'custom/custom-icons',
		addCustomIcons
	);
} );

Step 3:  Create a custom-icons.json file in your active theme with the following structure

[
	{
		"isDefault": true,
		"name": "mail",
		"title": "Mail",
		"svg": "<your svg code>",
		"categories": [ "category-1" ]
	},
	{
		"isDefault": true,
		"name": "search",
		"title": "Search",
		"svg": "<your svg code>",
		"categories": [ "category-2" ]
	},
]

That’s it! You now have a dynamic icon system that can be updated simply by editing the JSON file.

Examples in Action

1. Loyalist College – Orientation Page

On the Loyalist College Orientation page (part of the “Life at Loyalist” section), custom SVG icons are used effectively alongside textual content to enhance visual navigation. For example, icons appear next to section headings like “Orientation Schedule”, “ Intro to Student Services” and “Upcoming Events”, creating visual cues that help guide the reader through upcoming events and details.

Loyalist College Orientation page: a row of large, colorful circular icons for Orientation schedule (calendar icon), Intro to Student Services (clipboard icon), Start of term information (newspaper icon), International orientation (globe icon), and Upcoming events (theater masks icon).
Loyalist College uses bold, colourful icons to make orientation content scannable and fun. The icons highlight key student needs—schedules, services, term info, international orientation, and events—capturing the excitement of starting college life.

2. University of Georgia – Center for Continuing Education & Hotel – Amenities page

On the University of Georgia Hotel Amenities and Perks page, we implemented icon-style visuals (e.g., next to categories such as “Business Center,” “Onsite Fitness Center,” and “Free shuttle around town”) to complement the text and improve readability. These icons help break up sections, draw attention to key offerings, and provide a clean, hotel-style look and feel.

University of Georgia Hotel amenities page: a grid of refined, monochrome icons with short text descriptions, including icons for Business Center (wifi symbol), Onsite Fitness Center (martini glass with dumbbell), In-room amenities (suitcase), Borrow our bikes (bicycle), Free shuttle (bus stop marker), Ideal location (map pin), Special discounts at the golf course (golf flag), Exclusive access to student center (dumbbell), and Seasonal access to pool (swimmer)
The University of Georgia Hotel site uses refined monochrome icons to guide guests to amenities. Each icon—wifi, fitness, shuttle, bikes, golf, pool, and more—communicates services at a glance, reinforcing the brand’s hospitality tone.

Why icons work so well

Icons significantly enhance the user experience across both projects. They establish a clear visual hierarchy, making content more scannable for users browsing quickly. At Loyalist College, the playful and energetic icons reflect the fun spirit of orientation week, while at the University of Georgia Hotel, the polished icons align with the professional hospitality tone of the site, reinforcing each brand’s identity. Paired with text, these icons also improve accessibility by aiding comprehension for visual readers and ensuring crisp, scalable display through SVGs. Finally, by maintaining a consistent icon style across elements, both websites achieve a modern, cohesive look that strengthens their overall design.

Final thoughts

The Icon Block plugin is a powerful tool for extending the WordPress editor with flexible, custom icons. It supports multiple methods—manual entry, theme integration, and dynamic JSON loading—which makes it adaptable for different use cases.
That said, there are some limitations worth noting:

  • Multisite Restriction: On WordPress multisite setups, only super admins can add/edit icons to pages. Regular site users & admins cannot add or modify icons as it breaks the block since it’s trying to add html (SVG) which is not allowed in multi-site setups. You might face a block recovery error when the page is opened.
     
  • Maintaining Icon library dynamically: Icons must be pre-registered in code or JSON. There’s currently no other way to add icons from the WordPress admin without editing the JSON files. It would be good to have a UI that can enable this.
  • Open Issues: See GitHub issue #36 for ongoing discussion.

Need help with WordPress development?

Customizing WordPress often goes beyond what plugins provide out of the box. If you’d like expert guidance with building custom blocks, optimizing your theme, or setting up scalable icon systems, our team can help.

Get in touch with us to discuss your WordPress project and see how we can make your site more powerful, flexible, and user-friendly.