# A simple component

**To build a simple Loki Component, you will need to create a template-block in the XML layout, create a template and add a Loki-specific file `etc/loki_components.xml`. Once this is done, the block will automatically be *transformed* into a Loki Component with Alpine.js bindings. Calling upon the Alpine method `post()` will generate an AJAX request to Magento, after which all so-called targets will be updated.**

## Block definition in the XML layout
A simple component could first be defined by using the XML layout:

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <update handle="loki_components"/>
    
    <body>
        <referenceContainer name="after.body.start">
            <block
                name="loki-components.example"
                template="YireoTraining_ExampleLokiComponent::example.phtml"/>
        </referenceContainer>
    </body>
</page>
```

Note that the handle `loki_components` is added, to make sure AlpineJS and all of the specific Loki scripts are initialized.

Make sure to give thought to your block name, because it will be used as a unique identifier *and* the name of your Loki Component.

## Component definition in `etc/loki_components.xml`
Next, a file `etc/loki_components.xml` upgrades your block to an actual component. Note that the name of the component is equal to the name of your block:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
    <component name="loki-components.example" />
</components>
```

## The PHTML template
Next, a PHTML template `example.phtml` could be including a simple button:

```html
<div>
    <button @change="post">Refresh</button>
</div>
```

This tries to call a `post()` method in an Alpine component that you **did not write**. This is important to note. However, simply because you defined your block to be a Loki Component, the framework transforms your PHTML template output into the following:

```html
<div id="loki-components-example"
    x-data="LokiComponent"
    x-title="LokiComponentsExample"
    class="loki-components-example relative">
    <script ref="initialData" type="text/x-loki-init">{"value":null}</script>
    <button @change="post">Click</button>
</div>
```

As you can see, the Loki Components module changes the PHTML template as follows:

- The block name is used for `id` and `class`
- `x-data` refers to the AlpineJS component `LokiComponent` containing the method `post()`;
- `x-title` refers to the AlpineJS component ID (while this specific HTML attribute is also used by the DevTools)

The additional HTML `<script>` tag is generated too. It is not a JavaScript tag, but instead a JSON container that is used to insert data into the AlpineJS component instance via the `init()` method. The shown data here is a simplified version though.

## No data is saved
An important note of this simple component is that it does not save any data on the server side. The `post()` method simply makes an AJAX call and the current PHTML template will refresh. To save data on the server, we actually need to introduce a `ComponentRepository` class, which is explained on the next page "[Adding a `ComponentRepository` class](/checkout/dev/components/repository)"

## FAQ: Why is there a difference between `x-data` and `x-title`?
With `x-data`, an Alpine.js component is instantiated. With `x-title`, you only give a cosmetic title to the component, which is nice in the Alpine.js DevTools browser plugin.

The Loki Checkout tries to never use local data (`x-data='{"foo":"bar"}'`) or functions (`x-data="foobar()"`) to instantiate components. Instead, a JavaScript snippet is added to instantiate the component data via `Alpine.data('FooBar', () => {});` so that `x-data="FooBar"` is enough to instantiate the component. This separation is choosen to allow for future security restrictions (like PCI Compliance via CSP rules).

However, the Alpine.js data might be as generic `LokiCheckoutFieldComponent`, while the actual live component is dealing with a specific `street1` field instead. To help you navigate through components in the DevTools, the `x-title` attribute is added with a value like `LokiCheckoutShippingAddressStreet1`.
