Closed aerni closed 1 year ago
Does the component work with v2? I didnt understand the cache part (key) when implementing v3 component rendering.
In V2 you had to make sure that Livewire scripts were not cached.
I didn‘t look into it yet, but that could be a way to start.
Good point @jonassiewertsen.
Seems like Livewire does not inject the styles/scripts automatically when half/full cache is enabled. As soon as I add them manually into the layout, the component works fine.
Interesting! Simply adding the tags manually to make it usable if caching is turned on is a great workaround.
Before using this as a permanent fix, I would like to figure out how complex it is to force the style and script injection if caching is turned on.
I can't reproduce this behavior with half-measure
caching. Can others?
@aerni I tested it locally (half-measure) and did nothing more than add 'half' to my static_caching settings. Did you do more than that?
I just tested on a fresh installation and can confirm that half-measure caching is also broken. Here's a repo that reproduces the issue: https://github.com/aerni/statamic-livewire-caching.
Just enable STATAMIC_STATIC_CACHING_STRATEGY=half
in your .env
and the counter won't work on subsequent loads.
Livewire 3 seems to work on the first load when I manually include the styles and scripts, but after that I get this old baby back:
This is resolved by adding Livewire as a CSRF exception in VerifyCsrfToken.php
:
protected $except = [
'/livewire*'
];
Which I remember at some point wasn't needed anymore because of a PR @aerni did to the Statamic Core.
Which I remember at some point wasn't needed anymore because of a PR @aerni did to the Statamic Core.
Not sure if the endpoint changed
It's this PR: https://github.com/statamic/cms/pull/7894. It looks like Livewire changed its CSRF implementation as window.livewire_token
doesn't return anything anymore. So Statamic can't replace the token anymore.
I played around with it some and found two solutions to the problem. Both solutions currently only work with half-measure static caching. I've created a Statamic PR that will also make it work with full-measure static caching.
Solution 1:
Force loading the scripts with \Livewire\Livewire::forceAssetInjection();
in a service provider.
Solution 2:
Adding the script to your layout with {{ livewire:scripts }}
or {{ livewire:scriptConfig }}
.
How it works: Livewire 3 is exposing the CSRF token as a data attribute on its script tag:
<script
src="/livewire/livewire.js?id=f41737f6"
data-csrf="lAUYD16rDgXflgLYME6SFYoPUJaEjqqUDZmLxQRP"
data-uri="/livewire/update"
data-navigate-once="true">
</script>
When Statamic caches the page, it replaces the CSRF token with a placeholder.
<script
src="/livewire/livewire.js?id=f41737f6"
data-csrf="STATAMIC_CSRF_TOKEN"
data-uri="/livewire/update"
data-navigate-once="true">
</script>
This placeholder is then replaced with the current CSRF token whenever the cached page is loaded.
If you are manually bundling Livewire and Alpine, the script will look a little different but the concept stays the same:
<script data-navigate-once="true">
window.livewireScriptConfig = {
"csrf": "STATAMIC_CSRF_TOKEN",
"uri":"\/livewire\/update",
"progressBar":true
};
</script>
I just tested on a fresh installation and can confirm that half-measure caching is also broken. Here's a repo that reproduces the issue: aerni/statamic-livewire-caching.
In this repo, you are relying on the auto-injection feature.
Scripts only get injected if a Livewire component was rendered on that request. On subsequent requests, we're returning cached html early - the component rendering logic doesn't happen. That's why it's not working for you.
You can solve this by using the {{ livewire:styles }}
&{{ livewire:scripts }}
tags.
Or, use Livewire:: forceAssetInjection()
but that still won't work with full-measure static caching, even with @aerni 's PR. (The page is written to html before livewire adds the injected assets, and we don't have a way to guarantee the middleware order)
Or, use Livewire:: forceAssetInjection() but that still won't work with full-measure static caching, even with @aerni 's PR. (The page is written to html before livewire adds the injected assets, and we don't have a way to guarantee the middleware order)
@jasonvarga Oh, you're right. I missed that the current Statamic Valet driver still hits PHP even for full-measure static caching. This is why the script was still added when using Livewire:: forceAssetInjection()
. Thanks for the Valet PR btw. I saw that it just got merged!
So, to sum up:
\Livewire\Livewire::forceAssetInjection()
works only for half-measure static caching.{{ livewire:styles }}
, {{ livewire:scripts }}
and {{ livewire:scriptConfig }}
tag works with both half- and full-measure static caching.Correct!
The only change that this package should make is probably to:
"statamic/cms": "^4.23.2"
)I released a new version:
https://github.com/jonassiewertsen/statamic-livewire/releases/tag/v3.0.0-beta.4
Statamic's static caching breaks Livewire. Components stop working when loading a cached page. This is true for both half and full-measure static caching. I tested it on a fresh Statamic installation with v3.0.0-beta.1 of this addon.
The issue can be reproduced with this sample Counter component. I tested with a
blade.php
andantlers.html
component view. It doesn't make a difference.I'm unsure if the problem is Livewire, this addon, or Statamic. I haven't had time to dig deeper.
Component class:
Component view
Statamic template