Skip to content

[pull] canary from vercel:canary - #1316

Merged
pull[bot] merged 6 commits into
code:canaryfrom
vercel:canary
Aug 18, 2026
Merged

[pull] canary from vercel:canary#1316
pull[bot] merged 6 commits into
code:canaryfrom
vercel:canary

Conversation

@pull

@pull pull Bot commented Aug 18, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

fabian-hiller and others added 6 commits August 18, 2026 15:44
…97468)

The forms guides recommend validating with a library like Zod. This
broadens the wording to also mention Valibot, which covers the same use
case with a smaller bundle footprint. The authentication guide already
lists Zod or Yup, so Valibot is added to that list as well. The existing
Zod examples are unchanged. I'm the author of Valibot.

- Ran `prettier --check` on the touched files with the repo's pinned
version.
…link (#97507)

Closes #96999

Make sure we don't do `.read().hash()` which is incorrect with symlinks.
Instead, hash the symlink itself instead of its target. This is what we
copy into the function source anyway

---------

Co-authored-by: vercel-fleet[bot] <308483924+vercel-fleet[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Development responses used `no-store, must-revalidate` until #88182
tried `no-cache, must-revalidate` behind
`experimental.devCacheControlNoCache`, and #91503 removed that option
and hard-coded the `no-cache` value everywhere. That was right for
static assets and wrong for documents. A browser may reuse a stored
response for a history navigation without revalidating it, and
development documents are streamed without an `ETag`, so there is
nothing to revalidate against. Going back therefore restored the
document the browser had stored earlier and showed output from before
the latest edit, and it is also what forced the debug channel
persistence workarounds in #92892, #93486 and #94243.

Documents and RSC or data responses now use `no-store` again, set in
`app-page-runtime.ts` for app pages, in `pages-handler.ts` for pages,
and in the legacy render pipe in `base-server.ts` so that the three do
not drift apart. None of them ever serves a static asset, so assets keep
`no-cache, must-revalidate` from the `nextStaticFolder` branch in
`router-server.ts` and stay cacheable: they are revalidated against the
`ETag` that `serveStatic` adds and reused from a `304` instead of being
downloaded again on every page load. `must-revalidate` is left off the
document value, because it only governs reuse of an already stale stored
response and nothing is stored any more.

A back navigation is no longer instant, since the document is fetched
again instead of being restored locally.
`test/development/dev-cache-control` covers both sides of that
trade-off: an edit that is visible after a back navigation, and
unchanged assets that still come back as `304`. It replaces
`dev-cache-control-no-cache` and asserts the header for both routers as
well, so there is one suite instead of two with nearly the same name.

A development document is now never restored from the HTTP cache, so the
debug channel persistence has no remaining trigger and its `IndexedDB`
write on every page load is no longer needed. Removing it is a follow-up
on top of this change. The pruning and recovery test in
`bfcache-regression` is the one case whose premise disappears entirely,
and it is skipped here with a note to delete it along with the
persistence.

closes #96503
Documents are now served with `no-store` in development, so a browser
never restores one from its HTTP cache and the page scripts never
re-execute against a debug channel that has already delivered its data.
The persistence and restore machinery that existed for that case has no
remaining trigger, so this removes it: the `IndexedDB` write scheduled
on every page load, the cache-restore detection across
`PerformanceNavigationTiming` fields and `deliveryType`, the `pageshow`
deferral for browsers that populate those fields late, and the
`location.reload()` fallback for a missing entry. It was built up over
#92892, #93486, #94128, #94317 and #94243, and takes `debug-channel.ts`
from 535 lines to 121.

The per-consumer `tee()` and the LRU-bounded pair map stay. They were
added for an unrelated reason, namely that one response can be decoded
more than once, so this is not a revert to the state before the
persistence landed. The rejection handler on `writer.closed` also stays,
because an errored stream would otherwise surface as an unhandled
rejection now that nothing else observes it.

`bfcache-regression` keeps the original regression test, which loads a
page, navigates away, comes back and asserts that the counter is still
interactive. That case now fails if the development `Cache-Control`
value ever goes back to `no-cache`, because the restored document would
block hydration with no reload to recover, so it is worth keeping as is.
The other three tests lose their premise and are deleted along with the
routes only they used: the pruning case that was skipped when the header
changed, the recovery case that needs a restore path to recover into,
and the streaming case that guarded the detection against treating an
in-flight response as a restore. The `large-debug-data` route goes too.
It existed only to make the persistence write expensive enough to
profile by hand when it moved to `IndexedDB`.
## Summary

Document that `permanentRedirect()` throws and should be called outside
a broad `try/catch` block.

The `redirect()` and `notFound()` references already explain this
control-flow requirement. The `permanentRedirect()` reference omits it,
so application error handling can accidentally suppress the redirect.

Align the page with the `redirect()` reference by adding a dedicated
Behavior section for the try/catch guidance and temporary-redirect
cross-link.

## Verification

- Prettier, ESLint, and `git diff --check`
Closes #97467

---------

Co-authored-by: vercel-fleet[bot] <308483924+vercel-fleet[bot]@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators Aug 18, 2026
@pull pull Bot added the ⤵️ pull label Aug 18, 2026
@pull
pull Bot merged commit 9dfbc93 into code:canary Aug 18, 2026
12 of 15 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants