RouteKey Model Attribute in Laravel 13.21

Last updated on by

RouteKey Model Attribute in Laravel 13.21 image

Laravel 13.21 adds a #[RouteKey] class attribute for customizing route model binding on Eloquent models, a base64 validation rule, a #[RequestAttribute] contextual attribute for injecting request attributes, and PNG, GIF, AVIF, and BMP output support in the Image component. The Laravel team tagged v13.21.0 and v13.21.1 on July 21, 2026; the patch tag only bumps the framework's version constant, so the two are covered together here.

  • #[RouteKey] attribute for Eloquent route model binding
  • New base64 validation rule
  • #[RequestAttribute] contextual attribute
  • PNG, GIF, AVIF, and BMP output formats for the Image component
  • Customizable application builder and an illuminate/concurrency subsplit

What's New

#[RouteKey] Attribute for Eloquent Models

Customizing the column used for route model binding has always meant overriding getRouteKeyName() on the model. Following the pattern set by #[ObservedBy] and #[ScopedBy], models can now declare the route key with a class attribute instead:

use Illuminate\Database\Eloquent\Attributes\RouteKey;
 
#[RouteKey('slug')]
class Post extends Model
{
// ...
}

With the attribute in place, implicit route model binding resolves Post by its slug column, and getRouteKeyName() falls back to the primary key when no attribute is present. Contributed by @nimnaherath in #60841.

base64 Validation Rule

A base64 rule joins the validator's string format checks, filling a gap that libraries like Zod already cover. The rule verifies that a value is a valid RFC 4648 Base64 string:

$request->validate([
'signature' => ['required', 'base64'],
]);

The check requires a canonical encoding: the value must decode in strict mode and re-encode to the exact same string, so padding mistakes and stray characters fail validation. Contributed by @lucasmichot in #60808.

#[RequestAttribute] Contextual Attribute

Middleware often stashes resolved objects on the request's attribute bag, a tenant or organization resolved from an API key, for example. Pulling those back out means calling $request->attributes->get() and type-hinting by hand. The new #[RequestAttribute] contextual attribute injects the value directly into a resolved parameter:

use Illuminate\Container\Attributes\RequestAttribute;
 
class InventoryController
{
public function index(#[RequestAttribute('org')] Organization $org)
{
return $this->inventoryService->getForOrg($org);
}
}

Contributed by @cosmastech in #60847.

More Output Formats for the Image Component

The Image component introduced in Laravel 13.20 could only convert to WebP, JPG, and JPEG through its fluent methods, even though the bundled Intervention Image encoders support more. This release adds toPng(), toGif(), toAvif(), and toBmp():

use Illuminate\Support\Facades\Image;
 
Image::fromUpload($request->file('avatar'))
->cover(400, 400)
->toAvif()
->quality(80)
->store('avatars');

The change also fixes Image::extension(), which was missing the image/avif MIME mapping and would have produced a .bin extension for stored AVIF output. Contributed by @Tresor-Kasenda in #60713.

Customizable Application Builder

Application::configure() previously hardcoded the ApplicationBuilder class, so packages extending Laravel's Application had to override the whole method to swap it out. A protected static $applicationBuilder property now lets subclasses provide their own builder class while keeping the existing API. See #60848.

Concurrency Subsplit

The Illuminate\Concurrency component now has its own read-only subsplit, joining the other Illuminate components published as standalone packages. See #60836.

Other Fixes and Improvements

  • Database transaction rollback callbacks now fire correctly (#60777), and a new lost connection message is detected for automatic reconnects (#60819)
  • Question marks are escaped in Grammar::whereColumn() (#60832)
  • InvalidPayloadException messages now include the job name and queue (#60799)
  • Passing an enum to LogManager::forgetChannel() no longer throws a TypeError (#60801), and RedisTaggedCache::decrement() handles enum keys (#60821)
  • Str::wordWrap() handles multibyte strings correctly (#60814)
  • Contextual attribute caching no longer collides across properties of the same class (#60815), and falsey concurrency exception parameters are preserved (#60822)
  • Fixed host port parsing in the serve command (#60828) and an undefined index in Pipeline\Hub::pipe() (#60802)

References

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $9500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Acquaint Softtech logo

Acquaint Softtech

Acquaint Softtech offers AI-ready Laravel developers who onboard in 48 hours at $3000/Month with no lengthy sales process and a 100 percent money-back guarantee.

Acquaint Softtech
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud

The latest

View all →
Laravel Time Machine: A Request Lifecycle Profiler image

Laravel Time Machine: A Request Lifecycle Profiler

Read article
Laravel SMS Catcher: A Local Dashboard for SMS Notifications image

Laravel SMS Catcher: A Local Dashboard for SMS Notifications

Read article
The Analytics Stack for Laravel: Traffic, Revenue and Attribution in One Place image

The Analytics Stack for Laravel: Traffic, Revenue and Attribution in One Place

Read article
Scaffold Packages with the `laravel package` Command in Laravel Installer v5.31.0 image

Scaffold Packages with the `laravel package` Command in Laravel Installer v5.31.0

Read article
Vocalizer: Local Text-to-Speech for PHP image

Vocalizer: Local Text-to-Speech for PHP

Read article
Build a Laravel Scout Search Endpoint With the HTTP QUERY Method image

Build a Laravel Scout Search Endpoint With the HTTP QUERY Method

Read article