Blade provides a whole host of directives to make templating easier. However, sometimes you need to create your own custom directive to save repeating yourself and clear up your Blade templates.
So, here's how to create custom Blade directives in Laravel.
Let's start with a basic custom directive, so we know everything is working, and then we'll dive into some more advanced usage.
Over in AppServiceProvider
(or any other service provider), use the directive
method to name and return what your directive should do.
use Illuminate\Support\Facades\Blade;
class AppServiceProvider extends ServiceProvider
{
//...
public function boot(): void
{
Blade::directive('myCustomDirective', function () {
return 'It works!';
});
}
}
To use your custom directive, use it like any other built-in directive in Laravel.
<div>
@myCustomDirective()
</div>
This will dump It works! to the page.
Ok, so we have this working. Now let's take a look at a couple of practical examples.
It's likely you're going to want to use a directive to do something with some data. In this case, here's what a directive to uppercase some text might look like.
Blade::directive('upper', function (string $text) {
return str()->upper($text);
});
Let's try this out, and we'll see a slight issue with the output.
<div>
@upper('Hey')
</div>
Here's the output we get, which includes the single quotes surrounding the string. Hmm, strange.
'HEY'
The correct way to build a custom Blade directive in Laravel is to return a string
of PHP code to output the result of whatever you're doing.
Why? Because Blade is a templating engine, the end result is always transformed into vanilla PHP code that makes use of echo
!
So, our directive from earlier needs to be defined like this:
Blade::directive('upper', function (string $text) {
return "<?php echo str()->upper($text) ?>";
});
Tip: As you're developing a Blade directive, you'll want to run
php artisan view:clear
to clear previously cached versions of your custom directive.
Great, so make sure you use echo
and wrap it in PHP tags when returning values from custom Blade directives, and everything should work.
You can absolutely include more complex markup output in Blade directives, just be careful of single and double quote placement, as well as how you're concatenating data.
The return value of a Blade directive needs to be wrapped in double quotes in order for any arguments passed through to be accessed.
Here's an example of a custom Blade directive I created to attach some Google reCAPTCHA functionality using Alpine.js to any forms.
Blade::directive('recaptcha', function (string $action) {
return new HtmlString('
x-data
x-on:submit.prevent="
grecaptcha.ready(() => {
grecaptcha.execute(\'' . config('recaptcha.key') . '\', { action: ' . $action . ' }).then((token) => {
let input = document.createElement(\'input\')
input.setAttribute(\'type\', \'hidden\')
input.setAttribute(\'name\', \'recaptcha_token\')
input.setAttribute(\'value\', token)
$el.appendChild(input)
$nextTick(() => {
$el.submit()
})
})
})
"
');
});
As you can see, I've escaped any single quotes here, and used the HtmlString
class to wrap the output. This prevents double escaping, signals intent for safe HTML and just generally feels nicer than the echo
with vanilla PHP.
I hope this has helped you to create your own custom Blade directives in Laravel.
The process can be a little fiddly depending on how complex your custom directives get, but now you've got the basics, you can take it from here!