Last updated on April 15, 2023
Laravel 10 introduced a new package Pennant that manages your Laravel application’s features flags. It has the ability to hide and show the application’s features based on cases. It is created by the Laravel team.
But when to use Laravel Pennant? Let’s understand it by an example.
Assume, you’re releasing a new feature that should be accessible only to premium users. To do that you need an if-statement somewhere in your application that should hide new features from freemium users, right? The Laravel Pennant package provides a more advanced and easier way to do that.
How to use the Laravel Pennant?
In this article, we will be learning to use the Pennant package in the Laravel application by implementing a real example in which we will be allowing premium users to access the feature.
So, we have a Laravel 10 application that is installed with the Breeze package. Additionally, in this application, we have a Courses feature that has to be accessible only to premium users. Also, an additional column is_subscriber
in the users table that differentiates the premium and freemium users.
Install Laravel Pennant Package
To install Pennant into your application, run below composer command.
composer require laravel/pennant
Once it is installed, you need to run publish the Pennant’s configuration and migration files through vendor:publish artisan command.
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"
After, publishing the configurations, you need to run one more command to create a features table in the database. Run below artisan command,
php artisan migrate
The features table contains 5 columns id, name, scope, and value. Let’s understand each column’s function.
Defining Feature:
The Pennant package provides a define()
method that defines the feature. To define a feature in your application, You need to use the define() method from the Feature facade.
Go to app/Providers directory and open the AppServiceProvider.php. Add the below script in the boot() method of AppServiceProvider class that defines the feature for course management.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Pennant\Feature;
use App\Models\User;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Feature::define('course-management', function(User $user){
return (bool)$user->is_subscriber;
});
}
}
In the above script, we defined a feature for course management through the define() method. The define() method takes two parameters,
In the callback function, we passed the User $user
parameter that returns the current logged-in user. It returns a bool value based on the is_subscriber column from users table.
Apply Feature on Course Management Through Directive in Blade:
Pennant also provides a directive that checks if the user is authorized for the feature. Let’s use a feature directive to hide Courses for the freemium user.
Go to resources/views/layouts directory and open the navigation.blade.php. Add below HTML code with the feature directive.
@feature('course-management')
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<x-nav-link :href="route('courses')" :active="request()->routeIs('courses')">
{{ __('Courses') }}
</x-nav-link>
</div>
@endfeature
This feature directive checks if the user is premium and shows the Courses link in the menu in the dashboard.
But what about if a user directly accesses through the URL?
http://127.0.0.1:8000/courses
It will be accessible which is because it is hidden in the menu only. To remove the access from the freemium user we need middleware to protect the course management route.
Protect Feature Through Middleware:
To protect the Pennant feature, you need to register the middleware in the $middlewareAliases
array. Open the kernel.php from app/Http directory and register features middleware by adding the below script into the $middlewareAliases array.
'features' => EnsureFeaturesAreActive::class,
Also, add the following namespace at the top of the kernel.php file.
use Laravel\Pennant\Middleware\EnsureFeaturesAreActive;
Next, apply middleware on the course route. To apply to add the Pennant features middleware on the route, you need to use the middleware() method with argument.
Route::middleware('auth')->group(function () {
Route::get('/courses', [CourseController::class, 'index'])->name('courses')->middleware('features:course-management');
});
Now, courses route is protected and accessible only to premium users.
Test Pennant Feature with Premium and Freemium User:
Let’s test the course management feature with premium and freemium user. I registered two users,
For the freemium user, the is_subscriber column value is 0 while for premium it is 1. Look at the below screenshot of users table.
Pennant package inserts data for each user for the feature that needs to be managed. Look at the below screenshot of the features table.
In the features table, the value is false
for the freemium user whose id is 1 which means course management won’t be accessible. While course management will be accessible for the user that value is true
.
Below is the screenshot of freemium user John smith’s dashboard
Let’s access courses through the URL and check if it is accessible.
Now, let’s check the dashboard of Premium user Ronald