← lessons

Create a simple Magewire component in a Magento Luma template

Video Lesson

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/magewire

And since we are using it with Magento’s default Luma template, we will also need to install the compatibility module:

composer require magewirephp/magewire-requirejs

Once 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:

  1. A $count variable (type int) that starts at 0

  2. 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?