Search code examples
laravelhtmx

Adding CSRF tokens to HTML buttons with HTMX and Laravel 10


I am using Laravel 10 and slowly incorporating HTMX (which I LOVE). I am attempting to add a data-hx-post to a button that POSTs to a web route I have defined. I am getting a 419 error. Ok, cool, seen this before- all I have to do is add @csrf to the button, right?

That approach worked with forms, but apparently not for buttons. The csrf directive correctly adds a hidden input field to the DOM, but I guess it doesn't get sent with the button POST like it does with forms. Is there a way to add CSRF tokens to native HTML buttons, or do I need to start writing some JavaScript to add the token after button press? I've poked around a few SO questions and that seems to be the most common advice, but I would really like to avoid using JavaScript where I can- that's why I'm using HTMX to handle it all for me :-).

Button code:

<button type="button" class="tailwind stuff" data-hx-post="route">
@csrf
  <span class="tailwind stuff">X</span>
</button>

I am not using Laravel Sanctum, this is a SPA with minimal JavaScript (basically all php and HTMX), I'm not using Livewire and I'm not using Alpine.js. I also see no output in my laravel.log file- I'm just receiving a 419 when I click the button. Any tips would be greatly appreciated.


Solution

  • You can let htmx send csrf token value with every request by attaching it to the body element with hx-headers attribute:

    <body hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'>
    

    This approach is explained here in more details (django-htmx docs). It should work same way with laravel, by using the above snippet.