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

ignaaaam's avatar

Trying to render a {{ $slot }} on app.blade but getting undefined everytime

Hello I made a new project to test this because i'm having problems trying to render the blade/livewire components with the $slot on the app.blade.php

I have this app.blade.php in /resources/views/components/layouts

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

        <title>{{ $title ?? 'Page Title' }}</title>
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body>
        {{ $slot }}
    </body>
</html>

Made a simple Counter livewire component as the documentation says to see why it's not working on other projects where i'm having the same problem.

Livewire Counter component

<x-layouts.app>
<div>
    <h1>{{ $count }}</h1>
 
    <button wire:click="increment">+</button>
    
    <button wire:click="decrement">-</button>
</div>
</x-layouts.app>

Counter blade file

<?php
 
namespace App\Livewire;
 
use Livewire\Component;
 
class Counter extends Component
{
    public $count = 1;
 
    public function increment()
    {
        $this->count++;
    }
 
    public function decrement()
    {
        $this->count--;
    }
 
    public function render()
    {
        return view('livewire.counter');
    }
}

In my livewire config file I have the 'layout' => 'components.layouts.app'

I don't know why but still getting the error of Undefined variable $slot I dont know anything else to try or what could be causing the error...

0 likes
6 replies
shariff's avatar

@ignaaaam Is app.blade.php is inside components directory? If it is not then it will not work.

for example

if file is under components\layouts\app.blade.php you can call <x-layouts.app></x-layouts.app>.

If it is not you can create a component and return that view.

php artisan make:component App

In that App component which will be under App\View\Components You need to change render method which will return view

public function render(): View
    {
        return view('layouts.app');
    }
puklipo's avatar

No layout is required in Livewire components.

<div>
  <h1>{{ $count }}</h1>

  <button wire:click="increment">+</button>

  <button wire:click="decrement">-</button>
</div>

For full page components, Livewire will automatically load the layout and render the Livewire component in the $slot in that layout.

Route::get('counter', Counter::class);

For non-full page components, you need a regular blade to place the Livewire component.

<x-layouts.app>
    <livewire:counter />
</x-layouts.app>
Route::view('counter', 'counter');
Snapey's avatar
Snapey
Best Answer
Level 122

agree. You are rendering slot within slot. The default behavior is to load components/layouts/app if available

ignaaaam's avatar

@Snapey Tried this, I have the app.blade.php on resources/views/components/layouts. Shouldn't the render() method on App.php app/View/Components be components.layouts.app? Tried both with or without the components. and it's failing on both. Right now I only have the app.blade.php which has the $slot and then the counter.blade.php which is the livewire component that has no </x-layouts.app> wrapper anymore.

I have those 2 routes on my web.php

Route::get('/', function () {
    return view('components.layouts.app');
});

Route::get('/counter', Counter::class);`

If I go to /counter the livewire component works, but If I go to the / route still getting the Undefined variable $slot

I don't know if I'm doing anything wrong with Livewire or Laravel configuration since this is basic and never had any persisting problem like this with blade files or maybe I'm missing something.

Didn't have any problem using livewire Volt rendering components but started trying Livewire 3 without using Volt package on a project and made a fresh project with just this to see why I can't even render the $slot 🥲

ignaaaam's avatar

What I do not understand is that /counter loads all correctly with the Livewire component and the app.blade structure. But shouldn't my route / load also without any problem if /counter works? What is freaking me out it's finding the correct way to load the component I want on the $slot or how should I control what is passed in the $slot of the app. For example if I wanted a dashboard livewire component should I do it as the route below passing a Dashboard livewire component into the slot on the componenst.layouts.app view?

Managed to load the $slot correctly if I pass a slot in the / route like this:

Route::get('/', function () {
    return view('components.layouts.app')->with('slot', 'Welcome to Livewire');
});
ignaaaam's avatar

@Snapey Thanks managed to solve it. Didn't have the AppLayout on app\View\Components well set up, removed the on a new blade component, inside that blade component rendered the livewire:component. Also tweaked the routes to load the blade that has to be loaded instead of loading app directly.

Thanks a lot, in case anyone needs it watch the Pinkary project made with Livewire. Helped me to figure out what I was doing wrong.

Please or to participate in this conversation.