feat(inertia): add deferred props with defer()#1911
Merged
Conversation
🦋 Changeset detectedLatest commit: 84f47fe The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1911 +/- ##
==========================================
+ Coverage 92.08% 92.11% +0.03%
==========================================
Files 115 115
Lines 3965 3983 +18
Branches 1023 1029 +6
==========================================
+ Hits 3651 3669 +18
Misses 282 282
Partials 32 32
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
yusukebe
reviewed
Jun 1, 2026
Member
The previous assertion checked for '"posts"\\:[{' (with an escaped
colon), but serializePage only escapes '/' → '\\/', so the string
would never appear in the rendered HTML — the test passed trivially.
Match the actual serialized form so the assertion verifies that the
deferred value is omitted from the initial HTML.
Contributor
Author
|
@yusukebe Thanks for the review!
|
Member
|
@ashunar0 Thank you so much! |
Merged
This was referenced Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second step of the
@hono/inertiav3 protocol breakdown: ② Deferred props, built on top of the partial reload foundation from #1904.Adds a
defer(resolver, group?)helper. On the initial response the resolver is skipped and the prop key is advertised underpage.deferredProps[group]. The Inertia client then issues one partial reload per group, at which point the resolver runs and the value is sent down — letting heavy data fetching happen after the page becomes interactive.Multiple deferred props that share a
groupare fetched together in a single partial reload. The default group is"default".Protocol behaviour
posts: defer(fn)behaviourX-InertiaGET)fnnot invoked,page.deferredProps.default = ['posts']emittedpostsinX-Inertia-Partial-Datafninvoked, value returned underprops.postspostsfnnot invoked, key omitted from responseAccept: application/jsonrequestfnnot invoked, key omitteddeferredPropsis only emitted on the initial response; subsequent partial reloads strip it, so the client does not re-trigger the same group.Implementation
defer<T>(resolver, group = 'default'): Treturns an opaque marker (Symbol.for('@hono/inertia/defer')) that the renderer unwraps. The return type isT, so call sites stay transparent andTypedResponseinfers the awaited resolver type.PageObjectgains an optionaldeferredProps?: Record<string, string[]>field, only present on the initial response when at least one prop was deferred.Scope intentionally kept small (single PR per protocol feature, like #1904):
defer()markersmerge/prepend/deepMerge/always(fn)/ infinite scroll markers — separate PRs (③④⑤ in the breakdown)Test plan
yarn workspace @hono/inertia test(28 passed, 9 new tests covering initial skip / group emission / partial resolve /onlyfilter / JSON request / mixed deferred + function props / no-defer no-emit / non-XHR HTML visit)eslint packages/inertiacleanprettier --checkcleantsc -bcleantsdownbuild success