I tried to follow the mentioned steps in the related PR and found some needed changes (for me). But unfortunately, although it first seems to work, I ran into an issue related to the session / nonce / CSRF.
Currently the @livewireScripts or the ESM version @livewireScriptConfig won’t set a CSRF token, which will break on events like wire:click or wire:submit.
Has anyone a hint, why the csrf_token() will return null? Am I missing something?
… I tried to debug this and am quite not sure if I miss something fundamental.
It seems that the session will not be persistent between different requests. Secondly, at every point in code, the function csrf_token() will return null.
However, at the moment, I’m applying the following workaround to ensure that the Livewire components function properly:
I’ve encountered same issue in the past where the CSRF token wasn’t generated on pages managed by WordPress itself.
I guess it’s due to WordPress pages aren’t managed by the Laravel router, so doesn’t trigger a middleware that initiates the session which generates the token.
I build manually livewire and alpine (with some plugin) with radicle, and that was the missing part to work nicely
For information i just have a LivewireServiceProvider with
public function register(): void
{
add_filter('wp_head', function () {
echo Blade::render('@livewireStyles');
});
add_filter('wp_footer', function () {
echo Blade::render('@livewireScriptConfig');
});
add_action('wp_loaded', fn () => app('session')->isStarted() || app('session')->start());
}
and app.ts is
// We add Livewire/Alpinejs manually to be more flexible
// @see https://livewire.laravel.com/docs/alpine#manually-bundling-alpine-in-your-javascript-build
import {Livewire, Alpine} from '../../vendor/livewire/livewire/dist/livewire.esm';
import resize from '@alpinejs/resize'
Alpine.plugin(resize)
Livewire.start()
import.meta.webpackHot?.accept(console.error);
Thank you; this fixed a lot of things. However, two issues still remain unfixed for me:
The error related to the bootloader part: Method Roots\Acorn\Application::configure does not exist
The Session::token() remains the same only when I send a Livewire XHR request.
Cookies aren’t generated on a normal page request (considering that I’m using local server).
I’ve implemented the solutions provided in this thread and it works perfectly:
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Session\SessionManager;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
public function register(): void
{
add_action('init', $this->startSessionManually(...));
add_action('shutdown', $this->saveSessionManually(...));
}
/**
* Starts the session manually during the WordPress 'init' hook.
*
* This method ensures that a Laravel session is initialized within
* WordPress, allowing for session-based functionality across
* the application. If a session is not already active and a session
* cookie is present, it sets the session ID and starts the session.
*/
public function startSessionManually(): void
{
$session = app('session');
if (! $session instanceof SessionManager || $session->isStarted()) {
return;
}
if (empty($_COOKIE[$session->getName()])) {
return;
}
$session->setId($_COOKIE[$session->getName()]);
$session->start();
$session->regenerate(false); // Force reloading session data.
session('user')?->setSessionManager($session);
}
/**
* Saves the session manually during the WordPress 'shutdown' hook.
*
* This method ensures that any changes to the session are properly
* saved before the script ends. It checks if the session is active
* and saves it, preserving session data across requests.
*/
public function saveSessionManually(): void
{
$session = app('session');
if (! $session instanceof SessionManager || ! $session->isStarted()) {
return;
}
$session->save();
}
}
But the Illuminate Validator class of which the MessageBag is passed to the front-end does not work anymore:
if ($validator->fails()) {
return redirect('/inloggen')
->withErrors($validator)
->withInput();
}
When I disable the process of startin the session manually:
The errors from the Validator MessageBag are shown again.
I’m not sure yet about what the cause could be but being stuck for a few hours now I hope someone can help me.
EDIT:
Using this ugly solution it is possible to display the errors:
if ($validator->fails()) {
session()->flash('errors', $validator->errors());
return redirect()->back()->withInput();
// Does not work because of session mismanagement?
// return redirect('/inloggen')
// ->withErrors($validator)
// ->withInput();
}