Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

StarShines's avatar

Livewire Full Page Component

Hello,

I am using livewire 3 and trying to achieve a SPA-like behavior for rendering different views, which are all in different livewire blade components with the new wire:navigate feature. But its not working. Below is my setup:

  1. I am using layout.app as below.
  2. I am using {{ $slot }} in app.blade.php
  3. I am using livewire components routes as below.

Code Snippets: layout.app:

<!DOCTYPE html>

<html lang="en">

<head>

    <!-- Basic Page Needs
 ================================================== -->
    <meta charset="utf-8">
    <title>Educenter - Education HTML Template</title>

    <!-- Mobile Specific Metas
 ================================================== -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="Construction Html5 Template">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
  

    <!-- theme meta -->
    <meta name="theme-name" content="edu" />

    <!-- ** Plugins Needed for the Project ** -->
    <!-- Bootstrap -->
    <link rel="stylesheet" href="{{ asset('plugins/bootstrap/bootstrap.min.css') }}">
    <!-- slick slider -->
    <link rel="stylesheet" href="{{ asset('plugins/slick/slick.css') }}">
    <!-- themefy-icon -->
    <link rel="stylesheet" href="{{ asset('plugins/themify-icons/themify-icons.css') }}">
    <!-- animation css -->
    <link rel="stylesheet" href="{{ asset('plugins/animate/animate.css') }}">
    <!-- aos -->
    <link rel="stylesheet" href="{{ asset('plugins/aos/aos.css') }}">
    <!-- venobox popup -->
    <link rel="stylesheet" href="{{ asset('plugins/venobox/venobox.css') }}">

    <!-- Main Stylesheet -->
    <link href="{{ asset('css/style.css') }}" rel="stylesheet">

    <!--Favicon-->
    <link rel="shortcut icon" href="{{ asset('images/favicon.png') }}" type="image/x-icon">
    <link rel="icon" href="{{ asset('images/favicon.png') }}" type="image/x-icon">

   
</head>

<body>

    <livewire:header />

    {{ $slot }}
    
    <livewire:footer />

    <!-- jQuery -->
    <script src="{{ asset('plugins/jQuery/jquery.min.js') }}"></script>
    <!-- Bootstrap JS -->
    <script src="{{ asset('plugins/bootstrap/bootstrap.min.js') }}"></script>
    <!-- slick slider -->
    <script src="{{ asset('plugins/slick/slick.min.js') }}"></script>
    <!-- aos -->
    <script src="{{ asset('plugins/aos/aos.js') }}"></script>
    <!-- venobox popup -->
    <script src="{{ asset('plugins/venobox/venobox.min.js') }}"></script>
    <!-- filter -->
    <script src="{{ asset('plugins/filterizr/jquery.filterizr.min.js') }}"></script>
    <!-- google map -->
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCcABaamniA6OL5YvYSpB3pFMNrXwXnLwU"></script>
    <script src="{{ asset('plugins/google-map/gmap.js') }}"></script>

    <!-- Main Script -->

    <script src="{{ asset('js/script.js') }}"></script>
    

</body>

</html>

Routes:

// Livewire Component Routes
Route::get('/', Home::class)->name('home');
Route::get('/about', About::class)->name('about');

So my header and footer are fixed, only the slot should update as I navigate to different links.

Also when I use wire:navigate, I get a blank page saying "2023"

<a class="dropdown-item" href="{{ route('about') }}" wire:navigate>About</a> // Not Working

How this approach will work, Thanks for your help

0 likes
4 replies
Shaz3e's avatar

I have injected the @livewireStyles and @livewireScripts I am also getting only copyright year nothing else when I see console it shows 2024

this is my app.blade.php which is placed inside resource/views/components/layouts/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>{{ $title ?? config('app.name') }} | {{ config('app.name') }}</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" />

    <!-- App favicon -->
    <link rel="shortcut icon" href="{{ asset('assets/images/favicon.ico') }}">

    <!-- Bootstrap Css -->
    <link href="{{ asset('assets/css/bootstrap.min.css') }}" id="bootstrap-style" rel="stylesheet" type="text/css" />
    <!-- Icons Css -->
    <link href="{{ asset('assets/css/icons.min.css') }}" rel="stylesheet" type="text/css" />

    @stack('styles')

    <!-- App Css-->
    <link href="{{ asset('assets/css/app.min.css') }}" id="app-style" rel="stylesheet" type="text/css" />

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

<body data-topbar="light">

    <!-- <body data-layout="horizontal" data-topbar="dark"> -->

    <!-- Begin page -->
    <div id="layout-wrapper">

        <!-- Check if the user is logged in as an admin -->
        @if (auth()->guard('admin')->check())
            <x-admin-header />
            <x-admin-sidebar />
            <!-- Check if the user is logged in as a regular user -->
        @elseif (auth()->check())
            <x-user-header />
            <x-user-sidebar />
        @endif

        <!-- ============================================================== -->
        <!-- Start right Content here -->
        <!-- ============================================================== -->
        <div class="main-content">

            <div class="page-content">
                <div class="container-fluid">

                    {{ $slot }}

                </div> <!-- container-fluid -->
            </div>
            <!-- End Page-content -->

            <footer class="footer">
                <div class="container-fluid">
                    <div class="row">
                        <div class="col-sm-6">
                            <script>
                                document.write(new Date().getFullYear())
                            </script> © BrandName.
                        </div>
                        <div class="col-sm-6">
                            <div class="text-sm-end d-none d-sm-block">
                                Crafted with <i class="mdi mdi-heart text-danger"></i> by BrandName
                            </div>
                        </div>
                    </div>
                </div>
            </footer>

        </div>
        <!-- end main content-->

    </div>
    <!-- END layout-wrapper -->

    <x-rightsidebar />

    <!-- JAVASCRIPT -->
    <script src="{{ asset('assets/libs/jquery/jquery.min.js') }}"></script>
    <script src="{{ asset('assets/libs/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
    <script src="{{ asset('assets/libs/metismenu/metisMenu.min.js') }}"></script>
    <script src="{{ asset('assets/libs/simplebar/simplebar.min.js') }}"></script>
    <script src="{{ asset('assets/libs/node-waves/waves.min.js') }}"></script>

    @stack('scripts')

    <x-appjs />

    @livewireScripts

</body>

</html>

and my dashboard component placed inside app/Livewire/Admin/Dashboard.php

<?php

namespace App\Livewire\Admin;

use Livewire\Component;

class Dashboard extends Component
{
    public function render()
    {
        return view('livewire.admin.dashboard');
    }
}

and my web.php has 2 files one for regular user one for admin

<?php

require __DIR__.'/admin.php';
require __DIR__.'/user.php';

and my admin.php looks like this which is placed as same folder as web.php means at route/admin.php

<?php

use Illuminate\Support\Facades\Route;

use App\Livewire\Admin\Auth\Register;
use App\Livewire\Admin\Auth\Login;
use App\Livewire\Admin\Auth\ForgotPassword;
use App\Livewire\Admin\Auth\ResetPassword;
use App\Livewire\Admin\Auth\Logout;
use App\Livewire\Admin\Dashboard;
use App\Livewire\Admin\User\UserList;

// if route is /admin redirect to admin/dashboard

Route::prefix('admin')->name('admin.')->group(function () {
    Route::middleware('guest:admin')->group(function () {

        // Register
        Route::get('register', Register::class)->name('register');

        // Login
        Route::get('login', Login::class)->name('login');

        // Forgot Password
        Route::get('forgot-password', ForgotPassword::class)->name('forgot.password');

        // Reset Password
        Route::get('reset/{email}/{token}', ResetPassword::class)->name('password.reset');
    });

    Route::middleware('auth:admin')->group(function () {

        // Logout
        Route::get('logout', Logout::class)->name('logout');

        // Dashboard
        Route::get('/dashboard', Dashboard::class)->name('dashboard');
        
        // Users
        Route::get('/users', UserList::class)->name('users');
    });
});

when I use href with wire:navigate it load only body as mentioned above

<body cz-shortcut-listen="true">2024</body>

I have to manually refresh the page to load everything any help in this would be much much appreciated

Please or to participate in this conversation.