Create a simple Magewire component in a Magento Luma template
Learn how to create a simple Magewire "hello world" component in a Magento Luma template.
Lesson Content
Magewire is a library which allows you to create dynamic Javascript components, but without writing any Javascript — just PHP. It's inspired by Laravel's Livewire library and brings the same reactive capabilities to Magento.
Before continuing, ensure Magewire is installed:
composer require magewirephp/magewireAnd since we are using it with Magento’s default Luma template, we will also need to install the compatibility module:
composer require magewirephp/magewire-requirejsOnce these modules are installed, you’re ready to go.
We will build a simple counter component which increments a value every time a button is clicked. This will help demonstrate Magewire's reactive capabilities, while keeping things straightforward.
Think of this as the "Hello World" of Magewire components - simple enough to understand quickly, but showing off its core concept of reactivity.
I've set up a simple route at /counter which returns a standard Magento Page object. This will render a blank page in the standard 2-column layout.
First, let's create our component. Create a Magewire directory within your module, then add a new Counter.php file.
This will be a standard Counter class which extends Magewire's Component class. We'll make two things:
- A - $countvariable (type- int) that starts at- 0
- An - increment()function that adds 1 to our count
These will both have a public visibility so we can access them from our template file.
Magewire/Counter.php
<?php
declare(strict_types=1);
namespace Vendor\Module\Magewire;
use Magewirephp\Magewire\Component;
class Counter extends Component
{
    public int $count = 0;
    public function increment(): void
    {
        $this->count++;
    }
}Next, we need to create a counter_index_index.xml layout file for our /counter route. We'll add our block to the main container.
The important part here is that Magewire components must be passed in as an argument named magewire - this naming is required for things to work properly.
view/frontend/layout/counter_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="main">
            <block name="counter" template="Vendor_Module::counter.phtml">
                <arguments>
                    <argument name="magewire" xsi:type="object">Vendor\Module\Magewire\Counter</argument>
                </arguments>
            </block>
        </referenceContainer>
    </body>
</page>Finally, let's create our template file.
What’s neat about Magewire is that it automatically makes a “magewire” variable available within our template. But we should still set up a doc block mapping it to our related Magewire component class to get IntelliSense lookup functionality.
Then we will add our counter display and increment button:
view/frontend/templates/counter.phtml
<?php /** @var \Vendor\Module\Magewire\Counter $magewire */ ?>
<div>
    <h1><?= $magewire->count ?></h1>
    <button wire:click="increment()">+</button>
</div>Important: Magewire can only attach itself to a single root node in your template. Always wrap your Magewire template content in a single parent div to avoid issues.
Here's where the magic happens - we're echoing the count with PHP, but Magewire will automatically update it with JavaScript when the button is clicked!
The wire: prefix is Magewire's special prefix for reactive features, and click tells Magewire to call our PHP increment() function whenever someone clicks the button.
Load up your /counter page and try clicking the button. You'll see the counter increment in real-time, all powered by that simple PHP component we created, and without writing any JavaScript. So, so cool… right?