Skip to content

[4.x] Fix ->lazy() and ->defer() route macros not working for components without mount()#10106

Merged
calebporzio merged 2 commits intomainfrom
josh/fix-route-defer-without-mount
Mar 17, 2026
Merged

[4.x] Fix ->lazy() and ->defer() route macros not working for components without mount()#10106
calebporzio merged 2 commits intomainfrom
josh/fix-route-defer-without-mount

Conversation

@joshhanley
Copy link
Copy Markdown
Member

The Scenario

When using ->defer() or ->lazy() on a route for a full-page single-file component, the component renders immediately instead of being deferred/lazy loaded. The only workaround is adding the #[Defer] or #[Lazy] attribute directly to the component class, which defeats the purpose of the route macro.

// routes/web.php
Route::get('/dashboard', DashboardPage::class)->defer();
<?php

use Livewire\Attributes\Computed;
use Livewire\Component;

new class extends Component {
    #[Computed]
    public function computedProp()
    {
        sleep(10);

        return "OK";
    }
};
?>

@placeholder
<div>
    This is the placeholder
</div>
@endplaceholder
<div>
    This is not the placeholder: {{ $this->computedProp }}
</div>

The Problem

The ->defer() and ->lazy() route macros store their flags in route defaults ($route->defaults['defer'] / $route->defaults['lazy']). Laravel merges these defaults into $route->parameters() when the route is matched.

In SupportPageComponents::gatherMountMethodParamsFromRouteParameters(), the parameters are resolved via ImplicitRouteBinding::resolveMountParameters(), which calls $route->resolveMethodDependencies($route->parameters(), ...) against the component's mount() method. When mount() exists (even with no parameters), resolveMethodDependencies passes through all route parameters including defaults, so the defer/lazy keys reach SupportLazyLoading::mount($params).

However, when the component has no mount() method, resolveMountParameters() returns an empty collection. The resolveComponentProps() fallback only includes parameters matching public properties. Since there's no $defer or $lazy public property, the flags are silently dropped and lazy/deferred loading never activates.

The Solution

After resolving route parameters in gatherMountMethodParamsFromRouteParameters(), explicitly merge lazy and defer route defaults into the params array (if they're not already present). This ensures the flags always reach component hooks regardless of whether the component has a mount() method.

Fixes #10093

@calebporzio calebporzio merged commit 9791df5 into main Mar 17, 2026
32 checks passed
@calebporzio calebporzio deleted the josh/fix-route-defer-without-mount branch March 17, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants