Repository navigation
refactor: share the rendering core and prop types of Router and RouteDisplay - #273
Merged
Merged
Conversation
Follow-up to #270, with no behavior change. Extract the rendering logic duplicated between Router and RouteDisplay (feature flags, SSR URL, loader execution and cache keying, RouterContext and providers) into Router/RouteTree.tsx. Router and RouteDisplay now only differ in how they create the adapter and whether they set up interception. Also document that RouteDisplay assumes nothing else on the page intercepts navigations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vNbiZGrzNhyfyctwm4NbJ
Define the props both components pass to RouteTree (routes, ssr, trailingSlash, features) once, as RouteTreeSharedProps in Router/props.ts, together with SSRConfig and RouterFeatures. RouterProps, RouteDisplayProps and RouteTreeProps extend it as interfaces, and Router and RouteDisplay forward the shared props to RouteTree as a whole, so a new shared prop cannot be missed in one of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vNbiZGrzNhyfyctwm4NbJ
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
Follow-up to #270: step 2 of its refactoring plan (deduplication), plus shared prop types. No change in behavior or public exports.
Step 1 of the plan (moving interception out of
NavigationAPIAdapter) was tried and dropped. The interceptor still had to share the adapter's state, so the coupling stayed: aninstanceofcheck plus six internal methods on the adapter. All of that saved about 1.3 KB in aRouteDisplay-only bundle.Shared rendering core (
Router/RouteTree.tsx)The new internal
RouteTreecomponent holds what was duplicated betweenRouterandRouteDisplay:browser()checkssr.pathRouterContextvalue and the providers aroundRouteRendererAfter this:
Router=createAdapter(fallback)+useLocationEntry+adapter.setupInterception+RouteTreeRouteDisplay=createDisplayAdapter()+useLocationEntry+RouteTreeShared prop types (
Router/props.ts)RouteTreeSharedPropsdefinesroutes,ssr,trailingSlashandfeaturesonce, each with a single doc comment.SSRConfigandRouterFeaturesmoved to the same file;Router/index.tsxre-exports them, so the public exports are unchanged.RouterProps,RouteDisplayPropsandRouteTreePropsare interfaces that extend it, with no intersection types.Routerpasses the shared props it doesn't use itself straight toRouteTree(...sharedProps), andRouteDisplaypasses all its props. A new shared prop can't be forgotten in one of them.Changes users can see in types and docs:
routesgets a doc comment. Thessrcomment now says "the real URL of the page takes over" so it fits both components.RouterPropsandRouteDisplayPropsare now interfaces. Unlike the old aliases, they can't be assigned to an index-signature type such asRecord<string, unknown>..d.ts: the published types showRouterProps extends RouteTreeSharedProps. The base interface is emitted but not exported.Docs
<RouteDisplay>section of the Components API page now says it assumes nothing else on the page intercepts navigations. If something else does, entry changes still render, but loaders don't re-run on an intercepted reload and the navigationinfoisn't exposed.CLAUDE.mdnow describesRouteTree.Bundle size
Minified with esbuild against
dist/, React excluded: about 12.4 KB for an entry importing onlyRouteDisplayand 13.0 KB for one importing onlyRouter. Both are about 200 B larger than on master because of the extra component.Test plan
pnpm test:run: 371 tests pass, with no test changespnpm typecheck,pnpm lint,pnpm format:check,pnpm --filter @funstack/router buildURLPattern. CI uses Node 24.Generated by Claude Code