Summary
Support the stable typedRoutes config option (statically typed links). vinext's typegen already generates .next/types/routes.d.ts with route unions and a ParamMap, which is most of the machinery — what's missing is the typed-links file Next.js emits when typedRoutes: true is set, plus wiring for the config flag. vinext check currently reports experimental.typedRoutes as unsupported, and the stable top-level typedRoutes key isn't in the config support map at all.
Motivation / problem
Apps that enable typedRoutes rely on import type { Route } from 'next' and compile-time validation of href values (e.g. lint/CI guards that keep internal links pointing at real routes). Migrating such an app to vinext silently loses the feature: the vendored Route<T> type stays the string & {} fallback stub, so everything type-checks whether or not the route exists. For codebases that use typed routes as a correctness gate rather than a convenience, this is a migration blocker.
Expected behaviour
With typedRoutes: true in next.config.*:
- Dev, build, and
vinext typegen additionally emit the typed-links declaration file (Next 16 writes .next/types/link.d.ts): the __next_route_internal_types__ namespace with StaticRoutes / DynamicRoutes / RouteImpl<T>, plus declare module augmentations for next (real Route<T>), next/link (typed href), next/navigation (typed useRouter, redirect, permanentRedirect), and next/form.
- The generated
next-env.d.ts references the new file alongside routes.d.ts.
vinext check reports typedRoutes as supported, with experimental.typedRoutes treated as a deprecated alias (matching Next, which stabilised the option).
Actual behaviour
- The
typedRoutes flag is not read anywhere; only routes.d.ts is generated.
Route<T> resolves to the vendored stub string & {}, so no href validation occurs.
check.ts lists experimental.typedRoutes as unsupported — typed routes not implemented; the stable key is absent from CONFIG_SUPPORT.
Reproduction context
Any Next.js 16 App Router project with typedRoutes: true in next.config.ts. Run vinext typegen (or dev/build) and observe that no typed-links declarations are generated and invalid <Link href="/does-not-exist"> values type-check. Observed against vinext main as of 2026-08-25 while scanning a six-app Next 16 monorepo for migration feasibility.
Additional context
Implementation sketch, from reading both codebases:
- Next 16's reference implementation is compact:
route-types-utils.js writes link.d.ts from generateLinkTypesFile(manifest) when config.typedRoutes === true. The template ports nearly verbatim, and typegen.ts's existing route model (patternToNextFormat) already produces Next-format patterns for the StaticRoutes / DynamicRoutes unions.
- The vendored type tree (
packages/types/next/upstream/dist/) already contains the modules the generated augmentations import from (dist/client/link.d.ts, dist/client/components/redirect-error.d.ts), so the emitted file should type-check without adapting the template's import paths.
- Config plumbing: pass
nextConfig.typedRoutes through the writeRouteTypes() call sites in index.ts and the typegen CLI path; warnDeprecatedConfigOptions is the existing hook for the experimental.typedRoutes alias.
- Suggested scope for a first pass: App Router routes only (vinext's typegen currently models only the app dir). Next also folds Pages Router routes and redirect/rewrite sources into the generated unions — those, plus
experimental.strictRouteTypes, could be deferred to follow-ups if that helps keep the first PR reviewable.
- Tests would extend
tests/typegen.test.ts's existing temp-project harness: static / dynamic / catch-all / route-group cases with the flag on, and a flag-off case asserting no typed-links file is emitted.
Summary
Support the stable
typedRoutesconfig option (statically typed links). vinext's typegen already generates.next/types/routes.d.tswith route unions and aParamMap, which is most of the machinery — what's missing is the typed-links file Next.js emits whentypedRoutes: trueis set, plus wiring for the config flag.vinext checkcurrently reportsexperimental.typedRoutesas unsupported, and the stable top-leveltypedRouteskey isn't in the config support map at all.Motivation / problem
Apps that enable
typedRoutesrely onimport type { Route } from 'next'and compile-time validation ofhrefvalues (e.g. lint/CI guards that keep internal links pointing at real routes). Migrating such an app to vinext silently loses the feature: the vendoredRoute<T>type stays thestring & {}fallback stub, so everything type-checks whether or not the route exists. For codebases that use typed routes as a correctness gate rather than a convenience, this is a migration blocker.Expected behaviour
With
typedRoutes: trueinnext.config.*:vinext typegenadditionally emit the typed-links declaration file (Next 16 writes.next/types/link.d.ts): the__next_route_internal_types__namespace withStaticRoutes/DynamicRoutes/RouteImpl<T>, plusdeclare moduleaugmentations fornext(realRoute<T>),next/link(typedhref),next/navigation(typeduseRouter,redirect,permanentRedirect), andnext/form.next-env.d.tsreferences the new file alongsideroutes.d.ts.vinext checkreportstypedRoutesas supported, withexperimental.typedRoutestreated as a deprecated alias (matching Next, which stabilised the option).Actual behaviour
typedRoutesflag is not read anywhere; onlyroutes.d.tsis generated.Route<T>resolves to the vendored stubstring & {}, so no href validation occurs.check.tslistsexperimental.typedRoutesasunsupported — typed routes not implemented; the stable key is absent fromCONFIG_SUPPORT.Reproduction context
Any Next.js 16 App Router project with
typedRoutes: trueinnext.config.ts. Runvinext typegen(or dev/build) and observe that no typed-links declarations are generated and invalid<Link href="/does-not-exist">values type-check. Observed against vinext main as of 2026-08-25 while scanning a six-app Next 16 monorepo for migration feasibility.Additional context
Implementation sketch, from reading both codebases:
route-types-utils.jswriteslink.d.tsfromgenerateLinkTypesFile(manifest)whenconfig.typedRoutes === true. The template ports nearly verbatim, andtypegen.ts's existing route model (patternToNextFormat) already produces Next-format patterns for theStaticRoutes/DynamicRoutesunions.packages/types/next/upstream/dist/) already contains the modules the generated augmentations import from (dist/client/link.d.ts,dist/client/components/redirect-error.d.ts), so the emitted file should type-check without adapting the template's import paths.nextConfig.typedRoutesthrough thewriteRouteTypes()call sites inindex.tsand thetypegenCLI path;warnDeprecatedConfigOptionsis the existing hook for theexperimental.typedRoutesalias.experimental.strictRouteTypes, could be deferred to follow-ups if that helps keep the first PR reviewable.tests/typegen.test.ts's existing temp-project harness: static / dynamic / catch-all / route-group cases with the flag on, and a flag-off case asserting no typed-links file is emitted.