Search code examples
javascriptlaravellaravel-livewirealpine.jspersist

TypeError: Cannot redefine property: $persist in Laravel 11 with Livewire 3 and AlpineJs 3


I'm working on a project using Laravel 11, Livewire 3, and AlpineJs 3. I'm trying to use the @alpinejs/persist plugin to manage a dark mode toggle. However, I keep encountering the following error:

livewire.esm.js:4999 
 Uncaught 
TypeError: Cannot redefine property: $persist
    at Function.defineProperty (<anonymous>)
    at src_default (livewire.esm.js:4999:14)
    at livewire.esm.js:2766:32
    at Array.forEach (<anonymous>)
    at Object.plugin (livewire.esm.js:2766:17)
    at Object.start (livewire.esm.js:9448:28)
    at app.js:20:10

enter image description here

Here is my setup:

app.js:

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
import persist from '@alpinejs/persist';

window.Alpine = Alpine;

console.log('Alpine.$persist adding it');
Alpine.plugin(persist);

/* Stores */
Alpine.store('darkMode', {
  on: Alpine.$persist(true).as('darkMode_on'),
  toggle() {
    this.on = !this.on;
  },
});

Livewire.start();

layouts/app.blade.php:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" x-data :class="$store.darkMode.on && 'dark'">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="{{ asset('/css/bootstrap-icons.min.css') }}">
    @livewireStyles
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="">
<main class="container mx-auto my-3">
    {{ $slot }}
</main>
@livewireScriptConfig
</body>
</html>

I expected the @alpinejs/persist plugin to work without errors, allowing me to toggle dark mode using Alpine.js stores. However, the error TypeError: Cannot redefine property: $persist suggests that the persist plugin is being loaded or defined more than once.

Here are the steps I've taken to troubleshoot:

  1. Verified that @alpinejs/persist is only imported and registered once in app.js.

  2. Cleared the browser cache and tried in incognito mode.

  3. Ensured that the versions of Alpine.js and @alpinejs/persist are compatible.

Despite these steps, the error persists. I'm not sure why this is happening or how to resolve it.


Solution

  • Livewire 3 already includes some common AlpineJs plugins and persist is one of them.

    So you can remove all the imports and you don't need to manually start Livewire, you can leave only the darkMode initialization in the store

    document.addEventListener('alpine:init', () => {
    
        Alpine.store('darkMode', {
    
            on: Alpine.$persist(true).as('darkMode_on'),
    
            toggle() {
                this.on = !this.on;
            },
        });
    });
    

    Then in your app.blade.php you must replace @livewireScriptConfig with @livewireScripts

    Here there are informations about the plugins already included