Skip to main content

Crafting a Reusable Button Component in FlyntWP for Leaner, Faster Sites

I've spent years battling the bloat of low-code page builders, watching meticulously designed layouts crawl under the weight of excessive DIVs and inline…

I’ve spent years battling the bloat of low-code page builders, watching meticulously designed layouts crawl under the weight of excessive DIVs and inline styles. It’s frustrating when you pour hours into optimizing images and server response times, only for the page builder to spit out hundreds of kilobytes of unnecessary CSS and JavaScript, gutting your Core Web Vitals. That’s why I fell in love with FlyntWP. It’s a breath of fresh air, a philosophical shift back to thoughtful, programmatic development that doesn’t compromise on speed or flexibility. Flynt lets you build exactly what you need, with no fluff, and everything is optimized by design.

Today, I want to dive into a super practical technique that exemplifies FlyntWP’s power: building truly reusable, modular components. Let’s tackle something as fundamental as a button. In many page builders, adding a button means dragging, dropping, and then painstakingly replicating its styles every single time, or relying on a global style setting that’s often too broad. With FlyntWP, we can create a single Twig partial that handles all our button needs, ensuring consistency and performance across the entire site.

Here’s how I set up a robust, reusable _Button.twig component that can be easily dropped into any FlyntWP module. First, I create a dedicated components directory within my theme’s templates folder – or sometimes just a partials directory if I prefer. This keeps global elements neatly organized and separate from module-specific Twig files. Inside this directory, I create my _Button.twig file. The underscore _ is a common convention for partials or include-only files.

Inside _Button.twig, the code is lean and purposeful:

<a href="{{ link }}" class="button button--{{ style|default('primary') }}">
  {{ text|default('Learn More') }}
</a>

This simple snippet does a lot. It expects three parameters: link (the URL the button points to), text (the display text), and style (a class suffix to modify its appearance, like primary, secondary, or outline). I use Twig’s default filter to provide fallbacks, making the component resilient even if a parameter isn’t explicitly passed. This ensures that even if I forget to define a style, it defaults to primary, and if text is missing, it says “Learn More.”

Now, how do we use this? Let’s say I’m building a “Hero” module. In my Hero/index.twig file, I’d simply include the button like this:

{% include 'templates/components/_Button.twig' with {
  link: fields.buttonLink.url,
  text: fields.buttonText,
  style: fields.buttonStyle
} %}

Notice how I’m passing the values from my ACF Pro fields directly into the component. My Hero module’s functions.php would define an ACF field group with buttonLink (a Link field), buttonText (a Text field), and buttonStyle (a Select field with choices like ‘primary’, ‘secondary’, ‘outline’). This creates a beautiful separation of concerns: ACF handles the content and options, the module’s Twig file orchestrates the components, and the _Button.twig partial focuses solely on rendering a button.

The benefits here are huge. Firstly, consistency. Every button on the site, regardless of where it appears, will use the same HTML structure and, with the right CSS, the same visual styling. Secondly, maintainability. If I need to change the button’s markup – maybe add an icon or a data attribute – I only update _Button.twig once, and the change propagates everywhere. No more hunting through dozens of module files or struggling with global builder settings. Thirdly, performance. This approach results in incredibly clean, semantic HTML. There’s no extraneous wrapper DIVs or inline styles generated by a heavy page builder. When Vite compiles my assets, it only pulls in the CSS needed for these clearly defined classes, resulting in minuscule stylesheets and lightning-fast load times. This directly translates into stellar Core Web Vitals scores, something every client (and developer) loves to see.

This modularity, fueled by Twig and ACF Pro, is at the heart of FlyntWP’s appeal. It lets you build complex, dynamic layouts using simple, composable pieces, all while keeping your codebase lean, performant, and a joy to work with. It’s a strategic move towards a faster, more sustainable web.