laravellaravel-livewirealpine.js

Livewire V3: Keep getting Uncaught TypeError: Alpine.navigate is not a function


I am trying to convert Laravel Breeze to use Livewire. After the registration is complete I am trying to redirect it to Dashboard but it is throwing the following error

livewire.js?id=11c49d7e:6889 Uncaught (in promise) TypeError: Alpine.navigate is not a function

I have checked the source and I can see Alpine is loaded properly but still getting this error.

My Code:

Layout: app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />

        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])
        @livewireStyles
    </head>

    <body class="font-sans antialiased @auth @else text-gray-900 @endauth">
        @auth
            <div class="min-h-screen bg-gray-100">
                @include('layouts.navigation')

                <!-- Page Heading -->
                @if (isset($header))
                    <header class="bg-white shadow">
                        <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                            {{ $header }}
                        </div>
                    </header>
                @endif

                <!-- Page Content -->
                <main>
                    {{ $slot }}
                </main>
            </div>
        @else
            <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
                <div>
                    <a href="/">
                        <x-application-logo class="w-20 h-20 fill-current text-gray-500" />
                    </a>
                </div>

                <div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg">
                    {{ $slot }}
                </div>
            </div>
        @endauth

        @livewireScripts
    </body>
</html>

Route: web.php

use App\Livewire\Auth\Register;
use App\Livewire\Dashboard;

Route::middleware('guest')->prefix('breeze')->name('breeze.')->group(function () {
    Route::get('register', Register::class)->name('register');
});

Route::get('/dashboard', Dashboard::class)->middleware(['auth', 'verified'])->name('dashboard');

Livewire Register Class: Register.php

<?php

namespace App\Livewire\Auth;

use App\Models\User;
use Livewire\Component;
use Livewire\Attributes\Rule;
use Livewire\Attributes\Layout;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\Events\Registered;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\ValidationException;

class Register extends Component
{
    #[Rule('required|string')]
    public ?string $name = '';

    #[Rule('required|string|email')]
    public ?string $email = '';

    #[Rule('required|string|same:confirmPassword')]
    public ?string $password = '';

    #[Rule('required|string')]
    public ?string $confirmPassword = '';

    public function submit()
    {
        $this->validate();

        // TODO: Ensure rate limited with custom validation

        $user = User::create([
            'name' => $this->name,
            'email' => $this->email,
            'password' => Hash::make($this->password),
        ]);

        event(new Registered($user));

        auth()->login($user);

        return $this->redirect(RouteServiceProvider::HOME, navigate: true);
    }

    #[Layout('layouts.app')]
    public function render()
    {
        return view('livewire.auth.register');
    }
}

Livewire Dashboard Class: Dashboard.php

<?php

namespace App\Livewire;

use Livewire\Attributes\Layout;
use Livewire\Component;

class Dashboard extends Component
{
    #[Layout('layouts.app')]
    public function render()
    {
        return view('livewire.dashboard');
    }
}

Solution

  • This issue comes down from using Breeze as it also comes with it's own Alpine installation.

    Fixing this issue is as simple as:

    1. Open resources/js/app.js
    2. Remove:
    import Alpine from 'alpinejs';
    
    window.Alpine = Alpine;
    
    Alpine.start();
    
    1. Build assets - npm run build

    This is a known issue where 2 alpine installations collide.