statamic-livewire icon indicating copy to clipboard operation
statamic-livewire copied to clipboard

Multiple versions of livewire/livewire.js

Open mojosef opened this issue 1 year ago • 15 comments

I've got a strange issue when using full cacheing strategy in production.

If I clear the static cache, the page loads fine ( as there is not cached file to load yet ). However the generated html has 2 instances of livewire.js inserted. This causes issues with livewire and alpine, and gives me the following errors:

index.js:26 Detected multiple instances of Livewire running ni @ index.js:26 (anonymous) @ index.js:28 (anonymous) @ index.js:53 index.js:26 Detected multiple instances of Alpine running ni @ index.js:26 (anonymous) @ index.js:29 (anonymous) @ index.js:53 component.js:8 Uncaught Component already initialized

Here is the code generated at the bottom of the static html files

<script src="/livewire/livewire.min.js?id=923613aa"   data-csrf="STATAMIC_CSRF_TOKEN" data-update-uri="/livewire/update" data-navigate-once="true"></script>
<script src="/livewire/livewire.min.js?id=923613aa"   data-csrf="STATAMIC_CSRF_TOKEN" data-update-uri="/livewire/update" data-navigate-once="true"></script>
<script type="text/javascript">(function() {
    var els = document.getElementsByClassName('nocache');
    var map = {};
    for (var i = 0; i < els.length; i++) {
        var section = els[i].getAttribute('data-nocache');
        map[section] = els[i];
    }

    fetch('/!/nocache', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            url: window.location.href.split('#')[0],
            sections: Object.keys(map)
        })
    })
    .then((response) => response.json())
    .then((data) => {
        const regions = data.regions;
        for (var key in regions) {
            if (map[key]) map[key].outerHTML = regions[key];
        }

        for (const input of document.querySelectorAll('input[value="STATAMIC_CSRF_TOKEN"]')) {
            input.value = data.csrf;
        }

        for (const meta of document.querySelectorAll('meta[content="STATAMIC_CSRF_TOKEN"]')) {
            meta.content = data.csrf;
        }

        for (const input of document.querySelectorAll('script[data-csrf="STATAMIC_CSRF_TOKEN"]')) {
            input.setAttribute('data-csrf', data.csrf);
        }

        if (window.hasOwnProperty('livewire_token')) {
            window.livewire_token = data.csrf
        }

        if (window.hasOwnProperty('livewireScriptConfig')) {
            window.livewireScriptConfig.csrf = data.csrf
        }

        document.dispatchEvent(new CustomEvent('statamic:nocache.replaced', { detail: data }));
    });
})();</script></body>
</html>

My current config:

Environment Application Name: ** Laravel Version: 10.48.22 PHP Version: 8.2.5 Composer Version: 2.7.9 Environment: production Debug Mode: OFF URL: ** Maintenance Mode: OFF

Cache Config: CACHED Events: NOT CACHED Routes: CACHED Views: CACHED

Drivers Broadcasting: log Cache: file Database: mysql Logs: stack / single Mail: mailgun Queue: sync Session: file

Livewire Livewire: v3.5.8

Statamic Addons: 3 Sites: 1 Stache Watcher: Disabled Static Caching: full Version: 5.26.0 PRO

Statamic Addons jonassiewertsen/statamic-livewire: 3.8.0 spatie/statamic-responsive-images: 5.0.1 withcandour/aardvark-seo: 5.0.0

Any help would be appreciated.

mojosef avatar Sep 26 '24 20:09 mojosef

There was a bugfix a few hours ago in Statamic core (https://github.com/statamic/cms/pull/10306). Can you upgrade and see if it's already fixed?

marcorieser avatar Sep 27 '24 04:09 marcorieser

Thanks for reporting. Please reply here if the issue still exists, so we can reopen if it does.

jonassiewertsen avatar Oct 01 '24 13:10 jonassiewertsen

Sorry for the delay in reporting back. All updated to latest and for me at least, the issue remains. I can see the replacers in the head now but still getting duplicate livewire assets.

Livewire Livewire: v3.5.9

Statamic Addons: 3 Sites: 1 Stache Watcher: Disabled Static Caching: full Version: 5.29.0 PRO

Statamic Addons jonassiewertsen/statamic-livewire: 3.8.1 spatie/statamic-responsive-images: 5.0.1 withcandour/aardvark-seo: 5.0.0

mojosef avatar Oct 02 '24 08:10 mojosef

Are you using a {{ nocache }} tag?

afonic avatar Nov 03 '24 09:11 afonic

No, I'm not using the nocache tag

mojosef avatar Nov 08 '24 20:11 mojosef

Hello I get the same Error Message if I am implementing a Livewire Komponent within the Antlers with half measured Static Cache

HannesEURESA avatar Nov 27 '24 06:11 HannesEURESA

@mojosef @HannesEURESA do you have a simple repo for sharing that lets me reproduce the issue?

marcorieser avatar Nov 27 '24 07:11 marcorieser

I can´t share a repo, unfortunately,

We got activated static half caching, since then all Pages where we include Livewirecomponents inside Antlers are throwing the error in the console. So this brings problems to all Alpine and Livewire instances on all compoennts which are reachable from this current URL.

Example:

The Main Navigation is used with Alpine, so now the Menu isn´t working anymore and notDropdown is available.

I tried with {{nocache}} to wrap the whole Livewirecomponent, but it´s not working, and if I am wrapping not only the component, but also Inside the component the Elements, it shows me on the frontend that No Cache Placeholder is set.

We can´t take the whole Page to exclude from Stataic Caching, because it´s mainly crashing on our main Sites, where the Static caching need to be set of half.

I hope I could help

HannesEURESA avatar Nov 27 '24 07:11 HannesEURESA

@marcorieser I have a private repo I'm happy to add you to if it helps.

mojosef avatar Nov 28 '24 08:11 mojosef

Can someone try the following:

Publish the Livewire config:

php artisan livewire:publish --config

In the config disable assets injection:

'inject_assets' => false,

and then manually add the tags in your layout file by using {{ livewire:scripts }} and {{ livewire:styles }}.

If your component passes parameters using the tag, for example {{ livewire:something param="foo" otherparam="bar" }}, try enclosing it in {{ nocache }} tags.

afonic avatar Nov 28 '24 08:11 afonic

@mojosef

Yes, that would be a huge help.

marcorieser avatar Nov 28 '24 08:11 marcorieser

@afonic Is that different from doing it like in the docs? https://github.com/jonassiewertsen/statamic-livewire?tab=readme-ov-file#manually-including-livewires-frontend-assets

marcorieser avatar Nov 28 '24 08:11 marcorieser

@marcorieser No, the key is disabling auto injection in Livewire's config. That how I solved this issue when using half measure caching and Livewire Filters: https://livewirefilters.com/docs/v1/common-issues#content-the-add-on-doesnt-work-correctly-when-using-static-caching

My guess is that the cached version of the page contains the assets but the component loads and tries to inject them again. If you have parameters in the component itself, they get saved in the cache because of Livewire's snapshot and then it ignores changing set parameters on boot.

I'd be happy to help debug this, but I hit a dead end last time I tried.

afonic avatar Nov 28 '24 08:11 afonic

I always include the styles and scripts on every page with the link above or bundle it myself and disable it via {{ livewire:scriptConfig }}. That's probably why I never had any issue with caching. But I will know more once I get access to some repos.

marcorieser avatar Nov 28 '24 08:11 marcorieser

Thanks @afonic that did the trick, I was about to share the repo, but after trying this, and deploying to the production, everything is working again.

HannesEURESA avatar Nov 28 '24 09:11 HannesEURESA