Skip to content

feat(pages): check c.redirect() locations when typedRoutes is on - #739

Merged
cpojer merged 9 commits into
voidzero-dev:mainfrom
yangshun:feat/redirect-route-url
Nov 7, 2026
Merged

cpojer merged 9 commits into
voidzero-dev:mainfrom
yangshun:feat/redirect-route-url

Conversation

@yangshun

@yangshun yangshun commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Type c.redirect() as RouteUrlInput on CloudContext, so routing.typedRoutes checks the location the same way as a link.
  • An in-app route, a destination object, a URL, or an http:// / https:// / mailto: / tel: literal typechecks. A string TypeScript cannot check opts out with as Href. With typedRoutes off, any string still typechecks.
  • External redirects stay valid without a cast when the URL is an https:// literal.

Test plan

  • vp test run packages/void/test/integration/route-url-builder.test.ts -t "typechecks through the|checks URL strings against routes"
  • vp run --filter void typecheck (no new errors; existing Cloudflare deploy type errors are unchanged)
  • Confirm an app with routing.typedRoutes rejects c.redirect('/unknown') and accepts c.redirect('https://example.com/login')

Made with Cursor

Redirects take RouteUrlInput, so an in-app path is checked against the app's routes while an external URL still typechecks.

Co-authored-by: Cursor <[email protected]>
@yangshun
yangshun marked this pull request as draft November 6, 2026 23:54
yangshun and others added 3 commits November 7, 2026 09:43
Narrowing `redirect` made CloudContext an interface compared member by
member, so Hono helpers such as `getCookie(c)` and functions typed with
`Context` rejected it. `redirect` and `set` now start with an uncallable
`this: never` signature that Hono's Context accepts, while calls still
resolve to the typed signature. This drops the defineHandler overloads
that worked around the same problem for `etag()`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
handlePageGet and handlePageMutation were async before the CloudContext
wrappers were added. Keeping them async means any failure reaches callers
as a rejected promise.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The cast turns the typedRoutes check off and nothing validates the
location at runtime. Show how to check a `?redirectTo=` value before
redirecting to it, and list `c.redirect()` as a `RouteUrlInput` consumer.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@yangshun
yangshun marked this pull request as ready for review November 7, 2026 02:27
@cpojer
cpojer self-requested a review November 7, 2026 09:56
cpojer and others added 5 commits November 7, 2026 19:04
The main merge kept only this branch's side of the type-safety guide, which
dropped the stream client paragraph that voidzero-dev#741 added.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@cpojer cpojer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@cpojer
cpojer merged commit 4d51362 into voidzero-dev:main Nov 7, 2026
17 checks passed
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