How to Pass Global Variables to Blade: View Share and Composer

Laravel View Composer

Imagine you want to show some "global" data in the Blade: for example, the number of new users this week on the top navigation. Not sure what Controllers would the data come from? Then you can perform that action in the Service Provider, in three ways.

For example, you want to have this in the resources/layouts/app.blade.php, somewhere in the navigation:

<div class="flex flex-shrink-0 items-center mr-4">
Users this week: {{ $newUsersThisWeekCount }}
</div>

This would be shown on all pages that extend this layout. So where do we initialize that variable?

Answer: in the Service Provider. In any of them, but for this simple example we will use the boot() method of the default AppServiceProvider that comes with Laravel, so you wouldn't need to generate any new classes.


Option 1. View Share

app/Providers/AppServiceProvider.php:

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->share('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
}
}

This will share the variable $newUsersThisWeekCount value with all Blade views, not only layout navigation or sidebar.


Option 2. View Composer Callback

If you want to share the value only with specific Blade views, use this:

app/Providers/AppServiceProvider.php:

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('layouts.app', function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
});
}
}

You can also provide several views:

view()->composer(
['layouts.app', 'layouts.sidebar'],
function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
}
);

Or even use asterisk * to provide all views:

view()->composer('*', function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
});

Notice: be VERY careful with that asterisk option, because it will load the same SQL query for EVERY view separately, including all partial Blade views.


Option 3. View Composer Class

If you have more complicated logic and don't want to "pollute" the Service Provider with a lot of code, you can create a separate View Composer class.

There's no php artisan make:viewcomposer Artisan command, so you need to create this class manually, and it's your choice where to put it. Example:

app/View/Composers/NewUsersComposer.php:

namespace App\View\Composers;
 
use Illuminate\View\View;
 
class NewUsersComposer
{
public function compose(View $view)
{
$newUsersThisWeekCount = your_complicated_logic();
 
$view->with('newUsersThisWeekCount', $newUsersThisWeekCount);
}
}

Then, in the Service Provider, you would register it like this:

app/Providers/AppServiceProvider.php:

use App\View\Composers\NewUsersComposer;
 
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('layouts.app', NewUsersComposer::class);
}
}
avatar

Informative one.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 58 courses (1056 lessons, total 44 h 09 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials