← All posts

Crafting a Reusable SVG Icon Component in FlyntWP with Twig & ACF Pro

Crafting a Reusable SVG Icon Component in FlyntWP with Twig & ACF Pro

I’ve spent years battling the bloat and complexity of visual page builders, watching beautiful designs crumble under mountains of unnecessary divs and inline styles. That’s why I gravitated towards FlyntWP – it’s a breath of fresh air, a framework that empowers developers to build fast, clean WordPress sites without compromising on client content management. Forget slow load times and fighting with Core Web Vitals; FlyntWP prioritizes performance and a truly clean DOM from the ground up, largely thanks to its component-driven architecture and sensible build processes.

Today, I want to dive into a specific technique that really highlights FlyntWP’s power: building a truly reusable SVG icon component. Think about how many times you add social media icons, feature icons, or just general decorative SVGs across a site. In a page builder, you’re often stuck embedding raw SVG code, which is repetitive and hard to update, or relying on icon fonts, which come with their own performance drawbacks. FlyntWP, with its elegant combination of modular Twig components and ACF Pro, offers a far superior solution.

Our goal is to create a single, flexible Twig partial that we can call from any FlyntWP component, passing in just a few parameters to display the correct icon with the right styling. This keeps our markup DRY (Don't Repeat Yourself) and makes updates a breeze. Let's start with the data structure using ACF Pro. For our icons, we’ll create a simple field group that can be attached to any component where we need an icon. I typically make this a "clone" field group so it can be easily included. Inside, we’ll use a `Select` field named `icon_name` with choices like `facebook`, `twitter`, `instagram`, `email`, etc., mapping to the actual SVG file names or classes we’ll use. We might also add a `Text` field for an `icon_class` to allow for custom styling.

Next, we create our reusable Twig partial. I like to put these in a `templates/partials` folder within my theme, for instance, `templates/partials/_icon.twig`. This partial will take `icon_name` and `icon_class` as arguments. Here’s a simplified version of what that partial might look like:

{# templates/partials/_icon.twig #} {% if icon_name %} <svg class="icon icon--{{ icon_name }} {{ icon_class|default('') }}" aria-hidden="true"> <use xlink:href="#icon-{{ icon_name }}"></use> </svg> {% endif %}

Let's break that down. We’re checking if `icon_name` exists. Then, we render an SVG element. The `class` attribute uses BEM-like naming conventions (`icon`, `icon--facebook`) and includes any custom classes passed in via `icon_class`. The magic happens with `<use xlink:href="#icon-{{ icon_name }}"></use>`. This assumes you're using an SVG sprite, where all your SVGs are compiled into a single file and referenced by their ID. Vite, FlyntWP’s default build tool, makes setting up SVG sprites incredibly easy, pulling all SVGs from a specified directory and optimizing them. This approach means your browser only downloads one SVG file, and individual icons are pulled from that sprite, leading to fantastic performance and clean markup.

Now, how do we use this reusable partial within a FlyntWP component? Let’s say we have a `BlockHero` component and want to display a social media icon. In `BlockHero/index.twig`, after fetching our ACF data, we can call our `_icon.twig` partial like this:

{# src/components/BlockHero/index.twig #} <div class="BlockHero-socialLink"> {% include 'templates/partials/_icon.twig' with { icon_name: fields.social_icon_name, icon_class: 'BlockHero-socialIcon' } %} <a href="{{ fields.social_link_url }}">{{ fields.social_link_text }}</a> </div>

Here, `fields.social_icon_name` would come directly from our ACF `Select` field on the `BlockHero` component. Notice how clean and semantic this is. We’re not embedding any SVG code; we’re simply telling the component *which* icon to display and giving it a specific class for local styling within the `BlockHero` context. This pattern ensures extreme flexibility and maintainability. Need to change the core structure of how icons are rendered? You change `_icon.twig` once. Need to add a new icon? Add it to your SVG assets folder, update the ACF `Select` field, and it's available everywhere.

This level of modularity and programmatic control is precisely why FlyntWP shines. It’s not just about faster builds with Vite or cleaner output; it’s about a developer experience that genuinely enhances productivity and allows you to craft bespoke, high-performance websites without fighting an opinionated system. This approach means a lean DOM, minimal CSS, and ultimately, a fantastic experience for your users and excellent Core Web Vitals scores. Give it a try – you'll be amazed at how quickly you can build complex layouts with such elegant simplicity.