A tutorial on combining Laravel Components and HTMX

This is an implementation pattern for POST submissions (form submissions) using htmx and partial updates in the event of validation errors.

We will create a setup that submits form data via a POST request without reloading the entire page, and, if there are any errors, quickly updates only the form section (or the error display area).

1. Creating components for validation errors

Create a partial template for displaying error and success messages.

resources/views/test/partials/store.blade.php

HTML

copy

2. Add a ‘store’ action to the controller

Add a store action to app/Http/Controllers/TestController.php to receive POST data from the form.

PHP

copy

3. Adding a route (routes/web.php)

Add a route for receiving POST requests.

/mutunet/routes/controllers/routesTestController.php
* The above file has already been included in /mutunet/routes/web.php

PHP

copy

4. Add a form to the view (test/index.blade.php)

Add a form using hx-post.

resources/views/test/index.blade.php

HTML

copy

* As hx-headers='{“X-CSRF-TOKEN”: “{{ csrf_token() }}”}’ is set within the body tag of the base layout (layouts/app.blade.php), the CSRF token is sent automatically without the need to include @csrf within the form.

5. Verification of operation

  1. Reload http://localhost/mutunet/public/test/index in your browser.

  2. Leave the fields blank and click ‘Send’.

    • Check that the entire screen does not reload and that validation errors are displayed within the red box.

  3. Enter a title (up to 20 characters) and a comment (at least 5 characters), then submit.

    • Check that a success message appears in the green box.

Regarding ‘store.blade.php’,
we will adopt a policy of not using Blade directives for conditional statements and loops.
Please replace ‘@if’ and ‘@foreach’ with ‘<?php’.

Interview

This is the code from resources/views/test/partials/store.blade.php, where Blade directives such as @if and @foreach have been replaced with standard PHP control structures (<?php ... ?>).

HTML

copy

A quick note

  • XSS protection (escape processing) Blade’s {{ $variable }} automatically performs htmlspecialchars (XSS escaping), but when outputting variables using PHP tags, you can achieve the same level of escaping by writing <?php echo e($variable); ?>.

  • Alternative syntax (if: / endif;) When writing PHP within HTML, it is recommended to use if (...):~endif; or foreach (...):~endforeach; rather than curly brackets { }, as this makes the relationship with the HTML structure easier to understand.

An explanation I came across demonstrating the advantages of Laravel Blade directives

  • Improved readability

  • Code simplification

  • Template Inheritance and Componentisation: Security (XSS Countermeasures)

Unless there is something else besides these, I cannot see any reason to use Blade directives.

Explanation of the HTMX used

<form hx-post=”{{ route(‘test.store’) }}”
hx-target=”#form-result”
hx-swap=”outerHTML”
style=”max-width: 400px;”>
Could you please explain the ‘hx’ attribute?

Interviewer

This is an explanation of the htmx-specific attributes (hx-*) specified in the form tag.

In htmx, by adding these attributes, you can implement asynchronous communication (Ajax) and partial page updates using HTML alone, without having to write your own JavaScript.

1. hx-post=”{{ route(‘test.store’) }}”

  • Meaning: When a form submit event occurs, it asynchronously sends a POST request to the specified URL.

  • Action:

    • Unlike a standard HTML form, it does not reload or redirect the entire page, but instead submits the data to /test/store in the background.

    • It automatically parses the values of each input element in the form (such as name=”title” or name=”comment”) and includes them as request parameters.

2. hx-target=”#form-result”

  • Meaning: Specifies ‘which DOM element’ the response (HTML fragment) returned from the server should be applied to.

  • Action:

    • Specify this using the CSS selector syntax (where #form-result refers to the element with the ID ‘form-result’).

    • If this is not specified, by default the source element itself (in this case, the <form> tag) will be updated.

3. hx-swap=”outerHTML”

  • Meaning: Specifies ‘how’ the HTML returned from the server should be substituted for the target element (#form-result).

  • Action:

    • outerHTML replaces the target element—‘in its entirety, including the element itself’—with the response from the server.

    • If you specify innerHTML (the default), it will replace ‘only the inner content’ of the target element.

Summary of Overall Operation

  1. When the user clicks the ‘Submit’ button, the values of the form elements are sent in a single POST request to /test/store (the test.store root).

  2. Receive the component (store.blade.php) returned from the server (TestController@store).

  3. Replace the entire <div id=”form-result”></div> element on the screen with the received HTML  in its entirety.

I was able to add an error message to the screen by pressing the ‘Send’ button.