Laravel 13.21 landed on July 21, 2026 (tags v13.21.0 and v13.21.1), bringing a handful of developer-experience improvements across routing, validation, dependency injection, and image handling. Here is a detailed look at everything that changed.
#[RouteKey] Attribute for Eloquent Models
Customizing the column used for route model binding previously required overriding getRouteKeyName() on every model that needed it. Laravel 13.21 follows the same PHP attribute pattern established by #[ObservedBy] and #[ScopedBy], letting you declare the route key directly on the class:
use Illuminate\Database\Eloquent\Attributes\RouteKey;
#[RouteKey('slug')]
class Post extends Model
{
// ...
}
Implicit route model binding now resolves Post by its slug column automatically. When no attribute is present, getRouteKeyName() falls back to the primary key as before. Contributed by @nimnaherath in #60841.
base64 Validation Rule
A new base64 rule is available in the validator, covering a gap that previously required custom rules or third-party packages:
$request->validate([
'signature' => ['required', 'base64'],
]);
The rule enforces canonical RFC 4648 encoding: the value must decode in strict mode and re-encode to the exact same string, so padding errors and stray characters are rejected. Contributed by @lucasmichot in #60808.
#[RequestAttribute] Contextual Attribute
Middleware commonly stashes resolved objects—tenants, organizations, authenticated entities—on the request attribute bag. Retrieving them has always meant calling $request->attributes->get() and casting manually. The new #[RequestAttribute] contextual attribute injects the value directly into a controller parameter:
use Illuminate\Container\Attributes\RequestAttribute;
class InventoryController
{
public function index(#[RequestAttribute('org')] Organization $org)
{
return $this->inventoryService->getForOrg($org);
}
}
This keeps controllers clean and makes the dependency explicit without any boilerplate. Contributed by @cosmastech in #60847.
More Output Formats for the Image Component
The Image component introduced in Laravel 13.20 was limited to WebP, JPG, and JPEG output. This release adds four more fluent conversion methods:
use Illuminate\Support\Facades\Image;
Image::fromUpload($request->file('avatar'))
->cover(400, 400)
->toAvif()
->quality(80)
->store('avatars');
The new methods are toPng(), toGif(), toAvif(), and toBmp(). The release also fixes Image::extension(), which was missing the image/avif MIME mapping and would have written AVIF files with a .bin extension. Contributed by @Tresor-Kasenda in #60713.
Customizable Application Builder
Packages that extend Laravel's Application class previously had to override the entire configure() method to swap in a custom ApplicationBuilder. A new protected static $applicationBuilder property lets subclasses specify their own builder class without touching the rest of the method. See #60848.
Other Fixes and Improvements
- Database transaction rollback callbacks now fire correctly.
- Question marks are properly escaped in
Grammar::whereColumn(). InvalidPayloadExceptionmessages now include the job name and queue.Str::wordWrap()handles multibyte strings correctly.- Passing an enum to
LogManager::forgetChannel()no longer throws aTypeError. - Fixed host port parsing in the
servecommand. - The
Illuminate\Concurrencycomponent now has its own standalone subsplit package.
Key Takeaways
- Use
#[RouteKey('column')]instead of overridinggetRouteKeyName()for cleaner Eloquent models. - The
base64validation rule enforces strict RFC 4648 encoding with no extra packages required. #[RequestAttribute]eliminates manual$request->attributes->get()calls in controllers.- AVIF, PNG, GIF, and BMP are now first-class output formats in the Image component.
- The AVIF MIME mapping bug that produced
.binfiles is fixed.
Source: Laravel News — RouteKey Model Attribute in Laravel 13.21