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:

1<div class="flex flex-shrink-0 items-center mr-4">
2 Users this week: {{ $newUsersThisWeekCount }}
3</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:

1class AppServiceProvider extends ServiceProvider
2{
3 public function boot()
4 {
5 view()->share('newUsersThisWeekCount',
6 User::where('created_at', '>', now()->subDays(7))->count());
7 }
8}

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:

1class AppServiceProvider extends ServiceProvider
2{
3 public function boot()
4 {
5 view()->composer('layouts.app', function ($view) {
6 $view->with('newUsersThisWeekCount',
7 User::where('created_at', '>', now()->subDays(7))->count());
8 });
9 }
10}

You can also provide several views:

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

Or even use asterisk * to provide all views:

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

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:

1namespace App\View\Composers;
2 
3use Illuminate\View\View;
4 
5class NewUsersComposer
6{
7 public function compose(View $view)
8 {
9 $newUsersThisWeekCount = your_complicated_logic();
10 
11 $view->with('newUsersThisWeekCount', $newUsersThisWeekCount);
12 }
13}

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

app/Providers/AppServiceProvider.php:

1use App\View\Composers\NewUsersComposer;
2 
3class AppServiceProvider extends ServiceProvider
4{
5 public function boot()
6 {
7 view()->composer('layouts.app', NewUsersComposer::class);
8 }
9}
avatar

Informative one.

Like our articles?

Become a Premium Member for $129/year or $29/month

Recent Premium Tutorials