Ahmed Alaa's avatar

How to render components with controller

I need to create a component for Navbar to grab the nav bar links and buttons from the database I created a component using

php artisan make:component Front/General/lowerHeader

then I edited the component's controller like so

<?php

namespace App\View\Components\Front\General;

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

class lowerHeader extends Component
{
    public $nav_links;
    
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->nav_links = NavLink::get();
    }
    
    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.front.general.lower-header');
    }
}

and rendered it using the following code

    <x-front.general.lower-header/>

I used foreach to loop over $nav_links in the view part of the component

I got this error

Undefined variable $nav_links
0 likes
15 replies
LaryAI's avatar
Level 58

It looks like you are missing the $nav_links variable in your view. You need to pass the $nav_links variable to the view when you render the component. You can do this by adding the following line to your render() method in the component's controller:

return view('components.front.general.lower-header', ['nav_links' => $this->nav_links]);

This will pass the $nav_links variable to the view, which you can then use in your foreach loop.

tykus's avatar

What does the view template for the component look like?

1 like
Ahmed Alaa's avatar

@tykus

<div class="bg-white border-top border-gray-200 py-1 scrollbar scrollbar-hidden-x">
    <div class="container">
        <ul class="flex flex-nowrap justify-between lg:justify-center items-center gap-2 text-center">
            @foreach ($nav_links as $nav_link)
                <li class="min-w-max">
                    <a href="{{ route('front.homepage') }}"
                        class="opacity-60 text-xs md:text-sm font-bold px-3 py-2 inline-block fw-600 hover:opacity-100 hover:text-gray-900 text-reset">
                        {{ __('front/homePage.Home') }}
                    </a>
                </li>
            @endforeach

        </ul>
    </div>
</div>
tykus's avatar

@Ahmed Alaa all public components on the Component class should be available to the component's view. Are you using this Blade template elsewhere, i.e. not using <x-front.general.lower-header/>?

1 like
Ahmed Alaa's avatar

@tykus I noticed that it rendered without running the controller because when I used dd in the render method and __construct , it didn't work

rodrigo.pedra's avatar
Level 56

Rename your class to Pascal Case, i. e rename it to LowerHeader starting with a capital L.

Otherwise, Laravel won't find the class when parsing the template, and will assume it is an anonymous component.

Before testing, be sure to clean your views. You can do this by running:

php artisan view:clear

Or by removing any files, except for the .gitignore one, from your project's ./storage/framework/views/ directory.

3 likes
rodrigo.pedra's avatar

Don't forget to rename both the class (inside the PHP file), and the file.

Both need to match their names.

Both need to be in Pascal Case.

rodrigo.pedra's avatar

@tykus thanks!

I've seen this before on a project, not mine, a friend asked for help. It took some time to find it out, so the pain makes you gain. At least some knowledge in this case =)

1 like
onyashed's avatar

Guys where is the Controller logic... invoked by the route to the component view

onyashed's avatar

I have been off laravel for some time. I am seeing this in 2025.

Please or to participate in this conversation.