skip to Main Content

I’ve been following the Livewire docs and screencasts to build my new app, but I could be doing something wrong because the <head> tag is been included twice.

Here is my code:

routesweb.php

<?php

use IlluminateSupportFacadesRoute;
use AppHttpLivewireUserAll as UserAll;

Route::get('/', function () {
    return view('welcome');
});

Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified'
])->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard');
    })->name('dashboard');

    // Users
    Route::prefix('users')->group(function () {
        Route::get('/', UserAll::class)->name('users-all');
    });
});

AppHttpLivewireUserAll.php

<?php

namespace AppHttpLivewireUser;

use LivewireWithPagination;
use AppModelsUser;
use LivewireComponent;

class All extends Component
{
    use WithPagination;

    public $search = '';

    public function render()
    {
        return view('livewire.user.all', [
            'users' => User::search('name', $this->search)->paginate(10)
        ]);
    }
}

AppViewComponentsUserLayout.php

<?php

namespace AppViewComponents;

use IlluminateViewComponent;

class UserLayout extends Component
{

    /**
     * Get the view / contents that represent the component.
     *
     * @return IlluminateContractsViewView|Closure|string
     */
    public function render()
    {
        return view('layouts.user');
    }
}

resourseviewslayoutsuser.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="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">

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

        <!-- Styles -->
        @livewireStyles
    </head>
    <body class="font-sans antialiased dashboard">
        <x-jet-banner />

        <div class="min-h-screen bg-gray-100">
            @livewire('navigation-menu')

            <!-- 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>

        @stack('modals')

        @livewireScripts
    </body>
</html>

resourseviewslivewireuserall.blade.php

<x-user-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Users') }}
        </h2>
        <input wire:model="search" type="text">
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-xl sm:rounded-lg">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 bg-white border-b border-gray-200">
                        <table>
                            <thead>
                                <tr>
                                    <th>{{ __('ID') }}</th>
                                    <th>{{ __('Name') }}</th>
                                    <th>{{ __('Email') }}</th>
                                    <th>{{ __('Date') }}</th>
                                </tr>
                            </thead>
                            <tbody>
                            @foreach ($users as $user)
                                <tr>
                                    <td>{{ $user->id }}</td>
                                    <td>{{ $user->name }}</td>
                                    <td>{{ $user->email }}</td>
                                    <td>{{ $user->created_at->format('M, d Y') }}</td>
                                </tr>
                            @endforeach
                            </tbody>
                        </table>

                        <div class="my-7">
                            {{ $users->links() }}
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</x-user-layout>

If I remove the <x-user-layout> tag in the blade, the problem seems to be fixed, but then livewire doesn’t work.

I’ve tried many solutions, but nothig works. What am I doing wrong here?

Thanks a lot in advance.

2

Answers


  1. try this in

    AppHttpLivewireUserAll.php add layout

     public function render()
        {
            return view('livewire.user.all', [
                'users' => User::search('name', $this->search)->paginate(10)
            ])->layout('layouts.user');
        }
    
    Login or Signup to reply.
  2. I will add an answer just to clearify things

    AppHttpLivewireUserAll.php

    <?php
    
    namespace AppHttpLivewireUser;
    
    use LivewireWithPagination;
    use AppModelsUser;
    use LivewireComponent;
    
    class All extends Component
    {
        use WithPagination;
    
        public $search = '';
    
    
    /**
     * We add extends() and section()
     * In ->section(), I added layouts.user assuming that is the layout that all.blade.php will extend of (if it's not, change it)
    */
    
    function render() {
        return view('livewire.user.all', ['users' => User::search('name',$this->search)->paginate(10)])->extends("layouts.user")->section('content');
    }
    }
    

    resourseviewslivewireuserall.blade.php

    I changed <x-user-layout> and <x-slot> with a <div> and as i said in my early comments, you need to wrapp all the content in a <div> to make it work. If you want to use headers apart, instead of using <x-slot> use @include("") (personal recomendation).

    I will add a link if you want to learn more about the blade directives:
    https://laravel.com/docs/9.x/blade#blade-directives

    <div> 
        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-xl sm:rounded-lg">
                    <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                        <div class="p-6 bg-white border-b border-gray-200">
                            <table>
                                <thead>
                                    <tr>
                                        <th>{{ __('ID') }}</th>
                                        <th>{{ __('Name') }}</th>
                                        <th>{{ __('Email') }}</th>
                                        <th>{{ __('Date') }}</th>
                                    </tr>
                                </thead>
                                <tbody>
                                @foreach ($users as $user)
                                    <tr>
                                        <td>{{ $user->id }}</td>
                                        <td>{{ $user->name }}</td>
                                        <td>{{ $user->email }}</td>
                                        <td>{{ $user->created_at->format('M, d Y') }}</td>
                                    </tr>
                                @endforeach
                                </tbody>
                            </table>
    
                            <div class="my-7">
                                {{ $users->links() }}
                            </div>
    
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    resourseviewslayoutsuser.blade.php

    In your livewire component All.php, there is specified now the section that has to be used ->section("content"),the only thing remaining is to use @yield instead of {{ $slot }}

    <!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="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">
    
            <!-- Scripts -->
            @vite(['resources/css/app.css', 'resources/js/app.js'])
    
            <!-- Styles -->
            @livewireStyles
        </head>
        <body class="font-sans antialiased dashboard">
            <x-jet-banner />
    
            <div class="min-h-screen bg-gray-100">
                {{-- @livewire('navigation-menu') --}}
    
                <main>
                    @yield('content') 
                </main>
            </div>
    
            {{-- @stack('modals') --}}
    
    
            @livewireScripts
        </body>
    </html>
    

    routesweb.php

    I noticed, that you don’t call the class All, that is the responsible of rendering the view, you calling UserAll:: class, however I don’t really know the functionality of this class, so instead try adding this route, to test

    Route::get('/all', All::class)->name('users_all_test');
    

    Try it, and let me know how it went.

    You can use the livewire documentation too:
    https://laravel-livewire.com/docs/2.x/rendering-components

    there you can find explanations of ->extends(), and ->section()

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search