How to fix "Undefined variable" error in Laravel?
When rendering a Laravel Blade view, I get the following error:
ErrorException: Undefined variable: name (View: /resources/views/welcome.blade.php)
or
Undefined variable: user (View: /resources/views/dashboard.blade.php)
Solution
This can happen when a variable used in the Blade template has not been properly passed from the controller. Try the following:
1. Ensure the Variable is Passed from Controller
Check that the variable is included when returning the view:
return view('welcome', ['name' => $name]);
If using compact()
:
return view('welcome', compact('name'));
2. Use @isset or @empty in Blade Templates
If the variable might be missing, use Blade directives to prevent errors:
@isset($name)
<p>Hello, {{ $name }}</p>
@endisset
Or:
@empty($name)
<p>No name provided.</p>
@endempty
3. Check Route Controller for Missing Data
Ensure the controller function responsible for rendering the view is correctly passing the expected variables.
4. Check Middleware and Session Variables
If you're using session data, ensure the variable is set before accessing it:
session(['user' => 'John Doe']);
Then retrieve it in Blade:
{{ session('user') }}
To debug session values, use:
dd(session()->all());
5. Use Default Values in Blade Templates
To prevent errors, assign a default value:
<p>Hello, {{ $name ?? 'Guest' }}</p>
This ensures that even if $name
is undefined, the template will not break.
By following these steps, you should be able to resolve the "Undefined variable" error in Laravel.
Alternative #1
I've found that this error often occurs when using view composers or view creators incorrectly. Make sure your view composers are properly registered and the variables are being passed correctly.
// In a service provider
public function boot()
{
View::composer('welcome', function ($view) {
$view->with('name', 'John Doe');
$view->with('user', auth()->user());
});
}
Or using a dedicated composer class:
class WelcomeComposer
{
public function compose(View $view)
{
$view->with('name', 'John Doe');
$view->with('user', auth()->user());
}
}
// Register in service provider
View::composer('welcome', WelcomeComposer::class);
This approach ensures variables are always available to specific views, regardless of which controller renders them.
Alternative #2
Another common cause is middleware that modifies the request or session data. Check if you have middleware that might be clearing or modifying variables before they reach your controller.
You can debug this by adding logging in your middleware:
// In your middleware
public function handle($request, Closure $next)
{
\Log::info('Session data before middleware:', session()->all());
$response = $next($request);
\Log::info('Session data after middleware:', session()->all());
return $response;
}
Also, check if you're using route model binding correctly:
// In your routes file
Route::get('/user/{user}', function (User $user) {
return view('profile', compact('user'));
});
Make sure the model binding is working and the variable name matches what you're using in the Blade template.
Alternative #3
If you're using API resources or form requests, make sure the data is being passed correctly through the validation pipeline.
// In your form request
class UpdateProfileRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:255',
];
}
// Make sure to pass the validated data to the view
public function validated($key = null, $default = null)
{
return parent::validated($key, $default);
}
}
// In your controller
public function update(UpdateProfileRequest $request)
{
$validated = $request->validated();
return view('profile', [
'name' => $validated['name'],
'user' => auth()->user()
]);
}
You can also use view data to debug what's being passed:
// In your controller, before returning the view
\Log::info('View data:', [
'name' => $name ?? 'undefined',
'user' => $user ?? 'undefined'
]);
This helps identify exactly which variables are missing or undefined.