aerni / statamic-livewire-forms

Supercharge your Statamic forms with Livewire
https://statamic.com/addons/aerni/livewire-forms
Other
28 stars 2 forks source link

Static Cache + Livewire Forms Assets not loading #63

Closed jonathan-bird closed 3 months ago

jonathan-bird commented 3 months ago

I've been banging my head against a wall as to why the livewire-forms.js asset won't load when I have Static Cache enabled (Full). It causes a variety of errors when the form loads, all caused by the fact it's not including livewire-forms.js. Clearing the static cache works, or disabling it, but when it warms again, it just doesn't process the scripts within the @assets directive.

Am I doing something wrong? I have even tried including my forms around a @nocache tag but it didn't help, it's like it's ignoring processing the @assets blade directive when Static Cache is full, even when within nocache.

I have managed to get a workaround by bundling Livewire & your JS script manually and this works when Static caching is enabled.

My views are exactly as per the defaults:

<form
    x-data="form"
    x-effect="processForm"
    x-cloak
    wire:submit="submit"
>
    @formView("forms.{$this->type}")
</form>

@assets
    <script type="module" src="/vendor/livewire-forms/js/livewire-forms.js"></script>
@endassets

And my Livewire script is included as normal via @livewireScripts:

@vite(['resources/js/site.js'])

@stack('footer-scripts')

@livewireScripts
</body>
</html>

And including forms as normal:

<livewire:form :handle="$content->content_form->handle" />

Any help appreciated!

jonathan-bird commented 3 months ago

Same issue happens with the @assets directive processes when there's a captcha field set, so this doesn't load either:

@assets
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
@endassets
aerni commented 3 months ago

Yeah, so Livewire doesn't work out of the box with half nor full static caching. This issue is documented here: https://github.com/jonassiewertsen/statamic-livewire?tab=readme-ov-file#livewire-scripts-and-styles. I'll make a note in the docs of this addon too.

aerni commented 3 months ago

I've updated the docs: https://github.com/aerni/statamic-livewire-forms?tab=readme-ov-file#static-caching

jonathan-bird commented 3 months ago

Thanks @aerni I worked that part out today, was hoping for a nice solution as livewire scripts directive still fires normally on full static caching, it's just the Livewire assets directive that doesn't fire.

Assuming I have to manually include the ReCaptcha and asset files on the site too?

aerni commented 3 months ago

It's been a while since I've figured out the issue with static caching. I don't quite remember why things don't work as expected with full static caching. I wish there was a nicer solution too.

You only have to manually include the Livewire Forms scripts as per the docs. The rest should just work.

aerni commented 3 months ago

Hmm … actually, I might have gotten it wrong in the docs too. Running into some unexpected issues. I'll look into this.

aerni commented 3 months ago

Ok, so you're right. Somehow, the @assets directive isn't fired when static caching is enabled. However, the @script directive is fired. According to the Livewire docs, this is the directive that should be used when working with Alpine.data(), which is what the imported livewire-forms.js script is doing. So this directive seems more appropriate in this case. But I haven't figured out a way to make it work yet.

jonathan-bird commented 3 months ago

Interesting. I tried pushing in via the @stack / @push directive from the form, but it was injecting the script(s) twice so good thinking with the @script directive.

aerni commented 3 months ago

Alright, I have a better understanding of what's going on now. I developed a custom replacer to make Livewire compatible with Statamic's static caching. Waiting for the PR to get merged. You can check it out here: https://github.com/jonassiewertsen/statamic-livewire/pull/61.

jonathan-bird commented 3 months ago

Great solution to hook into Statamic's caching process to do that.

For some reason I didn't think a replacer/custom logic would be needed but I might read Statamics code on how they statically cache things, maybe it can be improved 🤔

aerni commented 3 months ago

The issue is that the @assets blade directive only gets hit on the first request. Once the response is cached, it won't hit the directive again. So we got to push the assets to the head before the response is cached.

And the replacer also solves the issue of automatic injection of the Livewire assets, which wasn't possible before.

aerni commented 3 months ago

The PR has been merged. Update your composer dependencies and you should be good to go!