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

PatrickDaniel's avatar

Passing a model to Breeze navigation component

I'm trying to create dynamic links within the navigation component that comes with Breeze. Here is what I am trying to do in views/layouts/navigation.blade.php:

<!-- Navigation Links -->
                <div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
                    <x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
                        {{ __('Dashboard') }}
                    </x-nav-link>
                    <x-nav-link :href="route('decks.index', [$user->id])" :active="request()->routeIs(['decks.index', 'decks.store'])">
                        {{ __('Decks') }}
                    </x-nav-link>
                    <x-nav-link :href="route('decks.create', [$user->id])" :active="request()->routeIs('decks.create')">
                        {{ __('Add Decks') }}
                    </x-nav-link>
                </div>

The key part is that I am struggling with is this : :href="route('decks.index', [$user->id])"

I'm getting an error that says undefined variable user. I am aware that I could change [$user->id] to [Auth::user()->id], but I am trying to add nav-link components for Flashcards that belong to a specific Deck, and so I will run into the same issue then.

How can I get something similar to Route Model binding with View Components? I start at views/flashcards/index.blade.php:

<x-app-layout
    {{-- :user="$user" --}}
>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ ucwords($deck->topic) . ' Flashcard Deck' }}
        </h2>
    </x-slot>

    <div class="py-12 mx-auto max-w-7xl sm:px-6 lg:px-8">
        <div class="grid grid-cols-5 gap-4">
            @forelse($deck->flashcards as $flashcard)
                <a href="#">
                    <div class="rounded border-2 bg-white border-gray-600 h-64 flex items-end">
                        <p class="mx-auto font-sans pb-2">{{ $flashcard->term }}</p>
                    </div>
                </a>
            @empty
                <p>No flashcards created for this deck yet.</p>
            @endforelse
        </div>
    </div>
</x-app-layout>

Which has the <x-app-layout/> component. This then calls app/View/Components/AppLayout.php:

<?php

namespace App\View\Components;

use App\Models\User;
use Illuminate\View\Component;

class AppLayout extends Component
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the view / contents that represents the component.
     *
     * @return \Illuminate\View\View
     */
    public function render()
    {
        // dd($this->user);
        return view('layouts.app');
    }
}

Which is where I try to pass the user, and I think is where I am making an error. This renders the views/layouts/app.blade.php component:

<!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.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">

        <!-- Styles -->
        <link rel="stylesheet" href="{{ asset('css/app.css') }}">

        <!-- Scripts -->
        <script src="{{ asset('js/app.js') }}" defer></script>
    </head>
    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">
            {{-- @include('layouts.navigation') --}}
            {{-- {{ dd($user) }} --}}
            @include('layouts.navigation', ['user' => Auth::user()])

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

            <!-- Page Content -->
            <main>
                {{ $slot }}
            </main>
        </div>
    </body>
</html>

Which loops back to the navigation layout view at the top of the post and is where I add the user with Auth::user(). To reiterate, this works fine but I have another resource that isn't going to be accessible with this method. In my app, a user has many decks but I want the specific one, so that I can take its id and use it to make the nav bar routes dynamic i.e. /users/{user}/decks/{deck}/flashcards.

I've reread over the view and blade template sections of the docs, but I can't quite figure out what direction to go from here. Any help or corrections appreciated.

0 likes
2 replies
PatrickDaniel's avatar

Just to add a bit more detail, my ideal navigation.blade.php file would have something like this:

<!-- Navigation Links -->
                <div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
                    <x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
                        {{ __('Dashboard') }}
                    </x-nav-link>
                    <x-nav-link :href="route('decks.index', [$user->id])" :active="request()->routeIs(['decks.index', 'decks.store'])">
                        {{ __('Decks') }}
                    </x-nav-link>
                    <x-nav-link :href="route('decks.create', [$user->id])" :active="request()->routeIs('decks.create')">
                        {{ __('Add Decks') }}
                    </x-nav-link>
                    @if (Route::is('flashcards.*'))
                        <x-nav-link :href="route('flashcards.index', [$user->id, $deck->id])" :active="request()->routeIs('flashcards.index')">
                            {{ __('Flashcards') }}
                        </x-nav-link>
                    @endif
                </div>
PatrickDaniel's avatar
PatrickDaniel
OP
Best Answer
Level 16

Fixed it for anyone stuck on the same issue. The key problem I was running into is that route model binding does not extend to blade components. First, I utilized route-model binding. Key web.php snippet:

Route::get('/users/{user}/decks', [DeckController::class, 'index'])->name('decks.index');

From here we go to the DeckController. Key method:

public function index(User $user)
    {
        return view('decks.index', ['user' => $user]);
    }

In the resources/views/decks/index.blade.php file, I had to find a way to pass the $user variable into the class based component that came with Breeze. Without route model binding this step does not work, as "request()->route('user')" would just return the value of the user id that is in the route rather than the whole model.

<x-app-layout
    :user="request()->route('user')"
>
    // More code here
</x-app-layout>

In my component I had it accept the user variable from above in its constructor. This makes it available in the view that it renders.

class AppLayout extends Component
{
    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the view / contents that represents the component.
     *
     * @return \Illuminate\View\View
     */
    public function render()
    {
        return view('layouts.app');
    }
}

Now my user model was available in my resources/views/layouts/app.blade.php file, which makes it available to pass into the layouts/navigation.blade.php. Key code from layouts/app.blade.php:

<!DOCTYPE html>
	// Some code
	@include('layouts.navigation', ['user' => $user])
	// More code
</html>

And finally I could use my user model in the resources/views/layouts/navigation.blade.php file:

// Some code
<x-nav-link 
	:href="route('decks.index', [$user->id])" 
	:active="request()->routeIs(['decks.index', 'decks.store'])">
    {{ __('Decks') }}
</x-nav-link>
// More code

I know you can use the auth helper in place of most of this, but for other models that you utilize route model binding for that's not the case, and for me this was really a proof of concept for that scenario.

Please or to participate in this conversation.