In this blog post, we will learn 4 ways to share common variables or data across all views without manually passing them to each view. This can be useful if you need to set common data like navigation menu items or some global variables you need to access in multiple views.
To pass data to multiple or all views using Laravel, you can use View::share in AppServiceProvider, use a View Composer or set the shared data in a BaseController constructor or a Middleware handle function.
In this blog post, we’ll cover each of these 4 options, including step-by-step instructions and code samples. Let’s dive in!
Method 1: Using AppServiceProvider
- Open
app/Providers/AppServiceProvider.php
- Add the following code into the
boot
method:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
View::share('myGlobalKey', 'This is our value');
}
}
- Replace
'myGlobalKey'
with the actual key name and'This is our value'
with the desired value or data. - Make a test.blade.php and fill it with:
Test: {{ $myGlobalKey }}
- Add a test route to web.php using the following code:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/test', function () {
return view('test');
});
- Open a browser and you will see our value is shown on the page
Method 2: Using a View Composer
View Composers provide a more flexible approach to passing data to views. Here’s how to use them:
- Create a new View Composer by running the following command in your terminal:
php artisan make:provider ViewServiceProvider
- Open the newly created file
app/Providers/ViewServiceProvider.php
- In the
boot
method, add the following code:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
}
/**
* Bootstrap services.
*/
public function boot(): void
{
View::composer('*', function ($view) {
$view->with('viewComposerBasedValue', 'This is our value as shared by a view composer');
});
}
}
- Replace
'key'
with the actual key name and'value'
with the desired value or data. - Open
config/app.php
and add our customViewServiceProvider
, like shown below:
<?php
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\ServiceProvider;
return [
/* Other config values in app.php ... */
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => ServiceProvider::defaultProviders()->merge([
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\ViewServiceProvider::class // <-- Here we add our ViewServiceProvider
])->toArray(),
/* Other config values in app.php ... */
];
- Make a Controller to test with by running:
php artisan make:controller SomeController
- Open
SomeController.php
and add ashow()
method using this code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SomeController extends Controller
{
public function show()
{
return view('some-view');
}
}
- In your views folder make a
and add:some-view.blade.php
Here is the value shared from a view composer: {{ $viewComposerBasedValue }}
- Add a route to web.php:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/some-view', [\App\Http\Controllers\SomeController::class, 'show']);
- Open the browser and check the result
Method 3: Using a BaseController
Another way to share data across views is to make a BaseController and have it set our shared value in its constructor. Then every Controller which extends the BaseController will have it available in all its views.
Here are the steps needed to set it up:
- Create a
BaseController
by running the following command in your terminal:
php artisan make:controller BaseController
- In the
BaseController
, define a method that will be called for all requests:
<?php
namespace App\Http\Controllers;
class BaseController extends Controller
{
public function __construct()
{
// Add data to be passed to all views
view()->share('anotherGlobalValue', 'This is another one of our values');
}
}
- Make another controller, for instance
HomeController
:
php artisan make:controller HomeController
- Open it and have it extend the
BaseController
using the following code:
<?php
namespace App\Http\Controllers;
class HomeController extends BaseController
{
public function home() {
return view('home');
}
}
- In your views folder make a
home.blade.php
and add:
Test Home: {{ $anotherGlobalValue }}
- Add a test route to web.php using the following code:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/home', [\App\Http\Controllers\HomeController::class, 'home']);
- Open the browser and check the result:
Note that when using the BaseController method, you need to edit all controllers that require the shared data and add
extends BaseController
. This ensures that the controllers inherit the shared data defined in the BaseController.
Method 4: Using Middleware
Middleware provides a convenient way to intercept requests and perform tasks before any controller or view code is executed. We can use this to set data before it is accessed by any of our views. Here’s how to implement it:
- Create a new middleware by running the following command in your terminal:
php artisan make:middleware SharedViewDataMiddleware
- Open the newly created middleware file and add the following code:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\View;
class SharedViewDataMiddleware
{
public function handle($request, Closure $next)
{
View::share('middlewareSharedData', 'This value was shared by our Middleware');
return $next($request);
}
}
- Register the middleware in the
$middleware
property of yourapp/Http/Kernel.php
file. - Add a view “some-other-view.blade.php”:
Here is the value shared from a middleware: {{ $middlewareSharedData }}
- Open
routes/web.php
and addSharedViewDataMiddleware
to a group. Inside the group add all routes which need the shared data:
use App\Http\Middleware\SharedViewDataMiddleware;
Route::group(['middleware' => SharedViewDataMiddleware::class], function () {
Route::get('/test-middleware', function () {
return view('some-other-view');
});
// .. Add other routes which need the shared view data here ..
});
- Open the browser to check the result:
Conclusion
In this blog post, we explored four different methods to pass data to all views in Laravel: using the AppServiceProvider, View Composers, BaseController, or Middleware. Each method has its advantages and considerations.
With the AppServiceProvider, we can easily share data across all views by defining it in the boot method. View Composers offer flexibility to bind specific data to individual or groups of views. The BaseController approach sets shared data in its constructor, making it available in views of controllers that extend it. Middleware intercepts requests and sets data before it’s accessed by any view.
By implementing these methods, you easily access common data across your blade views. Happy coding!
References
- Sharing data with all views (Laravel documentation)
- View Composers (Laravel documentation)
There are two more ways though:
1) Helper File
2) Defining Global Variables in route file
Thank you for sharing your thoughts and suggesting two more alternatives, which would undoubtedly work too. My post covered the four methods I found useful, but I’m also aware that there could be even more ways to share global view data. Learning every day!
You have missed to change extends Controller in:
class BaseController extends BaseController
Thank you for commenting. It indeed needs to be ‘extends Controller’ instead, I’m glad you caught the oversight. I have corrected the code sample accordingly.