Release Date: January 13, 2026
Laravel Version: 12.47.0
Summary
Laravel 12.47.0 was released on January 13, 2026, introducing several developer-experience improvements including a new @includeIsolated Blade directive for isolated template includes, a convenient Cache::withoutOverlapping() method for lock-based operations, and enhanced enum support across various framework components. This release also adds support for precognitive requests with wildcard array validations and makes the Notification class macroable.
Key highlights include:
- New
@includeIsolatedBlade directive for variable-isolated includes Cache::withoutOverlapping()method to simplify lock-based operations- Precognitive request support for wildcard array validations
- Notification class is now macroable
PendingBatch::onConnection()now accepts enum values- Additional enum key support in Session Store methods
- JSON API circular reference deduplication
- Improved
key:generateerror message whenAPP_KEYis already set - Indexes added to
failed_jobsmigration stub Bus::batchnow filters out falsy items
What's New
Isolated Blade Includes with @includeIsolated
Laravel 12.47.0 introduces the @includeIsolated directive, which allows you to include a Blade template without inheriting any variables from the parent view. This provides a clean slate for the included template, preventing accidental variable leakage and making templates more predictable.
Standard @include directives share the parent view's variables:
{{-- $user is available in the parent --}}@include('partials.header') {{-- $user is also available here --}}
With @includeIsolated, the included template starts fresh with only the variables you explicitly pass:
{{-- $user is available in the parent --}}@includeIsolated('partials.header') {{-- $user is NOT available here --}} {{-- Pass only what you need --}}@includeIsolated('partials.header', ['title' => 'Welcome'])
This is particularly useful for:
- Reusable components: Ensures templates don't accidentally depend on parent variables
- Third-party templates: Prevents variable conflicts when including external templates
- Testing: Makes it easier to test templates in isolation
- Clarity: Makes template dependencies explicit and intentional
Pull Request: #58311
Cache Lock Convenience with Cache::withoutOverlapping()
The new Cache::withoutOverlapping() method provides a cleaner API for executing code that should not run concurrently. This wraps the common pattern of acquiring a lock and blocking until it's available.
Previously, you might write:
Cache::lock('processing-order-' . $orderId) ->block(10) ->get(function () use ($orderId) { // Process the order });
Now you can use the more expressive withoutOverlapping() method:
Cache::withoutOverlapping('processing-order-' . $orderId, function () use ($orderId) { // Process the order - guaranteed no concurrent execution}, seconds: 10);
The method accepts a key, a callback to execute, and optional parameters for the blocking timeout and lock expiration:
Cache::withoutOverlapping( key: 'send-daily-report', callback: fn () => $this->generateAndSendReport(), seconds: 30, // Wait up to 30 seconds for the lock owner: 'worker-1' // Optional lock owner identifier);
This is ideal for queue jobs, scheduled tasks, and any operation where concurrent execution could cause data inconsistencies.
Pull Request: #58303
Precognitive Requests with Wildcard Array Validations
Laravel's precognition feature now supports wildcard array validations. This allows form validation to work correctly when using precognitive requests with array fields that use wildcard (*) syntax.
When validating array inputs with rules like:
$request->validate([ 'items' => ['required', 'array'], 'items.*.name' => ['required', 'string', 'max:255'], 'items.*.quantity' => ['required', 'integer', 'min:1'],]);
Precognitive requests will now properly validate individual array items as users interact with dynamic form fields, providing real-time feedback for each item in the array.
Pull Request: #57486
Macroable Notifications
The Illuminate\Notifications\Notification class is now macroable, allowing you to extend notifications with custom methods:
use Illuminate\Notifications\Notification; Notification::macro('sendToSlack', function (ChannelAwareSlackNotification $notification): void { Notification::route('slack', $notification::slackChannel())->notify($notification);});
This enables you to add shared functionality across all your notifications without creating a base notification class.
Pull Request: #58352
Enum Support for PendingBatch::onConnection()
The PendingBatch::onConnection() method now accepts enum values, bringing consistency with other parts of the framework that support enums for queue connections:
enum QueueConnection: string{ case Redis = 'redis'; case Database = 'database'; case Sync = 'sync';} Bus::batch([ new ProcessPodcast($podcast), new OptimizePodcast($podcast),])->onConnection(QueueConnection::Redis)->dispatch();
Pull Request: #58350
Enum Keys in Additional Session Store Methods
Following the enum support trend, additional Session Store methods now accept enum keys. This allows for more type-safe session operations:
enum SessionKey: string{ case Cart = 'cart'; case User = 'user'; case Preferences = 'preferences';} // Now supported with enum keyssession()->get(SessionKey::Cart);session()->put(SessionKey::User, $user);session()->forget(SessionKey::Preferences);
Pull Request: #58343
JSON API Circular Reference Deduplication
When using Laravel's JSON API resources, circular references are now automatically deduplicated. This prevents infinite loops and reduces response payload size when dealing with bidirectional relationships:
// User has many posts, Post belongs to User// Previously could cause circular reference issues// Now automatically handledreturn new UserResource($user->load('posts.author'));
Pull Request: #58348
Improved key:generate Error Message
The php artisan key:generate command now provides a more helpful error message when APP_KEY is already set in your environment. This makes it clearer why the command isn't generating a new key and guides developers to use the --force flag if they intentionally want to regenerate:
$ php artisan key:generate# Now shows: Application key already set. Use --force to regenerate.
Pull Request: #58345
Database Indexes for Failed Jobs Table
The failed_jobs migration stub now includes database indexes for improved query performance. When creating a new failed jobs table, it will automatically include indexes on commonly queried columns:
Schema::create('failed_jobs', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); $table->text('connection'); $table->text('queue')->index(); // New index $table->longText('payload'); $table->longText('exception'); $table->timestamp('failed_at')->useCurrent()->index(); // New index});
This improves performance when querying failed jobs by queue name or failure time.
Pull Request: #58355
Bus Batch Falsy Item Filtering
Bus::batch() now automatically filters out falsy items, making it easier to conditionally include jobs in a batch:
Bus::batch([ new ProcessOrder($order), $needsNotification ? new SendNotification($order) : null, $needsAnalytics ? new TrackAnalytics($order) : null,])->dispatch();// Falsy items (null, false) are automatically removed
Pull Request: #58360
Additional Changes
This release also includes several other improvements:
- Fixed QueryException to show correct connection details for read PDO connections (#58331)
- Improved return types for
Number::with*()helpers (#58358) - Fixed typo in JsonApiResource trait method (#58326)
- Updated return type annotations in FormRequest.php (#58333)
- Fixed composer uninstall events to only fire when removing dev packages (#58338)
- Improved types in
\Illuminate\Support\Strhelper (#58356)
Upgrade Notes
No breaking changes are expected for typical applications. Review the full changelog for complete details when upgrading.
References
- Full Changelog: v12.46.0...v12.47.0
- Official Changelog: CHANGELOG.md#v12470