Showing preview only (7,793K chars total). Download the full file or copy to clipboard to get everything.
Repository: remix-run/react-router
Branch: main
Commit: 00cb4d7b3106
Files: 1375
Total size: 7.2 MB
Directory structure:
gitextract_wusxnjs2/
├── .browserslistrc
├── .changeset/
│ ├── README.md
│ └── config.json
├── .eslintignore
├── .eslintrc
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ └── documentation_isse.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── close-feature-pr.yml
│ ├── close-no-repro-issue.yml
│ ├── close-no-repro-issues.yml
│ ├── deduplicate-lock-file.yml
│ ├── docs.yml
│ ├── format.yml
│ ├── integration-full.yml
│ ├── integration-pr-ubuntu.yml
│ ├── integration-pr-windows-macos.yml
│ ├── no-response.yml
│ ├── release-comment-manual.yml
│ ├── release.yml
│ ├── shared-build.yml
│ ├── shared-integration.yml
│ ├── support.yml
│ └── test.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── .vscode/
│ └── settings.json
├── AGENTS.md
├── CHANGELOG.md
├── CLA.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DEVELOPMENT.md
├── GOVERNANCE.md
├── LICENSE.md
├── README.md
├── SECURITY.md
├── build.utils.ts
├── contributors.yml
├── decisions/
│ ├── 0001-use-blocker.md
│ ├── 0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md
│ ├── 0002-do-not-clone-request.md
│ ├── 0002-lazy-route-modules.md
│ ├── 0003-data-strategy.md
│ ├── 0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md
│ ├── 0004-streaming-apis.md
│ ├── 0005-remixing-react-router.md
│ ├── 0006-linear-workflow.md
│ ├── 0007-remix-on-react-router-6-4-0.md
│ ├── 0008-only-support-js-conversion-for-app-code.md
│ ├── 0009-do-not-rely-on-treeshaking-for-correctness.md
│ ├── 0010-splitting-up-client-and-server-code-in-vite.md
│ ├── 0011-routes-ts.md
│ ├── 0012-type-inference.md
│ ├── 0013-react-router-config-ts.md
│ ├── 0014-context-middleware.md
│ ├── 0015-observability.md
│ └── template.md
├── docs/
│ ├── api/
│ │ ├── components/
│ │ │ ├── Await.md
│ │ │ ├── Form.md
│ │ │ ├── Link.md
│ │ │ ├── Links.md
│ │ │ ├── Meta.md
│ │ │ ├── NavLink.md
│ │ │ ├── Navigate.md
│ │ │ ├── Outlet.md
│ │ │ ├── PrefetchPageLinks.md
│ │ │ ├── Route.md
│ │ │ ├── Routes.md
│ │ │ ├── Scripts.md
│ │ │ ├── ScrollRestoration.md
│ │ │ └── index.md
│ │ ├── data-routers/
│ │ │ ├── RouterProvider.md
│ │ │ ├── StaticRouterProvider.md
│ │ │ ├── createBrowserRouter.md
│ │ │ ├── createHashRouter.md
│ │ │ ├── createMemoryRouter.md
│ │ │ ├── createStaticHandler.md
│ │ │ ├── createStaticRouter.md
│ │ │ └── index.md
│ │ ├── declarative-routers/
│ │ │ ├── BrowserRouter.md
│ │ │ ├── HashRouter.md
│ │ │ ├── HistoryRouter.md
│ │ │ ├── MemoryRouter.md
│ │ │ ├── Router.md
│ │ │ ├── StaticRouter.md
│ │ │ └── index.md
│ │ ├── framework-conventions/
│ │ │ ├── client-modules.md
│ │ │ ├── entry.client.tsx.md
│ │ │ ├── entry.server.tsx.md
│ │ │ ├── index.md
│ │ │ ├── react-router.config.ts.md
│ │ │ ├── root.tsx.md
│ │ │ ├── routes.ts.md
│ │ │ └── server-modules.md
│ │ ├── framework-routers/
│ │ │ ├── HydratedRouter.md
│ │ │ ├── ServerRouter.md
│ │ │ └── index.md
│ │ ├── hooks/
│ │ │ ├── index.md
│ │ │ ├── useActionData.md
│ │ │ ├── useAsyncError.md
│ │ │ ├── useAsyncValue.md
│ │ │ ├── useBeforeUnload.md
│ │ │ ├── useBlocker.md
│ │ │ ├── useFetcher.md
│ │ │ ├── useFetchers.md
│ │ │ ├── useFormAction.md
│ │ │ ├── useHref.md
│ │ │ ├── useInRouterContext.md
│ │ │ ├── useLinkClickHandler.md
│ │ │ ├── useLoaderData.md
│ │ │ ├── useLocation.md
│ │ │ ├── useMatch.md
│ │ │ ├── useMatches.md
│ │ │ ├── useNavigate.md
│ │ │ ├── useNavigation.md
│ │ │ ├── useNavigationType.md
│ │ │ ├── useOutlet.md
│ │ │ ├── useOutletContext.md
│ │ │ ├── useParams.md
│ │ │ ├── usePrompt.md
│ │ │ ├── useResolvedPath.md
│ │ │ ├── useRevalidator.md
│ │ │ ├── useRouteError.md
│ │ │ ├── useRouteLoaderData.md
│ │ │ ├── useRoutes.md
│ │ │ ├── useSearchParams.md
│ │ │ ├── useSubmit.md
│ │ │ └── useViewTransitionState.md
│ │ ├── index.md
│ │ ├── other-api/
│ │ │ ├── adapter.md
│ │ │ ├── dev.md
│ │ │ ├── index.md
│ │ │ └── serve.md
│ │ ├── rsc/
│ │ │ ├── RSCHydratedRouter.md
│ │ │ ├── RSCStaticRouter.md
│ │ │ ├── createCallServer.md
│ │ │ ├── getRSCStream.md
│ │ │ ├── index.md
│ │ │ ├── matchRSCServerRequest.md
│ │ │ └── routeRSCServerRequest.md
│ │ └── utils/
│ │ ├── IsCookieFunction.md
│ │ ├── IsSessionFunction.md
│ │ ├── RouterContextProvider.md
│ │ ├── createContext.md
│ │ ├── createCookie.md
│ │ ├── createCookieSessionStorage.md
│ │ ├── createMemorySessionStorage.md
│ │ ├── createPath.md
│ │ ├── createRequestHandler.md
│ │ ├── createRoutesFromElements.md
│ │ ├── createRoutesStub.md
│ │ ├── createSearchParams.md
│ │ ├── createSession.md
│ │ ├── createSessionStorage.md
│ │ ├── data.md
│ │ ├── generatePath.md
│ │ ├── href.md
│ │ ├── index.md
│ │ ├── isCookie.md
│ │ ├── isRouteErrorResponse.md
│ │ ├── isSession.md
│ │ ├── matchPath.md
│ │ ├── matchRoutes.md
│ │ ├── parsePath.md
│ │ ├── redirect.md
│ │ ├── redirectDocument.md
│ │ ├── renderMatches.md
│ │ ├── replace.md
│ │ └── resolvePath.md
│ ├── community/
│ │ ├── api-development-strategy.md
│ │ ├── contributing.md
│ │ └── index.md
│ ├── elements.md
│ ├── explanation/
│ │ ├── README
│ │ ├── backend-for-frontend.md
│ │ ├── code-splitting.md
│ │ ├── concurrency.md
│ │ ├── form-vs-fetcher.md
│ │ ├── hot-module-replacement.md
│ │ ├── hydration.md
│ │ ├── index-query-param.md
│ │ ├── index.md
│ │ ├── lazy-route-discovery.md
│ │ ├── location.md
│ │ ├── progressive-enhancement.md
│ │ ├── race-conditions.md
│ │ ├── react-transitions.md
│ │ ├── route-matching.md
│ │ ├── server-client-execution.md
│ │ ├── sessions-and-cookies.md
│ │ ├── special-files.md
│ │ ├── state-management.md
│ │ └── type-safety.md
│ ├── how-to/
│ │ ├── README
│ │ ├── accessibility.md
│ │ ├── client-data.md
│ │ ├── data-strategy.md
│ │ ├── error-boundary.md
│ │ ├── error-reporting.md
│ │ ├── fetchers.md
│ │ ├── file-route-conventions.md
│ │ ├── file-uploads.md
│ │ ├── form-validation.md
│ │ ├── headers.md
│ │ ├── index.md
│ │ ├── instrumentation.md
│ │ ├── meta.md
│ │ ├── middleware.md
│ │ ├── navigation-blocking.md
│ │ ├── optimize-revalidation.md
│ │ ├── pre-rendering.md
│ │ ├── presets.md
│ │ ├── react-server-components.md
│ │ ├── resource-routes.md
│ │ ├── route-module-type-safety.md
│ │ ├── search-params.md
│ │ ├── security.md
│ │ ├── server-bundles.md
│ │ ├── spa.md
│ │ ├── status.md
│ │ ├── suspense.md
│ │ ├── using-handle.md
│ │ ├── view-transitions.md
│ │ └── webhook.md
│ ├── index.md
│ ├── prettier.config.js
│ ├── start/
│ │ ├── README
│ │ ├── data/
│ │ │ ├── actions.md
│ │ │ ├── custom.md
│ │ │ ├── data-loading.md
│ │ │ ├── index.md
│ │ │ ├── installation.md
│ │ │ ├── navigating.md
│ │ │ ├── pending-ui.md
│ │ │ ├── route-object.md
│ │ │ ├── routing.md
│ │ │ └── testing.md
│ │ ├── declarative/
│ │ │ ├── index.md
│ │ │ ├── installation.md
│ │ │ ├── navigating.md
│ │ │ ├── routing.md
│ │ │ └── url-values.md
│ │ ├── framework/
│ │ │ ├── actions.md
│ │ │ ├── data-loading.md
│ │ │ ├── deploying.md
│ │ │ ├── index.md
│ │ │ ├── installation.md
│ │ │ ├── navigating.md
│ │ │ ├── pending-ui.md
│ │ │ ├── rendering.md
│ │ │ ├── route-module.md
│ │ │ ├── routing.md
│ │ │ └── testing.md
│ │ ├── index.md
│ │ └── modes.md
│ ├── tutorials/
│ │ ├── README
│ │ ├── address-book.md
│ │ ├── advanced-data-fetching.md
│ │ ├── index.md
│ │ └── quickstart.md
│ └── upgrading/
│ ├── README
│ ├── component-routes.md
│ ├── future.md
│ ├── index.md
│ ├── remix.md
│ ├── router-provider.md
│ └── v6.md
├── examples/
│ ├── README.md
│ ├── auth/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── auth.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── auth-router-provider/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── auth.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── basic/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── basic-data-router/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── custom-filter-link/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── snkrs.ts
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── custom-link/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── custom-query-parsing/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ ├── types/
│ │ │ └── jsurl.d.ts
│ │ └── vite.config.ts
│ ├── data-router/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── todos.ts
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── error-boundaries/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── routes.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── lazy-loading/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── pages/
│ │ │ │ ├── About.tsx
│ │ │ │ └── Dashboard.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── lazy-loading-router-provider/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── pages/
│ │ │ │ ├── About.tsx
│ │ │ │ └── Dashboard.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── modal/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── images.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── modal-data-router/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── images.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── modal-route-with-outlet/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── images.ts
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── multi-app/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── home/
│ │ │ ├── App.jsx
│ │ │ ├── index.css
│ │ │ ├── main.jsx
│ │ │ └── no-match.jsx
│ │ ├── inbox/
│ │ │ ├── App.jsx
│ │ │ ├── index.css
│ │ │ ├── index.html
│ │ │ ├── main.jsx
│ │ │ ├── messages.js
│ │ │ └── no-match.jsx
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── server.js
│ │ └── vite.config.js
│ ├── navigation-blocking/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.tsx
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── notes/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.jsx
│ │ │ ├── index.css
│ │ │ ├── main.jsx
│ │ │ ├── notes.js
│ │ │ ├── routes/
│ │ │ │ ├── new.jsx
│ │ │ │ ├── note.jsx
│ │ │ │ ├── notes.jsx
│ │ │ │ └── root.jsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── route-objects/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── scroll-restoration/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── app.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── search-params/
│ │ ├── .gitignore
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── ssr/
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── server.js
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── entry.client.tsx
│ │ │ ├── entry.server.tsx
│ │ │ ├── index.css
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.js
│ ├── ssr-data-router/
│ │ ├── .stackblitzrc
│ │ ├── README.md
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── server.js
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── entry.client.tsx
│ │ │ ├── entry.server.tsx
│ │ │ ├── index.css
│ │ │ ├── lazy.tsx
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.js
│ └── view-transitions/
│ ├── .gitignore
│ ├── .stackblitzrc
│ ├── README.md
│ ├── index.html
│ ├── package.json
│ ├── src/
│ │ ├── index.css
│ │ ├── main.tsx
│ │ └── vite-env.d.ts
│ ├── tsconfig.json
│ └── vite.config.ts
├── integration/
│ ├── CHANGELOG.md
│ ├── abort-signal-test.ts
│ ├── action-test.ts
│ ├── assets/
│ │ ├── toupload.txt
│ │ └── touploadtoobig.txt
│ ├── blocking-test.ts
│ ├── browser-entry-test.ts
│ ├── bug-report-test.ts
│ ├── catch-boundary-data-test.ts
│ ├── catch-boundary-test.ts
│ ├── cli-test.ts
│ ├── client-data-test.ts
│ ├── custom-entry-server-test.ts
│ ├── deduped-route-modules-test.ts
│ ├── defer-loader-test.ts
│ ├── defer-test.ts
│ ├── error-boundary-test.ts
│ ├── error-boundary-v2-test.ts
│ ├── error-data-request-test.ts
│ ├── error-sanitization-test.ts
│ ├── fetch-globals-test.ts
│ ├── fetcher-layout-test.ts
│ ├── fetcher-test.ts
│ ├── fog-of-war-test.ts
│ ├── form-data-test.ts
│ ├── form-test.ts
│ ├── fs-routes-test.ts
│ ├── headers-test.ts
│ ├── helpers/
│ │ ├── cleanup.mjs
│ │ ├── cloudflare-dev-proxy-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── entry.server.tsx
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── create-fixture.ts
│ │ ├── express.ts
│ │ ├── fixtures.ts
│ │ ├── playwright-fixture.ts
│ │ ├── rsc-vite/
│ │ │ ├── .gitignore
│ │ │ ├── package.json
│ │ │ ├── server.js
│ │ │ ├── src/
│ │ │ │ ├── config/
│ │ │ │ │ ├── basename.ts
│ │ │ │ │ ├── get-context.ts
│ │ │ │ │ └── request-context.ts
│ │ │ │ ├── entry.browser.tsx
│ │ │ │ ├── entry.rsc.tsx
│ │ │ │ ├── entry.ssr.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ ├── home.tsx
│ │ │ │ │ └── root.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── rsc-vite-framework/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── package.json
│ │ │ ├── start.js
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── stream.ts
│ │ ├── templates.ts
│ │ ├── vite-5-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── env.d.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── vite-6-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── env.d.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── vite-7-beta-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── env.d.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ ├── vite-plugin-cloudflare-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── entry.server.tsx
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── package.json
│ │ │ ├── react-router.config.ts
│ │ │ ├── tsconfig.cloudflare.json
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.node.json
│ │ │ ├── vite.config.ts
│ │ │ ├── workers/
│ │ │ │ └── app.ts
│ │ │ └── wrangler.toml
│ │ ├── vite-rolldown-template/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── root.tsx
│ │ │ │ ├── routes/
│ │ │ │ │ └── _index.tsx
│ │ │ │ └── routes.ts
│ │ │ ├── env.d.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.json
│ │ │ └── vite.config.ts
│ │ └── vite.ts
│ ├── hook-useSubmit-test.ts
│ ├── http-test.ts
│ ├── layout-route-test.ts
│ ├── link-test.ts
│ ├── loader-test.ts
│ ├── matches-test.ts
│ ├── mdx-test.ts
│ ├── middleware-test.ts
│ ├── multiple-cookies-test.ts
│ ├── navigation-state-test.ts
│ ├── package.json
│ ├── playwright.config.ts
│ ├── prefetch-test.ts
│ ├── react-router-serve-test.ts
│ ├── redirects-test.ts
│ ├── rendering-test.ts
│ ├── request-test.ts
│ ├── resource-routes-test.ts
│ ├── revalidate-test.ts
│ ├── root-route-test.ts
│ ├── route-collisions-test.ts
│ ├── route-config-test.ts
│ ├── rsc/
│ │ ├── rsc-nojs-test.ts
│ │ ├── rsc-test.ts
│ │ └── utils.ts
│ ├── scroll-test.ts
│ ├── server-entry-test.ts
│ ├── session-storage-denied-test.ts
│ ├── set-cookie-revalidation-test.ts
│ ├── single-fetch-test.ts
│ ├── splat-routes-test.ts
│ ├── split-route-modules-test.ts
│ ├── sri-test.ts
│ ├── transition-test.ts
│ ├── tsconfig.json
│ ├── typegen-test.ts
│ ├── use-route-test.ts
│ ├── vite-absolute-base-test.ts
│ ├── vite-basename-test.ts
│ ├── vite-build-test.ts
│ ├── vite-cloudflare-test.ts
│ ├── vite-css-lazy-loading-test.ts
│ ├── vite-css-test.ts
│ ├── vite-dev-custom-entry-test.ts
│ ├── vite-dev-test.ts
│ ├── vite-dot-client-test.ts
│ ├── vite-dot-server-test.ts
│ ├── vite-dotenv-test.ts
│ ├── vite-hmr-hdr-rsc-test.ts
│ ├── vite-hmr-hdr-test.ts
│ ├── vite-loader-context-test.ts
│ ├── vite-manifests-test.ts
│ ├── vite-node-env-test.ts
│ ├── vite-plugin-cloudflare-test.ts
│ ├── vite-plugin-order-validation-test.ts
│ ├── vite-prerender-test.ts
│ ├── vite-presets-test.ts
│ ├── vite-preview-test.ts
│ ├── vite-route-added-test.ts
│ ├── vite-route-exports-modified-offscreen-test.ts
│ ├── vite-server-bundles-test.ts
│ ├── vite-server-fs-allow-test.ts
│ ├── vite-spa-mode-test.ts
│ └── vite-unused-route-exports-test.ts
├── jest/
│ ├── jest.config.shared.js
│ └── transform.js
├── package.json
├── packages/
│ ├── create-react-router/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── create-react-router-test.ts
│ │ │ ├── fixtures/
│ │ │ │ ├── basic/
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── app/
│ │ │ │ │ │ ├── root.tsx
│ │ │ │ │ │ ├── routes/
│ │ │ │ │ │ │ └── home.tsx
│ │ │ │ │ │ └── routes.ts
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── tsconfig.json
│ │ │ │ │ └── vite.config.ts
│ │ │ │ ├── blank/
│ │ │ │ │ └── package.json
│ │ │ │ ├── template.tgz
│ │ │ │ └── with-ignored-dir/
│ │ │ │ └── package.json
│ │ │ ├── github-mocks.ts
│ │ │ ├── msw-register.ts
│ │ │ ├── msw.ts
│ │ │ └── setupAfterEnv.ts
│ │ ├── cli.ts
│ │ ├── copy-template.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── loading-indicator.ts
│ │ ├── package.json
│ │ ├── prompt.ts
│ │ ├── prompts-confirm.ts
│ │ ├── prompts-multi-select.ts
│ │ ├── prompts-prompt-base.ts
│ │ ├── prompts-select.ts
│ │ ├── prompts-text.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── utils.ts
│ ├── react-router/
│ │ ├── .eslintrc.js
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── .eslintrc
│ │ │ ├── Route-test.tsx
│ │ │ ├── Router-basename-test.tsx
│ │ │ ├── Router-test.tsx
│ │ │ ├── Routes-location-test.tsx
│ │ │ ├── Routes-test.tsx
│ │ │ ├── __snapshots__/
│ │ │ │ └── route-matching-test.tsx.snap
│ │ │ ├── absolute-path-matching-test.tsx
│ │ │ ├── createRoutesFromChildren-test.tsx
│ │ │ ├── data-memory-router-test.tsx
│ │ │ ├── data-router-no-dom-test.tsx
│ │ │ ├── descendant-routes-params-test.tsx
│ │ │ ├── descendant-routes-splat-matching-test.tsx
│ │ │ ├── descendant-routes-warning-test.tsx
│ │ │ ├── dom/
│ │ │ │ ├── client-on-error-test.tsx
│ │ │ │ ├── components/
│ │ │ │ │ └── LazyComponent.tsx
│ │ │ │ ├── concurrent-mode-navigations-test.tsx
│ │ │ │ ├── data-browser-router-legacy-formdata-test.tsx
│ │ │ │ ├── data-browser-router-test.tsx
│ │ │ │ ├── data-static-router-test.tsx
│ │ │ │ ├── dom-export-test.tsx
│ │ │ │ ├── fetcher-submit-tagname-test.tsx
│ │ │ │ ├── flush-sync-navigations-test.tsx
│ │ │ │ ├── link-click-test.tsx
│ │ │ │ ├── link-href-test.tsx
│ │ │ │ ├── link-push-test.tsx
│ │ │ │ ├── nav-link-active-test.tsx
│ │ │ │ ├── navigate-encode-params-test.tsx
│ │ │ │ ├── partial-hydration-test.tsx
│ │ │ │ ├── polyfills/
│ │ │ │ │ └── drop-FormData-submitter.ts
│ │ │ │ ├── scroll-restoration-test.tsx
│ │ │ │ ├── search-params-test.tsx
│ │ │ │ ├── special-characters-test.tsx
│ │ │ │ ├── ssr/
│ │ │ │ │ ├── components-test.tsx
│ │ │ │ │ ├── links-test.tsx
│ │ │ │ │ └── meta-test.tsx
│ │ │ │ ├── static-link-test.tsx
│ │ │ │ ├── static-location-test.tsx
│ │ │ │ ├── static-navigate-test.tsx
│ │ │ │ ├── stub-test.tsx
│ │ │ │ ├── trailing-slashes-test.tsx
│ │ │ │ ├── use-blocker-test.tsx
│ │ │ │ ├── use-prompt-test.tsx
│ │ │ │ └── useLinkClickHandler-test.tsx
│ │ │ ├── generatePath-test.tsx
│ │ │ ├── gh-issue-8127-test.tsx
│ │ │ ├── gh-issue-8165-test.tsx
│ │ │ ├── greedy-matching-test.tsx
│ │ │ ├── href-test.ts
│ │ │ ├── index-routes-test.tsx
│ │ │ ├── layout-routes-test.tsx
│ │ │ ├── matchPath-test.tsx
│ │ │ ├── matchRoutes-test.tsx
│ │ │ ├── navigate-test.tsx
│ │ │ ├── params-decode-test.tsx
│ │ │ ├── path-matching-test.tsx
│ │ │ ├── react-transitions-test.tsx
│ │ │ ├── resolvePath-test.tsx
│ │ │ ├── route-depth-order-matching-test.tsx
│ │ │ ├── route-matching-test.tsx
│ │ │ ├── router/
│ │ │ │ ├── TestSequences/
│ │ │ │ │ ├── EncodedReservedCharacters.ts
│ │ │ │ │ ├── GoBack.ts
│ │ │ │ │ ├── GoForward.ts
│ │ │ │ │ ├── InitialLocationDefaultKey.ts
│ │ │ │ │ ├── InitialLocationHasKey.ts
│ │ │ │ │ ├── Listen.ts
│ │ │ │ │ ├── ListenPopOnly.ts
│ │ │ │ │ ├── PushMissingPathname.ts
│ │ │ │ │ ├── PushNewLocation.ts
│ │ │ │ │ ├── PushRelativePathname.ts
│ │ │ │ │ ├── PushRelativePathnameWarning.ts
│ │ │ │ │ ├── PushSamePath.ts
│ │ │ │ │ ├── PushState.ts
│ │ │ │ │ ├── PushStateInvalid.ts
│ │ │ │ │ ├── ReplaceNewLocation.ts
│ │ │ │ │ ├── ReplaceSamePath.ts
│ │ │ │ │ └── ReplaceState.ts
│ │ │ │ ├── browser-test.ts
│ │ │ │ ├── context-middleware-test.tsx
│ │ │ │ ├── create-path-test.ts
│ │ │ │ ├── data-strategy-test.ts
│ │ │ │ ├── fetchers-test.ts
│ │ │ │ ├── flush-sync-test.ts
│ │ │ │ ├── hash-base-test.ts
│ │ │ │ ├── hash-test.ts
│ │ │ │ ├── instrumentation-test.ts
│ │ │ │ ├── interruptions-test.ts
│ │ │ │ ├── lazy-discovery-test.ts
│ │ │ │ ├── lazy-test.ts
│ │ │ │ ├── mask-test.ts
│ │ │ │ ├── memory-test.ts
│ │ │ │ ├── navigation-blocking-test.ts
│ │ │ │ ├── navigation-test.ts
│ │ │ │ ├── path-resolution-test.ts
│ │ │ │ ├── redirects-test.ts
│ │ │ │ ├── resolveTo-test.tsx
│ │ │ │ ├── revalidate-test.ts
│ │ │ │ ├── route-fallback-test.ts
│ │ │ │ ├── router-memory-test.ts
│ │ │ │ ├── router-test.ts
│ │ │ │ ├── scroll-restoration-test.ts
│ │ │ │ ├── should-revalidate-test.ts
│ │ │ │ ├── ssr-test.ts
│ │ │ │ ├── submission-test.ts
│ │ │ │ ├── utils/
│ │ │ │ │ ├── custom-matchers.ts
│ │ │ │ │ ├── data-router-setup.ts
│ │ │ │ │ ├── urlDataStrategy.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ └── view-transition-test.ts
│ │ │ ├── same-component-lifecycle-test.tsx
│ │ │ ├── server-runtime/
│ │ │ │ ├── actions-test.ts
│ │ │ │ ├── cookies-test.ts
│ │ │ │ ├── data-test.ts
│ │ │ │ ├── handle-error-test.ts
│ │ │ │ ├── handler-test.ts
│ │ │ │ ├── markup-test.ts
│ │ │ │ ├── responses-test.ts
│ │ │ │ ├── server-test.ts
│ │ │ │ ├── sessions-test.ts
│ │ │ │ └── utils.ts
│ │ │ ├── setup.ts
│ │ │ ├── use-revalidator-test.tsx
│ │ │ ├── useHref-basename-test.tsx
│ │ │ ├── useHref-test.tsx
│ │ │ ├── useLocation-test.tsx
│ │ │ ├── useMatch-test.tsx
│ │ │ ├── useNavigate-test.tsx
│ │ │ ├── useOutlet-test.tsx
│ │ │ ├── useParams-test.tsx
│ │ │ ├── useResolvedPath-test.tsx
│ │ │ ├── useRoutes-test.tsx
│ │ │ ├── utils/
│ │ │ │ ├── MemoryNavigate.tsx
│ │ │ │ ├── framework.ts
│ │ │ │ ├── getHtml.ts
│ │ │ │ ├── getWindow.ts
│ │ │ │ ├── renderStrict.tsx
│ │ │ │ ├── tick.ts
│ │ │ │ └── waitForRedirect.tsx
│ │ │ └── vendor/
│ │ │ └── turbo-stream-test.ts
│ │ ├── dom-export.ts
│ │ ├── index-react-server-client.ts
│ │ ├── index-react-server.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── actions.ts
│ │ │ ├── components.tsx
│ │ │ ├── context.ts
│ │ │ ├── dom/
│ │ │ │ ├── dom.ts
│ │ │ │ ├── global.ts
│ │ │ │ ├── lib.tsx
│ │ │ │ ├── node-main.js
│ │ │ │ ├── server.tsx
│ │ │ │ └── ssr/
│ │ │ │ ├── components.tsx
│ │ │ │ ├── data.ts
│ │ │ │ ├── entry.ts
│ │ │ │ ├── errorBoundaries.tsx
│ │ │ │ ├── errors.ts
│ │ │ │ ├── fallback.tsx
│ │ │ │ ├── fog-of-war.ts
│ │ │ │ ├── hydration.tsx
│ │ │ │ ├── invariant.ts
│ │ │ │ ├── links.ts
│ │ │ │ ├── markup.ts
│ │ │ │ ├── routeModules.ts
│ │ │ │ ├── routes-test-stub.tsx
│ │ │ │ ├── routes.tsx
│ │ │ │ ├── server.tsx
│ │ │ │ └── single-fetch.tsx
│ │ │ ├── dom-export/
│ │ │ │ ├── dom-router-provider.tsx
│ │ │ │ └── hydrated-router.tsx
│ │ │ ├── errors.ts
│ │ │ ├── hooks.tsx
│ │ │ ├── href.ts
│ │ │ ├── router/
│ │ │ │ ├── history.ts
│ │ │ │ ├── instrumentation.ts
│ │ │ │ ├── links.ts
│ │ │ │ ├── router.ts
│ │ │ │ └── utils.ts
│ │ │ ├── rsc/
│ │ │ │ ├── browser.tsx
│ │ │ │ ├── errorBoundaries.tsx
│ │ │ │ ├── html-stream/
│ │ │ │ │ ├── browser.ts
│ │ │ │ │ └── server.ts
│ │ │ │ ├── route-modules.ts
│ │ │ │ ├── server.rsc.ts
│ │ │ │ └── server.ssr.tsx
│ │ │ ├── server-runtime/
│ │ │ │ ├── .eslintrc.js
│ │ │ │ ├── build.ts
│ │ │ │ ├── cookies.ts
│ │ │ │ ├── crypto.ts
│ │ │ │ ├── data.ts
│ │ │ │ ├── dev.ts
│ │ │ │ ├── entry.ts
│ │ │ │ ├── errors.ts
│ │ │ │ ├── headers.ts
│ │ │ │ ├── invariant.ts
│ │ │ │ ├── mode.ts
│ │ │ │ ├── routeMatching.ts
│ │ │ │ ├── routes.ts
│ │ │ │ ├── server.ts
│ │ │ │ ├── serverHandoff.ts
│ │ │ │ ├── sessions/
│ │ │ │ │ ├── cookieStorage.ts
│ │ │ │ │ └── memoryStorage.ts
│ │ │ │ ├── sessions.ts
│ │ │ │ ├── single-fetch.ts
│ │ │ │ └── warnings.ts
│ │ │ └── types/
│ │ │ ├── future.ts
│ │ │ ├── internal.ts
│ │ │ ├── params.ts
│ │ │ ├── register.ts
│ │ │ ├── route-data.ts
│ │ │ ├── route-module-annotations.ts
│ │ │ ├── route-module.ts
│ │ │ ├── serializes-to.ts
│ │ │ └── utils.ts
│ │ ├── node-main-dom-export.js
│ │ ├── node-main.js
│ │ ├── package.json
│ │ ├── tsconfig.dom.json
│ │ ├── tsconfig.json
│ │ ├── tsup.config.rsc.ts
│ │ ├── tsup.config.ts
│ │ ├── typedoc.mjs
│ │ └── vendor/
│ │ └── turbo-stream-v2/
│ │ ├── flatten.ts
│ │ ├── turbo-stream.ts
│ │ ├── unflatten.ts
│ │ └── utils.ts
│ ├── react-router-architect/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── binaryTypes-test.ts
│ │ │ └── server-test.ts
│ │ ├── binaryTypes.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── server.ts
│ │ ├── sessions/
│ │ │ └── arcTableSessionStorage.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── typedoc.mjs
│ ├── react-router-cloudflare/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── sessions/
│ │ │ └── workersKVStorage.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ ├── typedoc.mjs
│ │ └── worker.ts
│ ├── react-router-dev/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── fixtures/
│ │ │ │ └── basic/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── app/
│ │ │ │ │ ├── root.tsx
│ │ │ │ │ ├── routes/
│ │ │ │ │ │ └── _index.tsx
│ │ │ │ │ └── routes.ts
│ │ │ │ ├── package.json
│ │ │ │ └── tsconfig.json
│ │ │ ├── route-config-test.ts
│ │ │ ├── setupAfterEnv.ts
│ │ │ ├── styles-test.ts
│ │ │ └── utils/
│ │ │ ├── captureError.ts
│ │ │ ├── cli.ts
│ │ │ ├── eol.ts
│ │ │ ├── git.ts
│ │ │ └── withApp.ts
│ │ ├── bin.js
│ │ ├── cli/
│ │ │ ├── commands.ts
│ │ │ ├── detectPackageManager.ts
│ │ │ ├── index.ts
│ │ │ ├── run.ts
│ │ │ └── useJavascript.ts
│ │ ├── config/
│ │ │ ├── config.ts
│ │ │ ├── default-rsc-entries/
│ │ │ │ ├── entry.client.tsx
│ │ │ │ ├── entry.rsc.tsx
│ │ │ │ └── entry.ssr.tsx
│ │ │ ├── defaults/
│ │ │ │ ├── entry.client.tsx
│ │ │ │ └── entry.server.node.tsx
│ │ │ ├── format.ts
│ │ │ ├── is-react-router-repo.ts
│ │ │ └── routes.ts
│ │ ├── config.ts
│ │ ├── invariant.ts
│ │ ├── jest.config.js
│ │ ├── manifest.ts
│ │ ├── module-sync-enabled/
│ │ │ ├── false.cjs
│ │ │ ├── index.d.mts
│ │ │ ├── index.mjs
│ │ │ └── true.mjs
│ │ ├── package.json
│ │ ├── routes.ts
│ │ ├── rsc-types.d.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ ├── typedoc.mjs
│ │ ├── typegen/
│ │ │ ├── context.ts
│ │ │ ├── generate.ts
│ │ │ ├── index.ts
│ │ │ ├── params.ts
│ │ │ └── route.ts
│ │ ├── vite/
│ │ │ ├── babel.ts
│ │ │ ├── build.ts
│ │ │ ├── cache.ts
│ │ │ ├── cloudflare-dev-proxy.ts
│ │ │ ├── cloudflare.ts
│ │ │ ├── combine-urls-test.ts
│ │ │ ├── combine-urls.ts
│ │ │ ├── dev.ts
│ │ │ ├── has-dependency.ts
│ │ │ ├── has-rsc-plugin.ts
│ │ │ ├── load-dotenv.ts
│ │ │ ├── node-adapter.ts
│ │ │ ├── optimize-deps-entries.ts
│ │ │ ├── plugin.ts
│ │ │ ├── plugins/
│ │ │ │ ├── prerender.ts
│ │ │ │ ├── validate-plugin-order.ts
│ │ │ │ └── warn-on-client-source-maps.ts
│ │ │ ├── profiler.ts
│ │ │ ├── remove-exports-test.ts
│ │ │ ├── remove-exports.ts
│ │ │ ├── resolve-file-url.ts
│ │ │ ├── resolve-relative-route-file-path.ts
│ │ │ ├── route-chunks-test.ts
│ │ │ ├── route-chunks.ts
│ │ │ ├── rsc/
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── virtual-route-config.ts
│ │ │ │ └── virtual-route-modules.ts
│ │ │ ├── ssr-externals.ts
│ │ │ ├── static/
│ │ │ │ ├── refresh-utils.mjs
│ │ │ │ └── rsc-refresh-utils.mjs
│ │ │ ├── styles.ts
│ │ │ ├── virtual-module.ts
│ │ │ ├── vite-node.ts
│ │ │ ├── vite.ts
│ │ │ └── with-props.ts
│ │ └── vite.ts
│ ├── react-router-dom/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── react-router-express/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ └── server-test.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── server.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── typedoc.mjs
│ ├── react-router-fs-routes/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── flatRoutes-test.ts
│ │ │ └── routeManifestToRouteConfig-test.ts
│ │ ├── flatRoutes.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── manifest.ts
│ │ ├── normalizeSlashes.ts
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── typedoc.mjs
│ ├── react-router-node/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ └── sessions-test.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── server.ts
│ │ ├── sessions/
│ │ │ └── fileStorage.ts
│ │ ├── stream.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── typedoc.mjs
│ ├── react-router-remix-routes-option-adapter/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── defineRoutes-test.ts
│ │ │ └── routeManifestToRouteConfig-test.ts
│ │ ├── defineRoutes.ts
│ │ ├── index.ts
│ │ ├── jest.config.js
│ │ ├── manifest.ts
│ │ ├── normalizeSlashes.ts
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── typedoc.mjs
│ └── react-router-serve/
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── bin.js
│ ├── cli.ts
│ ├── package.json
│ ├── tsconfig.json
│ ├── tsup.config.ts
│ └── typedoc.mjs
├── patches/
│ ├── @changesets__assemble-release-plan.patch
│ ├── @changesets__get-dependents-graph@1.3.6.patch
│ └── @mdx-js__rollup.patch
├── playground/
│ ├── data/
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── main.tsx
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── $.tsx
│ │ │ │ ├── _index.tsx
│ │ │ │ └── product.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework-express/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ └── _index.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── server.js
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework-rolldown-vite/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ └── product.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework-spa/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ └── _index.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework-vite-5/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ └── product.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── framework-vite-7-beta/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ └── product.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── middleware/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── contexts.ts
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ ├── client.a.b.tsx
│ │ │ │ ├── client.a.tsx
│ │ │ │ ├── server.a.b.tsx
│ │ │ │ └── server.a.tsx
│ │ │ └── routes.ts
│ │ ├── dev-server.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── server.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.node.json
│ │ ├── tsconfig.vite.json
│ │ └── vite.config.ts
│ ├── rsc-vite/
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── server.js
│ │ ├── src/
│ │ │ ├── counter.tsx
│ │ │ ├── entry.browser.tsx
│ │ │ ├── entry.rsc.tsx
│ │ │ ├── entry.ssr.tsx
│ │ │ ├── routes/
│ │ │ │ ├── about/
│ │ │ │ │ ├── about.client.tsx
│ │ │ │ │ └── about.tsx
│ │ │ │ ├── child/
│ │ │ │ │ └── child.tsx
│ │ │ │ ├── home/
│ │ │ │ │ ├── home.client.css
│ │ │ │ │ ├── home.client.tsx
│ │ │ │ │ ├── home.css
│ │ │ │ │ └── home.tsx
│ │ │ │ ├── parent/
│ │ │ │ │ └── parent.tsx
│ │ │ │ ├── parent-index/
│ │ │ │ │ └── parent-index.tsx
│ │ │ │ ├── redirect.ts
│ │ │ │ ├── render-redirects.tsx
│ │ │ │ └── root/
│ │ │ │ ├── root.client.tsx
│ │ │ │ ├── root.css
│ │ │ │ └── root.tsx
│ │ │ └── routes.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── rsc-vite-framework/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── entry.rsc.ts
│ │ │ ├── entry.ssr.ts
│ │ │ ├── root.css
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index/
│ │ │ │ │ ├── actions.ts
│ │ │ │ │ ├── route.tsx
│ │ │ │ │ └── styles.css
│ │ │ │ ├── _layout-a.route-a.tsx
│ │ │ │ ├── _layout-a.tsx
│ │ │ │ ├── _layout-b.route-b.tsx
│ │ │ │ ├── _layout-b.tsx
│ │ │ │ ├── client-loader/
│ │ │ │ │ ├── route.tsx
│ │ │ │ │ └── styles.module.css
│ │ │ │ ├── client-loader-hydrate/
│ │ │ │ │ ├── route.tsx
│ │ │ │ │ └── styles.module.css
│ │ │ │ ├── client-loader-without-server-loader/
│ │ │ │ │ ├── route.tsx
│ │ │ │ │ └── styles.module.css
│ │ │ │ ├── fixture.client-component/
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── fixture.server-component/
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── mdx/
│ │ │ │ │ ├── message.tsx
│ │ │ │ │ └── route.mdx
│ │ │ │ ├── mdx-glob.$post/
│ │ │ │ │ ├── posts/
│ │ │ │ │ │ ├── hello/
│ │ │ │ │ │ │ ├── hello-component.module.css
│ │ │ │ │ │ │ ├── hello-component.tsx
│ │ │ │ │ │ │ └── hello.mdx
│ │ │ │ │ │ ├── posts.ts
│ │ │ │ │ │ └── world/
│ │ │ │ │ │ ├── world-component.module.css
│ │ │ │ │ │ ├── world-component.tsx
│ │ │ │ │ │ └── world.mdx
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── mdx-glob._index/
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── optimistic/
│ │ │ │ │ ├── actions.ts
│ │ │ │ │ ├── form.tsx
│ │ │ │ │ ├── liked.ts
│ │ │ │ │ └── route.tsx
│ │ │ │ └── server-loader/
│ │ │ │ ├── route.tsx
│ │ │ │ └── styles.module.css
│ │ │ └── routes.ts
│ │ ├── mdx.d.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── start-vite-middleware.js
│ │ ├── start.js
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── split-route-modules/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ ├── semi-splittable.tsx
│ │ │ │ ├── splittable.tsx
│ │ │ │ └── unsplittable.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── split-route-modules-spa/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── root.tsx
│ │ │ ├── routes/
│ │ │ │ ├── _index.tsx
│ │ │ │ ├── semi-splittable.tsx
│ │ │ │ ├── splittable.tsx
│ │ │ │ └── unsplittable.tsx
│ │ │ └── routes.ts
│ │ ├── package.json
│ │ ├── react-router.config.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ └── vite-plugin-cloudflare/
│ ├── .gitignore
│ ├── app/
│ │ ├── entry.server.tsx
│ │ ├── root.tsx
│ │ ├── routes/
│ │ │ ├── _index.tsx
│ │ │ └── static.tsx
│ │ └── routes.ts
│ ├── package.json
│ ├── react-router.config.ts
│ ├── tsconfig.cloudflare.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ ├── vite.config.ts
│ ├── workers/
│ │ └── app.ts
│ └── wrangler.toml
├── pnpm-workspace.yaml
├── prettier.config.js
├── scripts/
│ ├── clean-v6-artifacts.sh
│ ├── close-feature-pr.md
│ ├── close-no-repro-issue.md
│ ├── close-no-repro-issues.md
│ ├── close-no-repro-issues.ts
│ ├── constants.js
│ ├── delete-pre-tags.sh
│ ├── docs.ts
│ ├── find-release-from-changeset.js
│ ├── finish-stable-release.sh
│ ├── playground.js
│ ├── publish.js
│ ├── remove-prerelease-changelogs.mjs
│ ├── start-prerelease.sh
│ ├── utils.js
│ └── version.js
├── tutorials/
│ └── address-book/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── app.css
│ │ ├── data.ts
│ │ ├── root.tsx
│ │ └── routes.ts
│ ├── package.json
│ ├── react-router.config.ts
│ ├── tsconfig.json
│ └── vite.config.ts
└── typedoc.mjs
================================================
FILE CONTENTS
================================================
================================================
FILE: .browserslistrc
================================================
# Browsers we support
Chrome >= 73
ChromeAndroid >= 75
Firefox >= 67
Edge >= 17
Safari >= 12.1
iOS >= 11.3
================================================
FILE: .changeset/README.md
================================================
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
================================================
FILE: .changeset/config.json
================================================
{
"$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json",
"changelog": [
"@remix-run/changelog-github",
{ "repo": "remix-run/react-router" }
],
"commit": false,
"fixed": [
[
"create-react-router",
"react-router",
"react-router-dom",
"@react-router/architect",
"@react-router/cloudflare",
"@react-router/dev",
"@react-router/fs-routes",
"@react-router/express",
"@react-router/node",
"@react-router/remix-routes-option-adapter",
"@react-router/serve"
]
],
"linked": [],
"access": "public",
"baseBranch": "dev",
"updateInternalDependencies": "patch",
"bumpVersionsWithWorkspaceProtocolOnly": true,
"ignore": ["integration", "integration-*", "@playground/*"],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
}
}
================================================
FILE: .eslintignore
================================================
/fixtures/
node_modules/
pnpm-lock.yaml
/docs/api
examples/**/dist/
worker-configuration.d.ts
/playground/
/playground-local/
integration/helpers/**/dist/
integration/helpers/**/build/
playwright-report/
test-results/
build.utils.d.ts
.wrangler/
.tmp/
.react-router/
packages/**/dist/
packages/react-router-dom/server.d.ts
packages/react-router-dom/server.js
packages/react-router-dom/server.mjs
tutorial/dist/
public/
================================================
FILE: .eslintrc
================================================
{
"extends": ["react-app"],
"rules": {
"import/first": "off",
"@typescript-eslint/consistent-type-imports": "error"
},
"overrides": [
{
"files": ["**/__tests__/**"],
"plugins": ["jest"],
"extends": ["plugin:jest/recommended"]
},
{
"files": ["integration/**/*.*"],
"rules": {
"react-hooks/rules-of-hooks": "off"
},
"env": {
"jest/globals": false
}
},
{
"files": ["packages/react-router-dev/config/default-rsc-entries/*"],
"rules": {
"@typescript-eslint/consistent-type-imports": "off"
}
},
{
// Only apply JSDoc lint rules to files we auto-generate docs for
"files": [
"packages/react-router/lib/components.tsx",
"packages/react-router/lib/hooks.tsx",
"packages/react-router/lib/dom/lib.tsx",
"packages/react-router/lib/dom/ssr/components.tsx",
"packages/react-router/lib/dom/ssr/server.tsx",
"packages/react-router/lib/dom-export/hydrated-router.tsx",
"packages/react-router/lib/dom/server.tsx",
"packages/react-router/lib/router/utils.ts",
"packages/react-router/lib/rsc/browser.tsx",
"packages/react-router/lib/rsc/server.rsc.ts",
"packages/react-router/lib/rsc/server.ssr.tsx",
"packages/react-router/lib/rsc/html-stream/browser.ts",
],
"plugins": ["jsdoc"],
"rules": {
"jsdoc/check-access": "error",
"jsdoc/check-alignment": "error",
"jsdoc/check-param-names": "error",
"jsdoc/check-property-names": "error",
"jsdoc/check-tag-names": [
"error",
{
"definedTags": ["additionalExamples", "category", "mode"]
}
],
"jsdoc/no-defaults": "error",
"jsdoc/no-multi-asterisks": ["error", { "allowWhitespace": true }],
"jsdoc/require-description": "error",
"jsdoc/require-param": ["error", { "enableRootFixer": false }],
"jsdoc/require-param-description": "error",
"jsdoc/require-param-name": "error",
"jsdoc/require-returns": "error",
"jsdoc/require-returns-check": "error",
"jsdoc/require-returns-description": "error",
"jsdoc/sort-tags": [
"error",
{
"tagSequence": [
{
"tags": ["description"]
},
{
"tags": ["example"]
},
{
"tags": ["additionalExamples"]
},
{
"tags": [
"name",
"public",
"private",
"category",
"mode",
"param",
"returns"
]
}
]
}
]
}
}
],
"reportUnusedDisableDirectives": true
}
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: react-router
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐛 Bug Report
description: Something is wrong with React Router
labels:
- bug
body:
- type: markdown
attributes:
value: |
Thank you for helping to improve React Router!
Please note that **all** bugs must have a **minimal** and **runnable** reproduction, meaning that it is not just pointing to a deployed site or a branch in your existing application, or showing a small code snippet. For more information, please refer to the [Bug/Issue Process Guidelines](https://github.com/remix-run/react-router/blob/main/GOVERNANCE.md#bugissue-process).
## If you are using **Framework Mode**, you have 2 preferred options
### Option 1 - Create a failing integration test
🏆 The most helpful reproduction is to use our _bug report integration test_ template:
1. [Fork `remix-run/react-router`](https://github.com/remix-run/react-router/fork)
2. Open [`integration/bug-report-test.ts`](https://github.com/remix-run/react-router/blob/dev/integration/bug-report-test.ts) in your editor
3. Follow the instructions to create a failing bug report test
4. Link to your forked branch with the failing test in this issue
### Option 2 - Create a **minimal** reproduction
- 🥇 Link to a [StackBlitz](https://reactrouter.com/new) environment
- 🥈 Link to a GitHub repository containing a minimal reproduction app
## If you are using **Data** or **Declarative Mode**
Create a **minimal** reproduction
- 🥇 Link to a CodeSandbox repro: [TS](https://codesandbox.io/templates/react-vite-ts) | [JS](https://codesandbox.io/templates/react-vite)
- 🥈 Link to a GitHub repository containing a minimal reproduction app
- type: textarea
id: reproduction
attributes:
label: Reproduction
description: Link to reproduction and steps to reproduce the behavior
placeholder: Go to https://stackblitz.com/edit/... and click the "Submit" button
validations:
required: true
- type: textarea
id: system-info
attributes:
label: System Info
description: Output of `npx envinfo --system --npmPackages '{vite,react-router,@react-router/*}' --binaries --browsers`
render: shell
placeholder: System, Binaries, Browsers
validations:
required: true
- type: dropdown
id: package-manager
attributes:
label: Used Package Manager
description: Select the used package manager
options:
- npm
- yarn
- pnpm
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Actual Behavior
description: A concise description of what you're experiencing.
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: 💡 Feature Request
url: https://github.com/remix-run/react-router/discussions/new?category=proposals
about: If you've got an idea for a new feature in React Router, please open a new Discussion with the `Proposals` label
- name: 🤔 Usage Question (Github Discussions)
url: https://github.com/remix-run/remix/discussions/new?category=q-a
about: Open a Discussion in GitHub with the `Q&A` label
- name: 💬 Remix Discord Channel
url: https://rmx.as/discord
about: Interact with other people using React Router and Remix 📀
================================================
FILE: .github/ISSUE_TEMPLATE/documentation_isse.yml
================================================
name: 📚 Documentation Issue
description: Something is wrong with the React Router docs
title: "[Docs]: "
labels:
- docs
body:
- type: markdown
attributes:
value: |
Thank you for contributing!
For documentation updates - we would happily accept PRs, so feel free to update and
open a PR to the `main` branch. Otherwise let us know in this issue what you felt
was missing or incorrect.
- type: textarea
attributes:
label: Describe what's incorrect/missing in the documentation
description: A concise description of what you expected to see in the docs
validations:
required: true
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
================================================
FILE: .github/workflows/close-feature-pr.yml
================================================
# Close a singular pull request that implements a feature that has not
# gone through the Proposal process
# Triggered by adding the `feature-request` label to an issue
name: 🚪 Check Feature PR
on:
pull_request_target:
types: [labeled]
jobs:
close-feature-pr:
name: 🚪 Check Feature PR
if: github.repository == 'remix-run/react-router' && github.event.label.name == 'feature-request'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 🚪 Close PR
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr comment ${{ github.event.pull_request.number }} -F ./scripts/close-feature-pr.md
gh pr edit ${{ github.event.pull_request.number }} --remove-label ${{ github.event.label.name }}
gh pr close ${{ github.event.pull_request.number }}
================================================
FILE: .github/workflows/close-no-repro-issue.yml
================================================
# Close a singular issue without a reproduction
# Triggered by adding the `no-reproduction` label to an issue
name: 🚪 Close issue without a reproduction
on:
issues:
types: [labeled]
jobs:
close-no-repro-issue:
name: 🚪 Close issue
if: github.repository == 'remix-run/react-router' && github.event.label.name == 'no-reproduction'
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 🚪 Close issue
env:
GH_TOKEN: ${{ github.token }}
run: |
gh issue comment ${{ github.event.issue.number }} -F ./scripts/close-no-repro-issue.md
gh issue edit ${{ github.event.issue.number }} --remove-label ${{ github.event.label.name }}
gh issue close ${{ github.event.issue.number }} -r "not planned";
================================================
FILE: .github/workflows/close-no-repro-issues.yml
================================================
# This is a bulk-close script that was used initially to find and close issues
# without a repro, but moving forward we'll likely use the singular version
# (close-no-repro-issue.yml) on new issues which is driven by a label added to
# the issue
name: 🚪 Close issues without a reproduction
on:
workflow_dispatch:
inputs:
dryRun:
type: boolean
description: "Dry Run? (no issues will be closed)"
default: false
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
close-no-repro-issues:
name: 🚪 Close issues
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
env:
CI: "true"
GH_TOKEN: ${{ github.token }}
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4.1.0
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
# required for --experimental-strip-types
node-version: 22
cache: "pnpm"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🚪 Close Issues (Dry Run)
if: ${{ inputs.dryRun }}
run: node --experimental-strip-types ./scripts/close-no-repro-issues.ts --dryRun
- name: 🚪 Close Issues
if: ${{ ! inputs.dryRun }}
run: node --experimental-strip-types ./scripts/close-no-repro-issues.ts
================================================
FILE: .github/workflows/deduplicate-lock-file.yml
================================================
name: ⚙️ Deduplicate lock file
on:
push:
branches:
- dev
paths:
- pnpm-lock.yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
dedupe:
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
token: ${{ secrets.FORMAT_PAT }}
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: ⚙️ Dedupe lock file
run: pnpm dedupe && rm -rf ./node_modules && pnpm install
- name: 💪 Commit
run: |
git config --local user.email "hello@remix.run"
git config --local user.name "Remix Run Bot"
git add .
if [ -z "$(git status --porcelain)" ]; then
echo "💿 no deduplication needed"
exit 0
fi
git commit -m "chore: deduplicate \`pnpm-lock.yaml\`"
git push
echo "💿 pushed dedupe changes https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)"
================================================
FILE: .github/workflows/docs.yml
================================================
name: 📚 Docs
on:
push:
branches:
- main
- dev
paths:
- "packages/**/*.ts"
- "packages/**/*.tsx"
- "scripts/docs.ts"
workflow_dispatch:
inputs:
branch:
description: "Branch to generate docs on"
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
docs:
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
token: ${{ secrets.FORMAT_PAT }}
ref: ${{ github.event.inputs.branch }}
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: pnpm
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🏗 Build
run: pnpm build
- name: 📚 Generate Typedoc Docs
run: pnpm run docs:typedoc
- name: 📚 Generate Markdown Docs
run: pnpm run docs:jsdoc --write
- name: 💪 Commit
run: |
git config --local user.email "hello@remix.run"
git config --local user.name "Remix Run Bot"
git add .
if [ -z "$(git status --porcelain)" ]; then
echo "💿 no docs changed"
exit 0
fi
git commit -m "chore: generate markdown docs from jsdocs"
git push
echo "💿 pushed docs changes https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)"
================================================
FILE: .github/workflows/format.yml
================================================
name: 👔 Format
on:
push:
branches:
- main
- dev
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
format:
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
token: ${{ secrets.FORMAT_PAT }}
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: pnpm
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🔃 Sort contributors.yml
run: sort --ignore-case --output contributors.yml contributors.yml
- name: 👔 Format
run: pnpm format
- name: 💪 Commit
run: |
git config --local user.email "hello@remix.run"
git config --local user.name "Remix Run Bot"
git add .
if [ -z "$(git status --porcelain)" ]; then
echo "💿 no formatting changed"
exit 0
fi
git commit -m "chore: format"
git push
echo "💿 pushed formatting changes https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)"
================================================
FILE: .github/workflows/integration-full.yml
================================================
name: Branch
# main/dev branches will get the full run across
# all OS/browsers for multiple node versions
on:
push:
branches:
- main
- dev
paths-ignore:
- ".changeset/**"
- "decisions/**"
- "docs/**"
- "examples/**"
- "jest/**"
- "scripts/**"
- "tutorial/**"
- "contributors.yml"
- "**/*.md"
jobs:
build:
name: "⚙️ Build"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-build.yml
integration-ubuntu:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[20.18, 22]"
browser: '["chromium", "firefox"]'
integration-windows:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "windows-latest"
node_version: "[22]"
browser: '["msedge"]'
timeout: 90
integration-macos:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "macos-latest"
node_version: "[20.18, 22]"
browser: '["webkit"]'
================================================
FILE: .github/workflows/integration-pr-ubuntu.yml
================================================
name: PR (Base)
# All PRs touching code will run tests on ubuntu/node/chromium
on:
pull_request:
paths-ignore:
- ".changeset/**"
- "decisions/**"
- "docs/**"
- "examples/**"
- "jest/**"
- "scripts/**"
- "tutorial/**"
- "contributors.yml"
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: "⚙️ Build"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-build.yml
integration-chromium:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[22]"
browser: '["chromium"]'
================================================
FILE: .github/workflows/integration-pr-windows-macos.yml
================================================
name: PR (Full)
# PRs touching @react-router/dev will also run on Ubuntu/Firefox, Windows/Edge and
# OSX/WebKit as well as an Ubuntu/Chromium run on Node 20.18.
on:
pull_request:
paths:
- "pnpm-lock.yaml"
- "integration/**"
- "packages/react-router-dev/**"
- "!**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
integration-chromium:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[20.18]"
browser: '["chromium"]'
integration-firefox:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "ubuntu-latest"
node_version: "[22]"
browser: '["firefox"]'
integration-msedge:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "windows-latest"
node_version: "[22]"
browser: '["msedge"]'
timeout: 90
integration-webkit:
name: "👀 Integration Test"
if: github.repository == 'remix-run/react-router'
uses: ./.github/workflows/shared-integration.yml
with:
os: "macos-latest"
node_version: "[22]"
browser: '["webkit"]'
================================================
FILE: .github/workflows/no-response.yml
================================================
name: 🥺 No Response
on:
schedule:
# Schedule for five minutes after the hour, every hour
- cron: "5 * * * *"
permissions:
issues: write
pull-requests: write
jobs:
stale:
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
steps:
- name: 🥺 Handle Ghosting
uses: actions/stale@v10
with:
days-before-close: 10
close-issue-message: >
This issue has been automatically closed because we haven't received a
response from the original author 🙈. This automation helps keep the issue
tracker clean from issues that aren't actionable. Please reach out if you
have more information for us! 🙂
close-pr-message: >
This PR has been automatically closed because we haven't received a
response from the original author 🙈. This automation helps keep the issue
tracker clean from PRs that aren't actionable. Please reach out if you
have more information for us! 🙂
# don't automatically mark issues/PRs as stale
days-before-stale: -1
stale-issue-label: needs-response
stale-pr-label: needs-response
================================================
FILE: .github/workflows/release-comment-manual.yml
================================================
# Used to manually trigger the release comments workflow
name: 💬 Release Comment
on:
workflow_dispatch:
inputs:
dryRun:
description: "Should this be a dry run? (true/false)"
type: "boolean"
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
jobs:
comment:
name: 📝 Comment on related issues and pull requests
if: github.repository == 'remix-run/react-router'
runs-on: ubuntu-latest
permissions:
issues: write # enable commenting on released issues
pull-requests: write # enable commenting on released pull requests
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
fetch-depth: 0
# IMPORTANT: if you make changes here, also make them in release.yml
- name: 📝 Comment on related issues and pull requests
uses: remix-run/release-comment-action@v0.5.1
with:
DRY_RUN: ${{ github.event.inputs.dryRun }}
DIRECTORY_TO_CHECK: "./packages"
PACKAGE_NAME: "react-router"
ISSUE_LABELS_TO_REMOVE: "awaiting release"
ISSUE_LABELS_TO_KEEP_OPEN: "🗺 Roadmap"
================================================
FILE: .github/workflows/release.yml
================================================
# We use this singular file for all of our releases because we can only specify
# a singular GitHub workflow file in npm's Trusted Publishing configuration.
# See https://docs.npmjs.com/trusted-publishers for more info.
#
# Specific jobs only run on the proper trigger:
#
# - Changesets-driven pre-releases/stable releases
# - Trigger: push to release-next/release-v6 branch
# - jobs: release -> find_package_version -> comment
# - Nightly releases
# - Trigger: schedule/cron
# - jobs: release-nightly
# - Experimental releases (from a workflow_dispatch trigger)
# - Trigger: workflow_dispatch
# - jobs: release-experimental
name: 🚢 Release
on:
# Changesets-driven prereleases and stable releases
push:
branches:
- "release-next"
- "release-v6"
# Nightly releases
schedule:
- cron: "0 7 * * *" # every day at 12AM PST
# Experimental Releases
workflow_dispatch:
inputs:
branch:
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
jobs:
release:
name: 🦋 Changesets Release
if: github.repository == 'remix-run/react-router' && github.event_name == 'push'
runs-on: ubuntu-latest
outputs:
published_packages: ${{ steps.changesets.outputs.publishedPackages }}
published: ${{ steps.changesets.outputs.published }}
permissions:
contents: write # enable pushing changes to the origin
id-token: write # enable generation of an ID token for publishing
pull-requests: write # enable opening a PR for the release
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version: 24 # Needed for npm@11 for Trusted Publishing
cache: "pnpm"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
# This action has two responsibilities. The first time the workflow runs
# (initial push to a `release-*` branch) it will create a new branch and
# then open a PR with the related changes for the new version. After the
# PR is merged, the workflow will run again and this action will build +
# publish to npm.
- name: 🚀 PR / Publish
id: changesets
# PLEASE KEEP THIS PINNED TO 1.4.10 to avoid a regression in 1.5.*
# See https://github.com/changesets/action/issues/465
uses: changesets/action@v1.4.10
with:
version: pnpm run changeset:version
commit: "chore: Update version for release"
title: "chore: Update version for release"
publish: pnpm run release
createGithubReleases: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
find_package_version:
name: 🦋 Find Package
needs: [release]
runs-on: ubuntu-latest
if: github.repository == 'remix-run/react-router' && github.event_name == 'push' && github.ref_name != 'release-v6' && needs.release.outputs.published == 'true'
outputs:
package_version: ${{ steps.find_package_version.outputs.package_version }}
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version: 24 # Needed for npm@11 for Trusted Publishing
cache: "pnpm"
- id: find_package_version
run: |
package_version=$(node ./scripts/find-release-from-changeset.js)
echo "package_version=${package_version}" >> $GITHUB_OUTPUT
env:
PACKAGE_VERSION_TO_FOLLOW: "react-router"
PUBLISHED_PACKAGES: ${{ needs.release.outputs.published_packages }}
comment:
name: 📝 Comment on related issues and pull requests
if: github.repository == 'remix-run/react-router' && github.event_name == 'push' && github.ref_name != 'release-v6' && needs.find_package_version.outputs.package_version != ''
needs: [release, find_package_version]
runs-on: ubuntu-latest
permissions:
issues: write # enable commenting on released issues
pull-requests: write # enable commenting on released pull requests
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
fetch-depth: 0
# IMPORTANT: if you make changes here, also make them in release-comment-manual.yml
- name: 📝 Comment on related issues and pull requests
uses: remix-run/release-comment-action@v0.5.1
with:
DIRECTORY_TO_CHECK: "./packages"
PACKAGE_NAME: "react-router"
ISSUE_LABELS_TO_REMOVE: "awaiting release"
ISSUE_LABELS_TO_KEEP_OPEN: "🗺 Roadmap"
# HEADS UP! this "nightly" job will only ever run on the `main` branch due to
# it being a cron job, and the last commit on main will be what github shows
# as the trigger however in the checkout below we specify the `dev` branch,
# so all the scripts in this job will be ran from that, confusing i know, so
# in some cases we'll need to create multiple PRs when modifying nightly
# release processes
release-nightly:
name: 🌒 Nightly Release
if: github.repository == 'remix-run/react-router' && github.event_name == 'schedule'
runs-on: ubuntu-latest
permissions:
contents: write # enable pushing changes to the origin
id-token: write # enable generation of an ID token for publishing
outputs:
# will be undefined if there's no release necessary
NEXT_VERSION: ${{ steps.version.outputs.NEXT_VERSION }}
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
ref: dev
# checkout using a custom token so that we can push later on
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version: 24 # Needed for npm@11 for Trusted Publishing
cache: "pnpm"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🕵️ Check for changes
id: version
run: |
SHORT_SHA=$(git rev-parse --short HEAD)
# get latest nightly tag
LATEST_NIGHTLY_TAG=$(git tag -l v0.0.0-nightly-\* --sort=-creatordate | head -n 1)
# check if last commit to dev starts with the nightly tag we're about
# to create (minus the date)
# if it is, we'll skip the nightly creation
# if not, we'll create a new nightly tag
if [[ ${LATEST_NIGHTLY_TAG} == v0.0.0-nightly-${SHORT_SHA}-* ]]; then
echo "🛑 Latest nightly tag is the same as the latest commit sha, skipping nightly release"
else
# yyyyMMdd format (e.g. 20221207)
DATE=$(date '+%Y%m%d')
# v0.0.0-nightly-<short sha>-<date>
NEXT_VERSION=0.0.0-nightly-${SHORT_SHA}-${DATE}
# set output so it can be used in other jobs
echo "NEXT_VERSION=${NEXT_VERSION}" >> $GITHUB_OUTPUT
fi
- name: ⤴️ Update version
if: steps.version.outputs.NEXT_VERSION
run: |
git config --local user.email "hello@remix.run"
git config --local user.name "Remix Run Bot"
git checkout -b nightly/${{ steps.version.outputs.NEXT_VERSION }}
pnpm run version ${{steps.version.outputs.NEXT_VERSION}}
git push origin --tags
- name: 🏗 Build
if: steps.version.outputs.NEXT_VERSION
run: pnpm build
- name: 🚀 Publish
if: steps.version.outputs.NEXT_VERSION
run: pnpm run publish
release-experimental:
name: 🧪 Experimental Release
if: github.repository == 'remix-run/react-router' && github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write # enable pushing changes to the origin
id-token: write # enable generation of an ID token for publishing
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.branch }}
# checkout using a custom token so that we can push later on
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version: 24 # Needed for npm@11 for Trusted Publishing
cache: "pnpm"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: ⤴️ Update version
run: |
git config --local user.email "hello@remix.run"
git config --local user.name "Remix Run Bot"
SHORT_SHA=$(git rev-parse --short HEAD)
NEXT_VERSION=0.0.0-experimental-${SHORT_SHA}
git checkout -b experimental/${NEXT_VERSION}
pnpm run version ${NEXT_VERSION}
git push origin --tags
- name: 🏗 Build
run: pnpm build
- name: 🚀 Publish
run: pnpm run publish
================================================
FILE: .github/workflows/shared-build.yml
================================================
name: 🛠️ Build
on:
workflow_call:
env:
CI: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
# TODO: Track and renable once this has been fixed: https://github.com/google/wireit/issues/1297
# - uses: google/wireit@setup-github-actions-caching/v2
- name: Disable GitHub Actions Annotations
run: |
echo "::remove-matcher owner=tsc::"
echo "::remove-matcher owner=eslint-compact::"
echo "::remove-matcher owner=eslint-stylish::"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🏗 Build
run: pnpm build
================================================
FILE: .github/workflows/shared-integration.yml
================================================
name: 🧪 Test (Integration)
on:
workflow_call:
inputs:
os:
required: true
type: string
node_version:
required: true
# this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457)
# but we want to pass an array (node_version: "[20, 22]"),
# so we'll need to manually stringify it for now
type: string
browser:
required: true
# this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457)
# but we want to pass an array (browser: "['chromium', 'firefox']"),
# so we'll need to manually stringify it for now
type: string
timeout:
required: false
type: number
default: 45
env:
CI: true
jobs:
integration:
name: "${{ inputs.os }} / node@${{ matrix.node }} / ${{ matrix.browser }}"
strategy:
fail-fast: false
matrix:
node: ${{ fromJSON(inputs.node_version) }}
browser: ${{ fromJSON(inputs.browser) }}
runs-on: ${{ inputs.os }}
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node ${{ matrix.node }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
cache: "pnpm"
# TODO: Track and renable once this has been fixed: https://github.com/google/wireit/issues/1297
# - uses: google/wireit@setup-github-actions-caching/v2
- name: Disable GitHub Actions Annotations
run: |
echo "::remove-matcher owner=tsc::"
echo "::remove-matcher owner=eslint-compact::"
echo "::remove-matcher owner=eslint-stylish::"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 📥 Install Playwright
run: npx playwright install --with-deps ${{ matrix.browser }}
- name: 👀 Run Integration Tests ${{ matrix.browser }}
run: "pnpm test:integration --project=${{ matrix.browser }}"
timeout-minutes: ${{inputs.timeout}}
================================================
FILE: .github/workflows/support.yml
================================================
name: "Support Requests"
on:
issues:
types: [labeled, unlabeled, reopened]
permissions:
issues: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/support-requests@v4
with:
issue-comment: >
:wave: @{issue-author}, we use the issue tracker exclusively for bug reports
and feature requests. However, this issue appears to be a support request.
For usage questions, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/react-router)
or [Discord](https://rmx.as/discord) where there are a lot more people ready to help you out, or
[post a new question](https://github.com/remix-run/react-router/discussions/new?category=q-a) in the
Discussions tab of this repository.
Please feel free to clarify your issue if you think it was closed prematurely.
================================================
FILE: .github/workflows/test.yml
================================================
name: 🧪 Test
on:
push:
branches:
- main
- dev
tags-ignore:
- v*
paths-ignore:
- "docs/**"
- "**/README.md"
pull_request:
paths-ignore:
- "docs/**"
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: "🧪 Test: (Node: ${{ matrix.node }})"
strategy:
fail-fast: false
matrix:
node:
- 20.18
- 22
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v6
- name: 📦 Setup pnpm
uses: pnpm/action-setup@v4
- name: ⎔ Setup node
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
cache: pnpm
check-latest: true
# TODO: Track and renable once this has been fixed: https://github.com/google/wireit/issues/1297
# - uses: google/wireit@setup-github-actions-caching/v2
- name: Disable GitHub Actions Annotations
run: |
echo "::remove-matcher owner=tsc::"
echo "::remove-matcher owner=eslint-compact::"
echo "::remove-matcher owner=eslint-stylish::"
- name: 📥 Install deps
run: pnpm install --frozen-lockfile
- name: 🏗 Build
run: pnpm build
- name: 🔍 Typecheck
run: pnpm typecheck
- name: 🔬 Lint
run: pnpm lint
- name: 🧪 Run tests
run: pnpm test
================================================
FILE: .gitignore
================================================
.DS_Store
npm-debug.log
/website/build/
node_modules/
/examples/*/yarn.lock
/examples/*/pnpm-lock.yaml
/examples/*/dist
/tutorial/dist
/playground-local/
/integration/playwright-report
/integration/test-results
# v5 build files
/packages/*/cjs/
/packages/*/esm/
/packages/*/umd/
# v6 build files
/build/
/packages/*/dist/
/packages/*/LICENSE.md
# v7 build files
.react-router
.wireit
.eslintcache
.tmp
tsup.config.bundled_*.mjs
build.utils.d.ts
worker-configuration.d.ts
/.env
/NOTES.md
# v7 reference docs
/public
================================================
FILE: .npmrc
================================================
ignore-workspace-cycles=true
enable-pre-post-scripts=true
================================================
FILE: .nvmrc
================================================
22
================================================
FILE: .vscode/settings.json
================================================
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
================================================
FILE: AGENTS.md
================================================
# React Router Development Guide
## Commands
- **Build**: `pnpm build` (all packages) or `pnpm run --filter <package> build` (single package)
- **Test (Jest)**: `pnpm test` (all packages), `pnpm test packages/<package>/` (single package), `pnpm test packages/react-router/__tests__/router/fetchers-test.ts` (single file), or `pnpm test -- -t "action fetch"` (tests matching name)
- **Integration tests (Playwright)**: `pnpm test:integration --project chromium` (build + test all), `pnpm test:integration:run --project chromium` (test only, all), `pnpm test:integration:run --project chromium integration/middleware-test.ts` (single file), or `pnpm test:integration:run --project chromium -g "middleware"` (tests matching name)
- **Typecheck**: `pnpm run typecheck`
- **Lint**: `pnpm run lint`
- **Docs generation**: `pnpm run docs` (regenerates API docs from JSDoc)
- **Type generation**: `pnpm run typegen` (Framework Mode only)
- **Clean**: `pnpm run clean` (git clean -fdX)
## Modes
**Five distinct modes**: Declarative, Data, Framework, RSC Data (unstable), RSC Framework (unstable). **Always identify which mode(s) a feature applies to.**
1. **Declarative**: `<BrowserRouter>`, `<Routes>`, `<Route>`
2. **Data**: `createBrowserRouter()` with `loader`/`action`, `<RouterProvider>`
3. **Framework**: Vite plugin + `routes.ts` + Route Module API (route exports like `loader`, `action`, `default`) + type generation + SSR/SPA
4. **RSC Data** (unstable): RSC runtime APIs, manual bundler setup, runtime route config
5. **RSC Framework** (unstable): Framework Mode with `unstable_reactRouterRSC` Vite plugin
**RSC mode differences:**
- **RSC Framework**: `unstable_reactRouterRSC` plugin, `@vitejs/plugin-rsc`, different entry points/format
- **RSC Data**: Manual bundler, runtime route config typically in `src/routes.ts`, `unstable_RSCRouteConfig`, different runtime APIs, `setupRscTest` in `integration/rsc/`
## Architecture
- **Monorepo**: pnpm workspace, packages in `packages/`
- **Key packages**:
- `react-router`: Core (all modes) - `lib/components.tsx`, `lib/hooks.tsx`, `lib/router/`, `lib/dom/`, `lib/rsc/`
- `@react-router/dev`: Framework tooling - `vite/plugin.ts` (Framework), `vite/rsc/plugin.ts` (RSC Framework), `typegen/`
- `react-router-dom`: Re-exports `react-router` (v6→v7 compat)
- `@react-router/node`, `@react-router/cloudflare`, `@react-router/express`: Server adapters
- `@react-router/serve`: Minimal server for Framework Mode
- `@react-router/fs-routes`: File-system routing (`flatRoutes()`)
## Testing
### Unit Tests (`packages/react-router/__tests__/`)
Use Jest for pure routing logic, pure server runtime behavior, router state, React component behavior. No build required.
```bash
pnpm test # All packages
pnpm test packages/react-router/ # Single package
pnpm test packages/react-router/__tests__/router/fetchers-test.ts # Single file
pnpm test -- -t "action fetch" # Tests matching name
```
### Integration Tests (`integration/`)
Use Playwright for Vite plugin, build pipeline, SSR/hydration, RSC, type generation.
```bash
pnpm test:integration --project chromium # Build + test all
pnpm test:integration:run --project chromium # Test only, all
pnpm test:integration:run --project chromium integration/middleware-test.ts # Single file
pnpm test:integration:run --project chromium -g "middleware" # Tests matching name
```
**Project**: Always use `chromium` for integration tests, unless explicitly stated otherwise.
**Rebuild when**: First run, after changing `packages/` (not needed for test-only changes)
**Organization**: Use `createFixture()` → `createAppFixture()` → `PlaywrightFixture`. Templates available: `vite-6-template/`, `rsc-vite-framework/`, etc. Test all applicable modes (iterate over template array when behavior should work across modes). Test both states when introducing future flags (one test with flag on, one with flag off).
**RSC testing**:
- **RSC Framework**: Use `createFixture` with `rsc-vite-framework/` template
- **RSC Data**: Use `setupRscTest` in `integration/rsc/`
Test shared behavior across multiple templates (e.g., `["vite-5-template", "rsc-vite-framework"]`). Test RSC-specific features against RSC template.
## routes.ts
Framework Mode uses `routes.ts` in `app/`. Most tests use `flatRoutes()` for file-system routing:
```ts
// app/routes.ts
import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";
export default flatRoutes() satisfies RouteConfig;
```
**File-system conventions** (`app/routes/`):
- `_index.tsx` → `/` (index route)
- `about.tsx` → `/about`
- `blog.$slug.tsx` → `/blog/:slug` (URL param)
- `settings.profile.tsx` → `/settings/profile` (`.` creates nesting)
- `_layout.tsx` → pathless layout route
**Manual config alternative**:
```ts
import { index, route, layout } from "@react-router/dev/routes";
export default [
index("./home.tsx"),
route("about", "./about.tsx"),
layout("./auth-layout.tsx", [route("login", "./login.tsx")]),
];
```
## Documentation
**Don't edit generated files**: `docs/api/` (from JSDoc), `.react-router/types/` (from typegen)
**Mode indicators**: Every doc needs `[MODES: framework, data, declarative]`
**API docs**: Edit JSDoc in `packages/react-router/lib/`, run `pnpm docs`
**Unstable features**: Prefix `unstable_`, add `unstable: true` to frontmatter, include warning block
## Future Flags
- **Future flags** (`vX_*`): Stable breaking changes for next major
- **Unstable flags** (`unstable_*`): Experimental, may change
Test both states (on/off) for future flags. Don't break existing behavior without a flag.
## Changesets
When making changes that affect users, create a changeset at `.changeset/<unique-meaningful-name>.md`. If iterating on a change that hasn't shipped yet, update the existing changeset file instead of creating a new one.
Format:
```markdown
---
"react-router": patch
"@react-router/dev": minor
---
Brief description of the change
- Additional details if needed
```
## Branching
- **`main`**: Latest stable release
- **`dev`**: Active development (branch from here for code changes)
- **`v6`**: v6.x maintenance
- Branch from `main` for docs-only changes
## Key Files
| Purpose | Location |
| ----------------- | ----------------------------------------------------------- |
| Router | `packages/react-router/lib/router/router.ts` |
| React API | `packages/react-router/lib/components.tsx`, `lib/hooks.tsx` |
| Vite plugin | `packages/react-router-dev/vite/plugin.ts` |
| RSC Vite plugin | `packages/react-router-dev/vite/rsc/plugin.ts` |
| Type generation | `packages/react-router-dev/typegen/` |
| Unit tests | `packages/react-router/__tests__/` |
| Integration tests | `integration/` |
| Decision docs | `decisions/` |
================================================
FILE: CHANGELOG.md
================================================
<!-- markdownlint-disable no-duplicate-header no-emphasis-as-heading no-inline-html -->
# React Router Releases
This page lists all releases/release notes for React Router back to `v6.0.0`. For releases prior to v6, please refer to the [Github Releases Page](https://github.com/remix-run/react-router/releases).
We manage release notes in this file instead of the paginated Github Releases Page for 2 reasons:
- Pagination in the Github UI means that you cannot easily search release notes for a large span of releases at once
- The paginated Github interface also cuts off longer releases notes without indication in list view, and you need to click into the detail view to see the full set of release notes
<details>
<summary>Table of Contents</summary>
- [React Router Releases](#react-router-releases)
- [v7.13.1](#v7131)
- [What's Changed](#whats-changed)
- [URL Masking (unstable)](#url-masking-unstable)
- [Patch Changes](#patch-changes)
- [Unstable Changes](#unstable-changes)
- [v7.13.0](#v7130)
- [Minor Changes](#minor-changes)
- [Patch Changes](#patch-changes-1)
- [v7.12.0](#v7120)
- [Security Notice](#security-notice)
- [Minor Changes](#minor-changes-1)
- [Patch Changes](#patch-changes-2)
- [Unstable Changes](#unstable-changes-1)
- [v7.11.0](#v7110)
- [What's Changed](#whats-changed-1)
- [`vite preview` Support](#vite-preview-support)
- [Stabilized Client-side `onError`](#stabilized-client-side-onerror)
- [Call-site Revalidation Opt-out (unstable)](#call-site-revalidation-opt-out-unstable)
- [Minor Changes](#minor-changes-2)
- [Patch Changes](#patch-changes-3)
- [Unstable Changes](#unstable-changes-2)
- [v7.10.1](#v7101)
- [Patch Changes](#patch-changes-4)
- [v7.10.0](#v7100)
- [What's Changed](#whats-changed-2)
- [Stabilized `future.v8_splitRouteModules`](#stabilized-futurev8_splitroutemodules)
- [Stabilized `future.v8_viteEnvironmentApi`](#stabilized-futurev8_viteenvironmentapi)
- [Stabilized `fetcher.reset()`](#stabilized-fetcherreset)
- [Stabilized `DataStrategyMatch.shouldCallHandler()`](#stabilized-datastrategymatchshouldcallhandler)
- [Minor Changes](#minor-changes-3)
- [Patch Changes](#patch-changes-5)
- [Unstable Changes](#unstable-changes-3)
- [v7.9.6](#v796)
- [Security Notice](#security-notice-1)
- [Patch Changes](#patch-changes-6)
- [Unstable Changes](#unstable-changes-4)
- [v7.9.5](#v795)
- [What's Changed](#whats-changed-3)
- [Instrumentation (unstable)](#instrumentation-unstable)
- [Patch Changes](#patch-changes-7)
- [Unstable Changes](#unstable-changes-5)
- [v7.9.4](#v794)
- [Security Notice](#security-notice-2)
- [What's Changed](#whats-changed-4)
- [`useRoute()` (unstable)](#useroute-unstable)
- [Patch Changes](#patch-changes-8)
- [Unstable Changes](#unstable-changes-6)
- [v7.9.3](#v793)
- [Patch Changes](#patch-changes-9)
- [v7.9.2](#v792)
- [What's Changed](#whats-changed-5)
- [RSC Framework Mode (unstable)](#rsc-framework-mode-unstable)
- [Fetcher Reset (unstable)](#fetcher-reset-unstable)
- [Patch Changes](#patch-changes-10)
- [Unstable Changes](#unstable-changes-7)
- [v7.9.1](#v791)
- [Patch Changes](#patch-changes-11)
- [v7.9.0](#v790)
- [Security Notice](#security-notice-3)
- [What's Changed](#whats-changed-6)
- [Stable Middleware and Context APIs](#stable-middleware-and-context-apis)
- [Minor Changes](#minor-changes-4)
- [Patch Changes](#patch-changes-12)
- [Unstable Changes](#unstable-changes-8)
- [v7.8.2](#v782)
- [Patch Changes](#patch-changes-13)
- [Unstable Changes](#unstable-changes-9)
- [v7.8.1](#v781)
- [Patch Changes](#patch-changes-14)
- [Unstable Changes](#unstable-changes-10)
- [v7.8.0](#v780)
- [What's Changed](#whats-changed-7)
- [Consistently named `loaderData` values](#consistently-named-loaderdata-values)
- [Improvements/fixes to the middleware APIs (unstable)](#improvementsfixes-to-the-middleware-apis-unstable)
- [Minor Changes](#minor-changes-5)
- [Patch Changes](#patch-changes-15)
- [Unstable Changes](#unstable-changes-11)
- [Changes by Package](#changes-by-package)
- [v7.7.1](#v771)
- [Patch Changes](#patch-changes-16)
- [Unstable Changes](#unstable-changes-12)
- [v7.7.0](#v770)
- [What's Changed](#whats-changed-8)
- [Unstable RSC APIs](#unstable-rsc-apis)
- [Minor Changes](#minor-changes-6)
- [Patch Changes](#patch-changes-17)
- [Unstable Changes](#unstable-changes-13)
- [Changes by Package](#changes-by-package-1)
- [v7.6.3](#v763)
- [Patch Changes](#patch-changes-18)
- [v7.6.2](#v762)
- [Patch Changes](#patch-changes-19)
- [v7.6.1](#v761)
- [Patch Changes](#patch-changes-20)
- [Unstable Changes](#unstable-changes-14)
- [v7.6.0](#v760)
- [What's Changed](#whats-changed-9)
- [`routeDiscovery` Config Option](#routediscovery-config-option)
- [Automatic Types for Future Flags](#automatic-types-for-future-flags)
- [Minor Changes](#minor-changes-7)
- [Patch Changes](#patch-changes-21)
- [Unstable Changes](#unstable-changes-15)
- [Changes by Package](#changes-by-package-2)
- [v7.5.3](#v753)
- [Patch Changes](#patch-changes-22)
- [v7.5.2](#v752)
- [Security Notice](#security-notice-4)
- [Patch Changes](#patch-changes-23)
- [v7.5.1](#v751)
- [Patch Changes](#patch-changes-24)
- [Unstable Changes](#unstable-changes-16)
- [v7.5.0](#v750)
- [What's Changed](#whats-changed-10)
- [`route.lazy` Object API](#routelazy-object-api)
- [Minor Changes](#minor-changes-8)
- [Patch Changes](#patch-changes-25)
- [Unstable Changes](#unstable-changes-17)
- [Changes by Package](#changes-by-package-3)
- [v7.4.1](#v741)
- [Security Notice](#security-notice-5)
- [Patch Changes](#patch-changes-26)
- [Unstable Changes](#unstable-changes-18)
- [v7.4.0](#v740)
- [Minor Changes](#minor-changes-9)
- [Patch Changes](#patch-changes-27)
- [Unstable Changes](#unstable-changes-19)
- [Changes by Package](#changes-by-package-4)
- [v7.3.0](#v730)
- [Minor Changes](#minor-changes-10)
- [Patch Changes](#patch-changes-28)
- [Unstable Changes](#unstable-changes-20)
- [Client-side `context` (unstable)](#client-side-context-unstable)
- [Middleware (unstable)](#middleware-unstable)
- [Middleware `context` parameter](#middleware-context-parameter)
- [`unstable_SerializesTo`](#unstable_serializesto)
- [Changes by Package](#changes-by-package-5)
- [v7.2.0](#v720)
- [What's Changed](#whats-changed-11)
- [Type-safe `href` utility](#type-safe-href-utility)
- [Prerendering with a SPA Fallback](#prerendering-with-a-spa-fallback)
- [Allow a root `loader` in SPA Mode](#allow-a-root-loader-in-spa-mode)
- [Minor Changes](#minor-changes-11)
- [Patch Changes](#patch-changes-29)
- [Unstable Changes](#unstable-changes-21)
- [Split Route Modules (unstable)](#split-route-modules-unstable)
- [Changes by Package](#changes-by-package-6)
- [v7.1.5](#v715)
- [Patch Changes](#patch-changes-30)
- [v7.1.4](#v714)
- [Patch Changes](#patch-changes-31)
- [v7.1.3](#v713)
- [Patch Changes](#patch-changes-32)
- [v7.1.2](#v712)
- [Patch Changes](#patch-changes-33)
- [v7.1.1](#v711)
- [Patch Changes](#patch-changes-34)
- [v7.1.0](#v710)
- [Minor Changes](#minor-changes-12)
- [Patch Changes](#patch-changes-35)
- [Changes by Package](#changes-by-package-7)
- [v7.0.2](#v702)
- [Patch Changes](#patch-changes-36)
- [v7.0.1](#v701)
- [Patch Changes](#patch-changes-37)
- [v7.0.0](#v700)
- [Breaking Changes](#breaking-changes)
- [Package Restructuring](#package-restructuring)
- [Removed Adapter Re-exports](#removed-adapter-re-exports)
- [Removed APIs](#removed-apis)
- [Minimum Versions](#minimum-versions)
- [Adopted Future Flag Behaviors](#adopted-future-flag-behaviors)
- [Vite Compiler](#vite-compiler)
- [Exposed Router Promises](#exposed-router-promises)
- [Other Notable Changes](#other-notable-changes)
- [`routes.ts`](#routests)
- [Type-safety improvements](#type-safety-improvements)
- [Prerendering](#prerendering)
- [Major Changes (`react-router`)](#major-changes-react-router)
- [Major Changes (`@react-router/*`)](#major-changes-react-router-1)
- [Minor Changes](#minor-changes-13)
- [Patch Changes](#patch-changes-38)
- [Changes by Package](#changes-by-package-8)
- [React Router v6 Releases](#react-router-v6-releases)
- [v6.30.3](#v6303)
- [Security Notice](#security-notice-6)
- [Patch Changes](#patch-changes-39)
- [v6.30.2](#v6302)
- [Security Notice](#security-notice-7)
- [Patch Changes](#patch-changes-40)
- [v6.30.1](#v6301)
- [Patch Changes](#patch-changes-41)
- [v6.30.0](#v6300)
- [Minor Changes](#minor-changes-14)
- [Patch Changes](#patch-changes-42)
- [v6.29.0](#v6290)
- [Minor Changes](#minor-changes-15)
- [Patch Changes](#patch-changes-43)
- [v6.28.2](#v6282)
- [Patch Changes](#patch-changes-44)
- [v6.28.1](#v6281)
- [Patch Changes](#patch-changes-45)
- [v6.28.0](#v6280)
- [What's Changed](#whats-changed-12)
- [Minor Changes](#minor-changes-16)
- [Patch Changes](#patch-changes-46)
- [v6.27.0](#v6270)
- [What's Changed](#whats-changed-13)
- [Stabilized APIs](#stabilized-apis)
- [Minor Changes](#minor-changes-17)
- [Patch Changes](#patch-changes-47)
- [v6.26.2](#v6262)
- [Patch Changes](#patch-changes-48)
- [v6.26.1](#v6261)
- [Patch Changes](#patch-changes-49)
- [v6.26.0](#v6260)
- [Minor Changes](#minor-changes-18)
- [Patch Changes](#patch-changes-50)
- [v6.25.1](#v6251)
- [Patch Changes](#patch-changes-51)
- [v6.25.0](#v6250)
- [What's Changed](#whats-changed-14)
- [Stabilized `v7_skipActionErrorRevalidation`](#stabilized-v7_skipactionerrorrevalidation)
- [Minor Changes](#minor-changes-19)
- [Patch Changes](#patch-changes-52)
- [v6.24.1](#v6241)
- [Patch Changes](#patch-changes-53)
- [v6.24.0](#v6240)
- [What's Changed](#whats-changed-15)
- [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war)
- [Minor Changes](#minor-changes-20)
- [Patch Changes](#patch-changes-54)
- [v6.23.1](#v6231)
- [Patch Changes](#patch-changes-55)
- [v6.23.0](#v6230)
- [What's Changed](#whats-changed-16)
- [Data Strategy (unstable)](#data-strategy-unstable)
- [Skip Action Error Revalidation (unstable)](#skip-action-error-revalidation-unstable)
- [Minor Changes](#minor-changes-21)
- [v6.22.3](#v6223)
- [Patch Changes](#patch-changes-56)
- [v6.22.2](#v6222)
- [Patch Changes](#patch-changes-57)
- [v6.22.1](#v6221)
- [Patch Changes](#patch-changes-58)
- [v6.22.0](#v6220)
- [What's Changed](#whats-changed-17)
- [Core Web Vitals Technology Report Flag](#core-web-vitals-technology-report-flag)
- [Minor Changes](#minor-changes-22)
- [Patch Changes](#patch-changes-59)
- [v6.21.3](#v6213)
- [Patch Changes](#patch-changes-60)
- [v6.21.2](#v6212)
- [Patch Changes](#patch-changes-61)
- [v6.21.1](#v6211)
- [Patch Changes](#patch-changes-62)
- [v6.21.0](#v6210)
- [What's Changed](#whats-changed-18)
- [`future.v7_relativeSplatPath`](#futurev7_relativesplatpath)
- [Partial Hydration](#partial-hydration)
- [Minor Changes](#minor-changes-23)
- [Patch Changes](#patch-changes-63)
- [v6.20.1](#v6201)
- [Patch Changes](#patch-changes-64)
- [v6.20.0](#v6200)
- [Minor Changes](#minor-changes-24)
- [Patch Changes](#patch-changes-65)
- [v6.19.0](#v6190)
- [What's Changed](#whats-changed-19)
- [`unstable_flushSync` API](#unstable_flushsync-api)
- [Minor Changes](#minor-changes-25)
- [Patch Changes](#patch-changes-66)
- [v6.18.0](#v6180)
- [What's Changed](#whats-changed-20)
- [New Fetcher APIs](#new-fetcher-apis)
- [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist)
- [Minor Changes](#minor-changes-26)
- [Patch Changes](#patch-changes-67)
- [v6.17.0](#v6170)
- [What's Changed](#whats-changed-21)
- [View Transitions 🚀](#view-transitions-)
- [Minor Changes](#minor-changes-27)
- [Patch Changes](#patch-changes-68)
- [v6.16.0](#v6160)
- [Minor Changes](#minor-changes-28)
- [Patch Changes](#patch-changes-69)
- [v6.15.0](#v6150)
- [Minor Changes](#minor-changes-29)
- [Patch Changes](#patch-changes-70)
- [v6.14.2](#v6142)
- [Patch Changes](#patch-changes-71)
- [v6.14.1](#v6141)
- [Patch Changes](#patch-changes-72)
- [v6.14.0](#v6140)
- [What's Changed](#whats-changed-22)
- [JSON/Text Submissions](#jsontext-submissions)
- [Minor Changes](#minor-changes-30)
- [Patch Changes](#patch-changes-73)
- [v6.13.0](#v6130)
- [What's Changed](#whats-changed-23)
- [`future.v7_startTransition`](#futurev7_starttransition)
- [Minor Changes](#minor-changes-31)
- [Patch Changes](#patch-changes-74)
- [v6.12.1](#v6121)
- [Patch Changes](#patch-changes-75)
- [v6.12.0](#v6120)
- [What's Changed](#whats-changed-24)
- [`React.startTransition` support](#reactstarttransition-support)
- [Minor Changes](#minor-changes-32)
- [Patch Changes](#patch-changes-76)
- [v6.11.2](#v6112)
- [Patch Changes](#patch-changes-77)
- [v6.11.1](#v6111)
- [Patch Changes](#patch-changes-78)
- [v6.11.0](#v6110)
- [Minor Changes](#minor-changes-33)
- [Patch Changes](#patch-changes-79)
- [v6.10.0](#v6100)
- [What's Changed](#whats-changed-25)
- [Minor Changes](#minor-changes-34)
- [`future.v7_normalizeFormMethod`](#futurev7_normalizeformmethod)
- [Patch Changes](#patch-changes-80)
- [v6.9.0](#v690)
- [What's Changed](#whats-changed-26)
- [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties)
- [Introducing Lazy Route Modules](#introducing-lazy-route-modules)
- [Minor Changes](#minor-changes-35)
- [Patch Changes](#patch-changes-81)
- [v6.8.2](#v682)
- [Patch Changes](#patch-changes-82)
- [v6.8.1](#v681)
- [Patch Changes](#patch-changes-83)
- [v6.8.0](#v680)
- [Minor Changes](#minor-changes-36)
- [Patch Changes](#patch-changes-84)
- [v6.7.0](#v670)
- [Minor Changes](#minor-changes-37)
- [Patch Changes](#patch-changes-85)
- [v6.6.2](#v662)
- [Patch Changes](#patch-changes-86)
- [v6.6.1](#v661)
- [Patch Changes](#patch-changes-87)
- [v6.6.0](#v660)
- [What's Changed](#whats-changed-27)
- [Minor Changes](#minor-changes-38)
- [Patch Changes](#patch-changes-88)
- [v6.5.0](#v650)
- [What's Changed](#whats-changed-28)
- [Minor Changes](#minor-changes-39)
- [Patch Changes](#patch-changes-89)
- [v6.4.5](#v645)
- [Patch Changes](#patch-changes-90)
- [v6.4.4](#v644)
- [Patch Changes](#patch-changes-91)
- [v6.4.3](#v643)
- [Patch Changes](#patch-changes-92)
- [v6.4.2](#v642)
- [Patch Changes](#patch-changes-93)
- [v6.4.1](#v641)
- [Patch Changes](#patch-changes-94)
- [v6.4.0](#v640)
- [What's Changed](#whats-changed-29)
- [Remix Data APIs](#remix-data-apis)
- [Patch Changes](#patch-changes-95)
- [v6.3.0](#v630)
- [Minor Changes](#minor-changes-40)
- [v6.2.2](#v622)
- [Patch Changes](#patch-changes-96)
- [v6.2.1](#v621)
- [Patch Changes](#patch-changes-97)
- [v6.2.0](#v620)
- [Minor Changes](#minor-changes-41)
- [Patch Changes](#patch-changes-98)
- [v6.1.1](#v611)
- [Patch Changes](#patch-changes-99)
- [v6.1.0](#v610)
- [Minor Changes](#minor-changes-42)
- [Patch Changes](#patch-changes-100)
- [v6.0.2](#v602)
- [Patch Changes](#patch-changes-101)
- [v6.0.1](#v601)
- [Patch Changes](#patch-changes-102)
- [v6.0.0](#v600)
</details>
<!-- To add a new release, copy from this template:
## v7.X.Y
Date: YYYY-MM-DD
### What's Changed
#### Big New Feature 1
#### Big New Feature 2
### Minor Changes
### Patch Changes
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
**Full Changelog**: [`v7.X.Y...v7.X.Y`](https://github.com/remix-run/react-router/compare/react-router@7.X.Y...react-router@7.X.Y)
-->
## v7.13.1
Date: 2026-02-23
## What's Changed
### URL Masking (unstable)
This release includes a new `<Link unstable_mask>` API which brings first-class support for URL masking to Framework/Data Mode ([RFC](https://github.com/remix-run/react-router/discussions/9864)). This allows the same type of UI you could achieve in Declarative Mode via [manual `backgroundLocation` management](https://github.com/remix-run/react-router/tree/main/examples/modal). That example has been converted to Data Mode using the new API [here](https://github.com/remix-run/react-router/tree/main/examples/modal-data-router).
### Patch Changes
- `react-router` - Clear timeout when `turbo-stream` encoding completes ([#14810](https://github.com/remix-run/react-router/pull/14810))
- `react-router` - Improve error message when `Origin` header is invalid ([#14743](https://github.com/remix-run/react-router/pull/14743))
- `react-router` - Fix `matchPath` optional params matching without a `"/"` separator. ([#14689](https://github.com/remix-run/react-router/pull/14689))
- `matchPath("/users/:id?", "/usersblah")` now returns null
- `matchPath("/test_route/:part?", "/test_route_more")` now returns null.
- `react-router` - Fix `HydrateFallback` rendering during initial lazy route discovery with matching splat route ([#14740](https://github.com/remix-run/react-router/pull/14740))
- `react-router` - Preserve query parameters and hash on manifest version mismatch reload ([#14813](https://github.com/remix-run/react-router/pull/14813))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - RSC: fix null reference exception in bad codepath leading to invalid route tree comparisons ([#14780](https://github.com/remix-run/react-router/pull/14780))
- `react-router` - RSC: add `unstable_getRequest` API ([#14758](https://github.com/remix-run/react-router/pull/14758))
- `react-router` - RSC: Update failed origin checks to return a 400 status and appropriate UI instead of a generic 500 ([#14755](https://github.com/remix-run/react-router/pull/14755))
- `react-router` - Add support for `<Link unstable_mask>` in Framework/Data Mode which allows users to navigate to a URL in the router but "mask" the URL displayed in the browser ([#14716](https://github.com/remix-run/react-router/pull/14716))
- This is useful for contextual routing usages such as displaying an image in a modal on top of a gallery, but displaying a browser URL directly to the image that can be shared and loaded without the contextual gallery in the background
- The masked location, if present, will be available on `useLocation().unstable_mask` so you can detect whether you are currently masked or not
- Masked URLs only work for SPA use cases, and will be removed from `history.state` during SSR
- This provides a first-class API to mask URLs in Framework/Data Mode to achieve the same behavior you could do in Declarative Mode via [manual `backgroundLocation` management](https://github.com/remix-run/react-router/tree/main/examples/modal).
```tsx
// routes/gallery.tsx
export function clientLoader({ request }: Route.LoaderArgs) {
let sp = new URL(request.url).searchParams;
return {
images: getImages(),
// When the router location has the image param, load the modal data
modalImage: sp.has("image") ? getImage(sp.get("image")!) : null,
};
}
export default function Gallery({ loaderData }: Route.ComponentProps) {
return (
<>
<GalleryGrid>
{loaderData.images.map((image) => (
<Link
key={image.id}
{/* Navigate the router to /galley?image=N */}}
to={`/gallery?image=${image.id}`}
{/* But display /images/N in the URL bar */}}
unstable_mask={`/images/${image.id}`}
>
<img src={image.url} alt={image.alt} />
</Link>
))}
</GalleryGrid>
{/* When the modal data exists, display the modal */}
{data.modalImage ? (
<dialog open>
<img src={data.modalImage.url} alt={data.modalImage.alt} />
</dialog>
) : null}
</>
);
}
```
**Full Changelog**: [`v7.13.0...v7.13.1`](https://github.com/remix-run/react-router/compare/react-router@7.13.0...react-router@7.13.1)
## v7.13.0
Date: 2026-01-23
### Minor Changes
- `react-router` - Add `crossOrigin` prop to `Links` component ([#14687](https://github.com/remix-run/react-router/pull/14687))
### Patch Changes
- `react-router` - Fix double slash normalization for `useNavigate` paths with a colon ([#14718](https://github.com/remix-run/react-router/pull/14718))
- `react-router` - Fix missing `nonce` on inline `criticalCss` ([#14691](https://github.com/remix-run/react-router/pull/14691))
- `react-router` - Update failed origin checks to return a 400 status instead of a 500 ([#14737](https://github.com/remix-run/react-router/pull/14737))
- `react-router` - Loosen `allowedActionOrigins` glob check so `**` matches all domains ([#14722](https://github.com/remix-run/react-router/pull/14722))
- `@react-router/dev` - Bump `@remix-run/node-fetch-server` dep ([#14704](https://github.com/remix-run/react-router/pull/14704))
- `@react-router/fs-routes` - Fix route file paths when routes directory is outside of the app directory ([#13937](https://github.com/remix-run/react-router/pull/13937))
**Full Changelog**: [`v7.12.0...v7.13.0`](https://github.com/remix-run/react-router/compare/react-router@7.12.0...react-router@7.13.0)
## v7.12.0
Date: 2026-01-07
### Security Notice
This release addresses 3 security vulnerabilities:
- [CSRF in React Router Action/Server Action Request Processing](https://github.com/remix-run/react-router/security/advisories/GHSA-h5cw-625j-3rxh)
- [XSS via Open Redirects](https://github.com/remix-run/react-router/security/advisories/GHSA-2w69-qvjg-hvjx)
- [React Router SSR XSS in ScrollRestoration](https://github.com/remix-run/react-router/security/advisories/GHSA-8v8x-cx79-35w7)
### Minor Changes
- `react-router` - Add additional layer of CSRF protection by rejecting submissions to UI routes from external origins ([#14708](https://github.com/remix-run/react-router/pull/14708))
- If you need to permit access to specific external origins, there is a new `allowedActionOrigins` config field in `react-router.config.ts` where you can specify external origins
### Patch Changes
- `react-router` - Fix `generatePath` when used with suffixed params (i.e., `/books/:id.json`) ([#14269](https://github.com/remix-run/react-router/pull/14269))
- `react-router` - Escape HTML in scroll restoration keys ([#14705](https://github.com/remix-run/react-router/pull/14705))
- `react-router` - Validate redirect locations ([#14706](https://github.com/remix-run/react-router/pull/14706))
- `@react-router/dev` - Fix `Maximum call stack size exceeded` errors when HMR is triggered against code with cyclic imports ([#14522](https://github.com/remix-run/react-router/pull/14522))
- `@react-router/dev` - Skip SSR middleware in `vite preview` server for SPA mode ([#14673](https://github.com/remix-run/react-router/pull/14673))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Preserve `clientLoader.hydrate=true` when using `<HydratedRouter unstable_instrumentations>` ([#14674](https://github.com/remix-run/react-router/pull/14674))
- `react-router` - Pass `<Scripts nonce>` value through to the underlying `importmap` `script` tag when using `future.unstable_subResourceIntegrity` ([#14675](https://github.com/remix-run/react-router/pull/14675))
- `react-router` - Export `UNSAFE_createMemoryHistory` and `UNSAFE_createHashHistory` alongside `UNSAFE_createBrowserHistory` for consistency ([#14663](https://github.com/remix-run/react-router/pull/14663))
- These are not intended to be used for new apps but intended to help apps using `unstable_HistoryRouter` migrate from v6->v7 so they can adopt the newer APIs
- `@react-router/dev` - Add a new `future.unstable_trailingSlashAwareDataRequests` flag to provide consistent behavior of `request.pathname` inside `middleware`, `loader`, and `action` functions on document and data requests when a trailing slash is present in the browser URL. ([#14644](https://github.com/remix-run/react-router/pull/14644))
- Currently, your HTTP and `request` pathnames would be as follows for `/a/b/c` and `/a/b/c/`
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
| ------------ | ----------------- | ----------------------- |
| **Document** | `/a/b/c` | `/a/b/c` ✅ |
| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
| ------------- | ----------------- | ----------------------- |
| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
| **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
- With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
| ------------ | ----------------- | ----------------------- |
| **Document** | `/a/b/c` | `/a/b/c` ✅ |
| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
| ------------- | ------------------ | ----------------------- |
| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
| **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
- This a bug fix but we are putting it behind an opt-in flag because it has the potential to be a "breaking bug fix" if you are relying on the URL format for any other application or caching logic
- Enabling this flag also changes the format of client side `.data` requests from `/_root.data` to `/_.data` when navigating to `/` to align with the new format - This does not impact the `request` pathname which is still `/` in all cases
**Full Changelog**: [`v7.11.0...v7.12.0`](https://github.com/remix-run/react-router/compare/react-router@7.11.0...react-router@7.12.0)
## v7.11.0
Date: 2025-12-17
### What's Changed
We've added `vite preview` support and stabilized the client-side `onError` API - please make the appropriate changes if you've adopted the `unstable_onError` API already in a prior release.
#### `vite preview` Support
We've added support for [`vite preview`](https://vite.dev/guide/cli#vite-preview) when using Framework mode to make it easy to preview your production build.
#### Stabilized Client-side `onError`
The existing `<RouterProvider unstable_onError>`/`<HydratedRouter unstable_onError>` APIs have been stabilized as `<RouterProvider onError>`/`<HydratedRouter onError>`. Please see the [Error Reporting](https://reactrouter.com/7.11.0/how-to/error-reporting#client-errors) docs for more information.
#### Call-site Revalidation Opt-out (unstable)
We've added initial unstable support for call-site revalidation opt-out via a new `unstable_defaultShouldRevalidate` flag ([RFC](https://github.com/remix-run/react-router/discussions/10006)). This flag is available on all navigation/fetcher submission APIs to alter standard revalidation behavior. If any routes include a `shouldRevalidate` function, then the flag value will be passed to that function so the route has the final say on revalidation behavior.
```tsx
<Form method="post" unstable_defaultShouldRevalidate={false} />
submit(data, { method: "post", unstable_defaultShouldRevalidate: false })
<fetcher.Form method="post" unstable_defaultShouldRevalidate={false} />
fetcher.submit(data, { method: "post", unstable_defaultShouldRevalidate: false })
```
This flag is also available on non-submission navigational use cases - for example, you may want to opt-out of revalidation when adding a search param that doesn't impact the UI:
```tsx
<Link to="?analytics-param=1" unstable_defaultShouldRevalidate={false} />;
navigate("?analytics-param=1", { unstable_defaultShouldRevalidate: false });
setSearchParams(params, { unstable_defaultShouldRevalidate: false });
```
### Minor Changes
- `react-router` - Stabilize `<HydratedRouter onError>`/`<RouterProvider onError>` ([#14546](https://github.com/remix-run/react-router/pull/14546))
- `@react-router/dev` - Add `vite preview` support ([#14507](https://github.com/remix-run/react-router/pull/14507))
### Patch Changes
- `react-router` - Fix `unstable_useTransitions` prop on `<Router>` component to permit omission for backwards compatibility ([#14646](https://github.com/remix-run/react-router/pull/14646))
- `react-router` - Allow redirects to be returned from client side middleware ([#14598](https://github.com/remix-run/react-router/pull/14598))
- `react-router` - Handle `dataStrategy` implementations that return insufficient result sets by adding errors for routes without any available result ([#14627](https://github.com/remix-run/react-router/pull/14627))
- `@react-router/serve` - Update `compression` and `morgan` dependencies to address `on-headers` CVE: [GHSA-76c9-3jph-rj3q](https://github.com/advisories/GHSA-76c9-3jph-rj3q) ([#14652](https://github.com/remix-run/react-router/pull/14652))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - RSC: Support for throwing `data()` and Response from server component render phase ([#14632](https://github.com/remix-run/react-router/pull/14632))
- Response body is not serialized as async work is not allowed as error encoding phase.
- If you wish to transmit data to the boundary, throw `data()` instead
- `react-router` - RSC: Support for throwing `redirect` Response's at render time ([#14596](https://github.com/remix-run/react-router/pull/14596))
- `react-router` - RSC: `routeRSCServerRequest` replace `fetchServer` with `serverResponse` ([#14597](https://github.com/remix-run/react-router/pull/14597))
- `@react-router/dev` - RSC (Framework mode): Manual chunking for `react` and `react-router` deps ([#14655](https://github.com/remix-run/react-router/pull/14655))
- `@react-router/dev` - RSC (Framework mode): Optimize `react-server-dom-webpack` if in project `package.json` ([#14656](https://github.com/remix-run/react-router/pull/14656))
- `@react-router/{dev,serve}` - RSC (Framework mode): Support custom entrypoints ([#14643](https://github.com/remix-run/react-router/pull/14643))
- `react-router` - Add a new `unstable_defaultShouldRevalidate` flag to various APIs to allow opt-ing out of standard revalidation behaviors ([#14542](https://github.com/remix-run/react-router/pull/14542))
**Full Changelog**: [`v7.10.1...v7.11.0`](https://github.com/remix-run/react-router/compare/react-router@7.10.1...react-router@7.11.0)
## v7.10.1
Date: 2025-12-04
### Patch Changes
- `react-router` - Update the `useOptimistic` stub we provide for React 18 users to use a stable setter function to avoid potential `useEffect` loops - specifically when using `<Link viewTransition>` ([#14628](https://github.com/remix-run/react-router/pull/14628))
- `@react-router/dev` - Import ESM package `pkg-types` with a dynamic `import()` to fix issues on Node 20.18 ([#14624](https://github.com/remix-run/react-router/pull/14624))
- `@react-router/dev` - Update `valibot` dependency to `^1.2.0` to address [GHSA-vqpr-j7v3-hqw9](https://github.com/advisories/GHSA-vqpr-j7v3-hqw9) ([#14608](https://github.com/remix-run/react-router/pull/14608))
**Full Changelog**: [`v7.10.0...v7.10.1`](https://github.com/remix-run/react-router/compare/react-router@7.10.0...react-router@7.10.1)
## v7.10.0
Date: 2025-12-02
### What's Changed
We've stabilized a handful of existing APIs and future flags in this release, please make the appropriate changes if you'd adopted any of these APIs in their unstable state!
#### Stabilized `future.v8_splitRouteModules`
The existing `future.unstable_splitRouteModules` flag has been stabilized as `future.v8_splitRouteModules` in `react-router.config.ts`. Please see the [docs](https://reactrouter.com/7.10.0/upgrading/future#futurev8_splitroutemodules) for more information on adopting this flag.
#### Stabilized `future.v8_viteEnvironmentApi`
The existing `future.unstable_viteEnvironmentApi` flag has been stabilized as `future.v8_viteEnvironmentApi` in `react-router.config.ts`. Please see the [docs](https://reactrouter.com/7.10.0/upgrading/future#futurev8_viteenvironmentapi) for more information on adopting this flag.
#### Stabilized `fetcher.reset()`
The existing `fetcher.unstable_reset()` API has been stabilized as `fetcher.reset()`.
#### Stabilized `DataStrategyMatch.shouldCallHandler()`
The existing low-level `DataStrategyMatch.unstable_shouldCallHandler()`/`DataStrategyMatch.unstable_shouldRevalidateArgs` APIs have been stabilized as `DataStrategyMatch.shouldCallHandler()`/`DataStrategyMatch.shouldRevalidateArgs`. Please see the [docs](https://reactrouter.com/7.10.0/how-to/data-strategy) for information about using a custom `dataStrategy` and how to migrate away from the deprecated `DataStrategyMatch.shouldLoad` API if you are using that today.
### Minor Changes
- `react-router` - Stabilize `fetcher.reset()` ([#14545](https://github.com/remix-run/react-router/pull/14545))
- ⚠️ This is a breaking change if you have begun using `fetcher.unstable_reset()` - please update your code to use `fetcher.reset()`
- `react-router` - Stabilize the `dataStrategy` `match.shouldCallHandler()`/`match.shouldRevalidateArgs` APIs ([#14592](https://github.com/remix-run/react-router/pull/14592))
- The `match.shouldLoad` API is now marked deprecated in favor of these more powerful alternatives
- ⚠️ This is a breaking change if you have begun using `match.unstable_shouldCallHandler()`/`match.unstable_shouldRevalidateArgs` - please update your code to use `match.shouldCallHandler()`/`match.shouldRevalidateArgs`
- `@react-router/dev` - Stabilize `future.v8_splitRouteModules`, replacing `future.unstable_splitRouteModules` ([#14595](https://github.com/remix-run/react-router/pull/14595))
- ⚠️ This is a breaking change if you have begun using `future.unstable_splitRouteModules` - please update your `react-router.config.ts`
- `@react-router/dev` - Stabilize `future.v8_viteEnvironmentApi`, replacing `future.unstable_viteEnvironmentApi` ([#14595](https://github.com/remix-run/react-router/pull/14595))
- ⚠️ This is a breaking change if you have begun using `future.unstable_viteEnvironmentApi` - please update your `react-router.config.ts`
### Patch Changes
- `react-router` - Fix a Framework Mode bug where the `defaultShouldRevalidate` parameter to `shouldRevalidate` would not be correct after `action` returned a 4xx/5xx response (`true` when it should have been `false`) ([#14592](https://github.com/remix-run/react-router/pull/14592))
- If your `shouldRevalidate` function relied on that parameter, you may have seen unintended revalidations
- `react-router` - Fix `fetcher.submit` failing with plain objects containing a `tagName` property ([#14534](https://github.com/remix-run/react-router/pull/14534))
- `react-router` - Fix the promise returned from `useNavigate` in Framework/Data Mode so that it properly tracks the duration of `popstate` navigations (i.e., `navigate(-1)`) ([#14524](https://github.com/remix-run/react-router/pull/14524))
- `react-router` - Preserve `statusText` on the `ErrorResponse` instance when throwing `data()` from a route handler ([#14555](https://github.com/remix-run/react-router/pull/14555))
- `react-router` - Optimize `href()` to avoid backtracking regex on splat ([#14329](https://github.com/remix-run/react-router/pull/14329))
- `@react-router/dev` - Fix internal type error in `useRoute` types that surfaces when `skipLibCheck` is disabled ([#14577](https://github.com/remix-run/react-router/pull/14577))
- `@react-router/dev` - Load environment variables before evaluating `routes.ts` ([#14446](https://github.com/remix-run/react-router/pull/14446))
- For example, you can now compute your routes based on [`VITE_`-prefixed environment variables](https://vite.dev/guide/env-and-mode#env-variables)
```ts
// app/routes.ts
import { type RouteConfig, route } from "@react-router/dev/routes";
const routes: RouteConfig = [];
// Only add the route when VITE_ENV_ROUTE is set
if (import.meta.env.VITE_ENV_ROUTE === "my-route") {
routes.push(route("my-route", "routes/my-route.tsx"));
}
export default routes;
```
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add `unstable_pattern` to the parameters for client side `unstable_onError` ([#14573](https://github.com/remix-run/react-router/pull/14573))
- `react-router` - Refactor how `unstable_onError` is called internally by `RouterProvider` to avoid potential strict mode issues ([#14573](https://github.com/remix-run/react-router/pull/14573))
- `react-router` - Add new `unstable_useTransitions` flag to routers to give users control over the usage of [`React.startTransition`](https://react.dev/reference/react/startTransition) and [`React.useOptimistic`](https://react.dev/reference/react/useOptimistic) ([#14524](https://github.com/remix-run/react-router/pull/14524))
- Please see the [docs](https://reactrouter.com/7.10.0/explanation/react-transitions) for more information
- Framework Mode + Data Mode:
- `<HydratedRouter unstable_transition>`/`<RouterProvider unstable_transition>`
- When left unset (current default behavior)
- Router state updates are wrapped in `React.startTransition`
- ⚠️ This can lead to buggy behaviors if you are wrapping your own navigations/fetchers in `React.startTransition`
- You should set the flag to `true` if you run into this scenario to get the enhanced `useOptimistic` behavior (requires React 19)
- When set to `true`
- Router state updates remain wrapped in `React.startTransition` (as they are without the flag)
- `Link`/`Form` navigations will be wrapped in `React.startTransition`
- You can drop down to `useNavigate`/`useSubmit` if you wish to opt out of this outer `React.startTransition` call for the navigation
- A subset of router state info will be surfaced to the UI _during_ navigations via `React.useOptimistic` (i.e., `useNavigation()`, `useFetchers()`, etc.)
- ⚠️ This is a React 19 API so you must also be React 19 to opt into this flag for Framework/Data Mode
- When set to `false`
- The router will not leverage `React.startTransition` or `React.useOptimistic` on any navigations or state changes
- Declarative Mode
- `<BrowserRouter unstable_useTransitions>`
- When left unset
- Router state updates are wrapped in `React.startTransition`
- When set to `true`
- Router state updates remain wrapped in `React.startTransition` (as they are without the flag)
- `Link`/`Form` navigations will be wrapped in `React.startTransition`
- When set to `false`
- The router will not leverage `React.startTransition` on any navigations or state changes
**Full Changelog**: [`v7.9.6...v7.10.0`](https://github.com/remix-run/react-router/compare/react-router@7.9.6...react-router@7.10.0)
## v7.9.6
Date: 2025-11-13
### Security Notice
This release addresses 1 security vulnerability:
- [Unexpected external redirect via untrusted paths](https://github.com/remix-run/react-router/security/advisories/GHSA-9jcx-v3wj-wh4m)
### Patch Changes
- `react-router` - Properly handle ancestor thrown middleware errors before `next()` on fetcher submissions ([#14517](https://github.com/remix-run/react-router/pull/14517))
- `react-router` - Fix issue with splat routes interfering with multiple calls to `patchRoutesOnNavigation` ([#14487](https://github.com/remix-run/react-router/pull/14487))
- `react-router` - Normalize double-slashes in `resolvePath` ([#14529](https://github.com/remix-run/react-router/pull/14529))
- `@react-router/dev` - Use a dynamic `import()` to load ESM-only `p-map` dependency to avoid issues on Node 20.18 and below ([#14492](https://github.com/remix-run/react-router/pull/14492))
- `@react-router/dev` - Short circuit `HEAD` document requests before calling `renderToPipeableStream` in the default `entry.server.tsx` to more closely align with the [spec](https://httpwg.org/specs/rfc9110.html#HEAD) ([#14488](https://github.com/remix-run/react-router/pull/14488))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add `location`/`params` as arguments to client-side `unstable_onError` to permit enhanced error reporting ([#14509](https://github.com/remix-run/react-router/pull/14509))
- ⚠️ This is a breaking change if you've already adopted `unstable_onError`
- The second parameter has changed to an object including `errorInfo`, `location`, and `params`:
```tsx
// <RouterProvider unstable_onError={errorHandler} />
// <HydratedRouter unstable_onError={errorHandler} />
// Before
function errorHandler(error: unknown, errorInfo?: React.errorInfo) {
/*...*/
}
// After
function errorHandler(
error: unknown,
info: {
location: Location;
params: Params;
errorInfo?: React.ErrorInfo;
},
) {
/*...*/
}
```
**Full Changelog**: [`v7.9.5...v7.9.6`](https://github.com/remix-run/react-router/compare/react-router@7.9.5...react-router@7.9.6)
## v7.9.5
Date: 2025-10-29
### What's Changed
#### Instrumentation (unstable)
This release adds new `unstable_instrumentation` APIs that will allow you to add runtime instrumentation logic to various aspects of your application (server handler, client navigations/fetches, loaders, actions, middleware, `route.lazy`). For more information, please see the [docs](https://reactrouter.com/7.9.5/how-to/instrumentation).
### Patch Changes
- `react-router` - Ensure action handlers run for routes with middleware even if no loader is present ([#14443](https://github.com/remix-run/react-router/pull/14443))
- `@react-router/dev` - Ensure route navigation doesn't remove CSS `link` elements used by dynamic imports ([#14463](https://github.com/remix-run/react-router/pull/14463))
- `@react-router/dev` - Typegen: only register route module types for routes within the app directory ([#14439](https://github.com/remix-run/react-router/pull/14439))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Move `unstable_RSCHydratedRouter` and utils to `react-router/dom` export ([#14457](https://github.com/remix-run/react-router/pull/14457))
- `react-router` - Add a type-safe `handle` field to `unstable_useRoute()` ([#14462](https://github.com/remix-run/react-router/pull/14462))
For example:
```ts
// app/routes/admin.tsx
const handle = { hello: "world" };
```
```ts
// app/routes/some-other-route.tsx
export default function Component() {
const admin = useRoute("routes/admin");
if (!admin) throw new Error("Not nested within 'routes/admin'");
console.log(admin.handle);
// ^? { hello: string }
}
```
- `react-router` - Add `unstable_instrumentations` API to allow users to add observability to their apps by instrumenting route loaders, actions, middlewares, lazy, as well as server-side request handlers and client side navigations/fetches ([#14412](https://github.com/remix-run/react-router/pull/14412))
- Framework Mode:
- `entry.server.tsx`: `export const unstable_instrumentations = [...]`
- `entry.client.tsx`: `<HydratedRouter unstable_instrumentations={[...]} />`
- Data Mode
- `createBrowserRouter(routes, { unstable_instrumentations: [...] })`
- `react-router` - Add a new `unstable_pattern` parameter to loaders/actions/middleware which contains the un-interpolated route pattern (i.e., `/blog/:slug`) which is useful for aggregating logs/metrics by route in instrumentation code ([#14412](https://github.com/remix-run/react-router/pull/14412))
- `@react-router/dev` - Introduce a `prerender.unstable_concurrency` option, to support running the pre-rendering concurrently, potentially speeding up the build ([#14380](https://github.com/remix-run/react-router/pull/14380))
**Full Changelog**: [`v7.9.4...v7.9.5`](https://github.com/remix-run/react-router/compare/react-router@7.9.4...react-router@7.9.5)
## v7.9.4
Date: 2025-10-08
### Security Notice
This release addresses 1 security vulnerability:
- [Unauthorized file access when using `createFileSessionStorage()` with unsigned cookies](https://github.com/remix-run/react-router/security/advisories/GHSA-9583-h5hc-x8cw)
### What's Changed
#### `useRoute()` (unstable)
This release includes a new `unstable_useRoute()` hook that provides a type-safe way to access route `loaderData`/`actionData` from a specific route in Framework Mode. Think if it like a better version of `useRouteLoaderData` that works with the typegen system and also supports `actionData`. Check out the changelog entry below for more information.
### Patch Changes
- `@react-router/dev` - Update `valibot` dependency to `^1.1.0` ([#14379](https://github.com/remix-run/react-router/pull/14379))
- `@react-router/node` - Validate format of incoming session ids in `createFileSessionStorage` ([#14426](https://github.com/remix-run/react-router/pull/14426))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - handle external redirects in from server actions ([#14400](https://github.com/remix-run/react-router/pull/14400))
- `react-router` - New (unstable) `useRoute` hook for accessing data from specific routes ([#14407](https://github.com/remix-run/react-router/pull/14407))
For example, let's say you have an `admin` route somewhere in your app and you want any child routes of `admin` to all have access to the `loaderData` and `actionData` from `admin.`
```tsx
// app/routes/admin.tsx
import { Outlet } from "react-router";
export const loader = () => ({ message: "Hello, loader!" });
export const action = () => ({ count: 1 });
export default function Component() {
return (
<div>
{/* ... */}
<Outlet />
{/* ... */}
</div>
);
}
```
You might even want to create a reusable widget that all of the routes nested under `admin` could use:
```tsx
import { unstable_useRoute as useRoute } from "react-router";
export function AdminWidget() {
// How to get `message` and `count` from `admin` route?
}
```
In framework mode, `useRoute` knows all your app's routes and gives you TS errors when invalid route IDs are passed in:
```tsx
export function AdminWidget() {
const admin = useRoute("routes/dmin");
// ^^^^^^^^^^^
}
```
`useRoute` returns `undefined` if the route is not part of the current page:
```tsx
export function AdminWidget() {
const admin = useRoute("routes/admin");
if (!admin) {
throw new Error(`AdminWidget used outside of "routes/admin"`);
}
}
```
Note: the `root` route is the exception since it is guaranteed to be part of the current page.
As a result, `useRoute` never returns `undefined` for `root`.
`loaderData` and `actionData` are marked as optional since they could be accessed before the `action` is triggered or after the `loader` threw an error:
```tsx
export function AdminWidget() {
const admin = useRoute("routes/admin");
if (!admin) {
throw new Error(`AdminWidget used outside of "routes/admin"`);
}
const { loaderData, actionData } = admin;
console.log(loaderData);
// ^? { message: string } | undefined
console.log(actionData);
// ^? { count: number } | undefined
}
```
If instead of a specific route, you wanted access to the _current_ route's `loaderData` and `actionData`, you can call `useRoute` without arguments:
```tsx
export function AdminWidget() {
const currentRoute = useRoute();
currentRoute.loaderData;
currentRoute.actionData;
}
```
This usage is equivalent to calling `useLoaderData` and `useActionData`, but consolidates all route data access into one hook: `useRoute`.
Note: when calling `useRoute()` (without a route ID), TS has no way to know which route is the current route.
As a result, `loaderData` and `actionData` are typed as `unknown`.
If you want more type-safety, you can either narrow the type yourself with something like `zod` or you can refactor your app to pass down typed props to your `AdminWidget`:
```tsx
export function AdminWidget({
message,
count,
}: {
message: string;
count: number;
}) {
/* ... */
}
```
**Full Changelog**: [`v7.9.3...v7.9.4`](https://github.com/remix-run/react-router/compare/react-router@7.9.3...react-router@7.9.4)
## v7.9.3
Date: 2025-09-26
### Patch Changes
- `react-router` - Fix Data Mode regression causing a 404 during initial load in when `middleware` exists without any `loader` functions ([#14393](https://github.com/remix-run/react-router/pull/14393))
- `react-router` - Do not try to use `turbo-stream` to decode CDN errors that never reached the server ([#14385](https://github.com/remix-run/react-router/pull/14385))
- This was logic we used to have in Remix v2 that got lost in the adoption of Single Fetch
- This permits the actual CDN error to bubble to the `ErrorBoundary` instead of a generic _"Unable to decode turbo-stream response"_ error
**Full Changelog**: [`v7.9.2...v7.9.3`](https://github.com/remix-run/react-router/compare/react-router@7.9.2...react-router@7.9.3)
## v7.9.2
Date: 2025-09-24
### What's Changed
This release contains a handful of bug fixes, but we think you'll be most excited about the new unstable stuff 😉.
#### RSC Framework Mode (unstable)
This release includes our first release of unstable support for RSC in Framework Mode! You can read more about it in our [blog post](https://remix.run/blog/rsc-framework-mode-preview) and the [docs](https://reactrouter.com/how-to/react-server-components#rsc-framework-mode).
#### Fetcher Reset (unstable)
This release also includes a new (long-requested) `fetcher.unstable_reset()` API to reset fetchers back to their initial `idle` state.
### Patch Changes
- `react-router` - Ensure client-side router runs client `middleware` during initialization data load (if required) even if no loaders exist ([#14348](https://github.com/remix-run/react-router/pull/14348))
- `react-router` - Fix `middleware` prop not being supported on `<Route>` when used with a data router via `createRoutesFromElements` ([#14357](https://github.com/remix-run/react-router/pull/14357))
- `react-router` - Update `createRoutesStub` to work with `middleware` ([#14348](https://github.com/remix-run/react-router/pull/14348))
- You will need to set the `<RoutesStub future={{ v8_middleware: true }} />` flag to enable the proper `context` type
- `react-router` - Update Lazy Route Discovery manifest requests to use a singular comma-separated `paths` query param instead of repeated `p` query params ([#14321](https://github.com/remix-run/react-router/pull/14321))
- This is because Cloudflare has a hard limit of 100 URL search param key/value pairs when used as a key for caching purposes
- If more that 100 paths were included, the cache key would be incomplete and could produce false-positive cache hits
- `react-router` - Fail gracefully on manifest version mismatch logic if `sessionStorage` access is blocked ([#14335](https://github.com/remix-run/react-router/pull/14335))
- `react-router` - Update `useOutlet` returned element to have a stable identity in-between route changes ([#13382](https://github.com/remix-run/react-router/pull/13382))
- `react-router` - Handle encoded question mark and hash characters in ancestor splat routes ([#14249](https://github.com/remix-run/react-router/pull/14249))
- `@react-router/dev` - Switch internal vite plugin Response logic to use `@remix-run/node-fetch-server` ([#13927](https://github.com/remix-run/react-router/pull/13927))
- `@react-router/dev` - Fix `presets` `future` flags being ignored during config resolution ([#14369](https://github.com/remix-run/react-router/pull/14369))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add `fetcher.unstable_reset()` API ([#14206](https://github.com/remix-run/react-router/pull/14206))
- `react-router` - In RSC Data Mode, handle SSR'd client errors and re-try in the browser ([#14342](https://github.com/remix-run/react-router/pull/14342))
- `react-router` - Enable full transition support for the RSC router ([#14362](https://github.com/remix-run/react-router/pull/14362))
- `@react-router/dev` - Add unstable support for RSC Framework Mode ([#14336](https://github.com/remix-run/react-router/pull/14336))
- `@react-router/serve` - Disable `compression()` middleware in RSC framework mode ([#14381](https://github.com/remix-run/react-router/pull/14381))
**Full Changelog**: [`v7.9.1...v7.9.2`](https://github.com/remix-run/react-router/compare/react-router@7.9.1...react-router@7.9.2)
## v7.9.1
Date: 2025-09-12
### Patch Changes
- Fix internal `Future` interface naming from `middleware` -> `v8_middleware` ([#14327](https://github.com/remix-run/react-router/pull/14327))
**Full Changelog**: [`v7.9.0...v7.9.1`](https://github.com/remix-run/react-router/compare/react-router@7.9.0...react-router@7.9.1)
## v7.9.0
Date: 2025-09-12
### Security Notice
This release addresses 1 security vulnerability:
- [XSS via Meta component when generating script:ld+json tags](https://github.com/remix-run/react-router/security/advisories/GHSA-3cgp-3xvw-98x8)
### What's Changed
#### Stable Middleware and Context APIs
We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use:
- [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider)
- [`createContext`](https://reactrouter.com/api/utils/createContext)
- `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option
- `<HydratedRouter>` [`getContext`](https://reactrouter.com/api/framework-routers/HydratedRouter#getcontext) prop
Please see the [Middleware Docs](https://reactrouter.com/how-to/middleware), the [Middleware RFC](https://github.com/remix-run/remix/discussions/7642), and the [Client-side Context RFC](https://github.com/remix-run/react-router/discussions/9856) for more information.
### Minor Changes
- Stabilize middleware and context APIs ([#14215](https://github.com/remix-run/react-router/pull/14215))
### Patch Changes
- `react-router` - Update `href()` to correctly process routes that have an extension after the parameter or are a single optional parameter ([#13797](https://github.com/remix-run/react-router/pull/13797))
- `react-router` - Escape HTML in `meta()` JSON-LD content ([#14316](https://github.com/remix-run/react-router/pull/14316))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - RSC: Add react-server `Await` component implementation ([#14261](https://github.com/remix-run/react-router/pull/14261))
- `react-router` - RSC: Fix hydration errors for routes that only have client loaders when using RSC in Data Mode along with a custom basename ([#14264](https://github.com/remix-run/react-router/pull/14264))
- `react-router` - RSC: Make `href` function available in a `react-server` context ([#14262](https://github.com/remix-run/react-router/pull/14262))
- `react-router` - RSC: Decode each time `getPayload()` is called to allow for "in-context" decoding and hoisting of contextual assets ([#14248](https://github.com/remix-run/react-router/pull/14248))
**Full Changelog**: [`v7.8.2...v7.9.0`](https://github.com/remix-run/react-router/compare/react-router@7.8.2...react-router@7.9.0)
## v7.8.2
Date: 2025-08-22
### Patch Changes
- `react-router` - Maintain `ReadonlyMap` and `ReadonlySet` types in server response data. ([#13092](https://github.com/remix-run/react-router/pull/13092))
- `react-router` - Fix `basename` usage without a leading slash in data routers ([#11671](https://github.com/remix-run/react-router/pull/11671))
- `react-router` - Fix `TypeError` if you throw from `patchRoutesOnNavigation` when no partial matches exist ([#14198](https://github.com/remix-run/react-router/pull/14198))
- `react-router` - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530))
- `@react-router/dev` - Fix potential memory leak in default `entry.server` ([#14200](https://github.com/remix-run/react-router/pull/14200))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
**Client-side `onError`**
- `react-router` - Add `<RouterProvider unstable_onError>`/`<HydratedRouter unstable_onError>` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162))
**Middleware**
- `react-router` - Delay serialization of `.data` redirects to 202 responses until after middleware chain ([#14205](https://github.com/remix-run/react-router/pull/14205))
- `react-router` - Update client middleware so it returns the `dataStrategy` results up the chain allowing for more advanced post-processing middleware ([#14151](https://github.com/remix-run/react-router/pull/14151), [#14212](https://github.com/remix-run/react-router/pull/14212))
- `react-router` - Remove Data Mode `future.unstable_middleware` flag from `createBrowserRouter` ([#14213](https://github.com/remix-run/react-router/pull/14213))
- This is only needed as a Framework Mode flag because of the route modules and the `getLoadContext` type behavior change
- In Data Mode, it's an opt-in feature because it's just a new property on a route object, so there's no behavior changes that necessitate a flag
**RSC**
- `react-router` - Allow opting out of revalidation on server actions with hidden `$SKIP_REVALIDATION` input ([#14154](https://github.com/remix-run/react-router/pull/14154))
**Full Changelog**: [`v7.8.1...v7.8.2`](https://github.com/remix-run/react-router/compare/react-router@7.8.1...react-router@7.8.2)
## v7.8.1
Date: 2025-08-15
### Patch Changes
- `react-router` - Fix usage of optional path segments in nested routes defined using absolute paths ([#14135](https://github.com/remix-run/react-router/pull/14135))
- `react-router` - Fix optional static segment matching in `matchPath` ([#11813](https://github.com/remix-run/react-router/pull/11813))
- `react-router` - Fix pre-rendering when a `basename` is set with `ssr:false` ([#13791](https://github.com/remix-run/react-router/pull/13791))
- `react-router` - Properly convert returned/thrown `data()` values to `Response` instances via `Response.json()` in resource routes and middleware ([#14159](https://github.com/remix-run/react-router/pull/14159), [#14181](https://github.com/remix-run/react-router/pull/14181))
- `@react-router/dev` - Update generated `Route.MetaArgs` type so `loaderData` is only potentially undefined when an `ErrorBoundary` export is present ([#14173](https://github.com/remix-run/react-router/pull/14173))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
**Middleware**
- `react-router` - Bubble client pre-`next` middleware errors to the shallowest ancestor that needs to load, not strictly the shallowest ancestor with a loader ([#14150](https://github.com/remix-run/react-router/pull/14150))
- `react-router` - Propagate non-redirect `Response` values thrown from middleware to the error boundary on document/data requests ([#14182](https://github.com/remix-run/react-router/pull/14182))
**RSC**
- `react-router` - Provide `isRouteErrorResponse` utility in `react-server` environments ([#14166](https://github.com/remix-run/react-router/pull/14166))
- `react-router` - Handle `meta` and `links` Route Exports in RSC Data Mode ([#14136](https://github.com/remix-run/react-router/pull/14136))
**Full Changelog**: [`v7.8.0...v7.8.1`](https://github.com/remix-run/react-router/compare/react-router@7.8.0...react-router@7.8.1)
## v7.8.0
Date: 2025-08-07
### What's Changed
#### Consistently named `loaderData` values
Ever noticed the discrepancies in loader data values handed to you by the framework? Like, we call it `loaderData` in your component props, but then `match.data` in your matches? Yeah, us too - as well as some keen-eyed React Router users who raised this in a proposal. We've added new `loaderData` fields alongside existing `data` fields in a few lingering spots to align with the `loaderData` naming used in the new `Route.*` APIs.
#### Improvements/fixes to the middleware APIs (unstable)
The biggest set of changes in `7.8.0` are to the `unstable_middleware` API's as we move closer to stabilizing them. If you've adopted the middleware APIs for early testing, please read the middleware changes below carefully. We hope to stabilize these soon so please let us know of any feedback you have on the API's in their current state!
### Minor Changes
- `react-router` - Add `nonce` prop to `Links` & `PrefetchPageLinks` ([#14048](https://github.com/remix-run/react-router/pull/14048))
- `react-router` - Add `loaderData` arguments/properties alongside existing `data` arguments/properties to provide consistency and clarity between `loaderData` and `actionData` across the board ([#14047](https://github.com/remix-run/react-router/pull/14047))
- Updated types: `Route.MetaArgs`, `Route.MetaMatch`, `MetaArgs`, `MetaMatch`, `Route.ComponentProps.matches`, `UIMatch`
- `@deprecated` warnings have been added to the existing `data` properties to point users to new `loaderData` properties, in preparation for removing the `data` properties in a future major release
### Patch Changes
- `react-router` - Prevent _"Did not find corresponding fetcher result"_ console error when navigating during a `fetcher.submit` revalidation ([#14114](https://github.com/remix-run/react-router/pull/14114))
- `react-router` - Switch Lazy Route Discovery manifest URL generation to use a standalone `URLSearchParams` instance instead of `URL.searchParams` to avoid a major performance bottleneck in Chrome ([#14084](https://github.com/remix-run/react-router/pull/14084))
- `react-router` - Adjust internal RSC usage of `React.use` to avoid Webpack compilation errors when using React 18 ([#14113](https://github.com/remix-run/react-router/pull/14113))
- `react-router` - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059))
- `react-router` - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206))
- When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary
- The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered
- ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios.
```tsx
// app/root.tsx
export function loader() {
someFunctionThatThrows(); // ❌ Throws an Error
return { title: "My Title" };
}
export function Layout({ children }: { children: React.ReactNode }) {
let matches = useMatches();
let rootMatch = matches[0] as UIMatch<Awaited<ReturnType<typeof loader>>>;
// ^ rootMatch.data is currently incorrectly typed here, so TypeScript does
// not complain if you do the following which throws an error at runtime:
let { title } = rootMatch.data; // 💥
return <html>...</html>;
}
```
- `@react-router/dev` - Fix rename without mkdir in Vite plugin ([#14105](https://github.com/remix-run/react-router/pull/14105))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
**RSC**
- `react-router` - Fix Data Mode issue where routes that return `false` from `shouldRevalidate` would be replaced by an `<Outlet />` ([#14071](https://github.com/remix-run/react-router/pull/14071))
- `react-router` - Proxy server action side-effect redirects from actions for document and `callServer` requests ([#14131](https://github.com/remix-run/react-router/pull/14131))
**Middleware**
- `react-router` - Change the `unstable_getContext` signature on `RouterProvider`, `HydratedRouter`, and `unstable_RSCHydratedRouter` so that it returns an `unstable_RouterContextProvider` instance instead of a `Map` used to construct the instance internally ([#14097](https://github.com/remix-run/react-router/pull/14097))
- See the [docs](https://reactrouter.com/api/data-routers/createBrowserRouter#optsunstable_getcontext) for more information
- ⚠️ This is a breaking change if you have adopted the `unstable_getContext` prop
- `react-router` - Run client middleware on client navigations even if no loaders exist ([#14106](https://github.com/remix-run/react-router/pull/14106))
- `react-router` - Convert internal middleware implementations to use the new `unstable_generateMiddlewareResponse` API ([#14103](https://github.com/remix-run/react-router/pull/14103))
- `react-router` - Ensure resource route errors go through `handleError` w/middleware enabled ([#14078](https://github.com/remix-run/react-router/pull/14078))
- `react-router` - Propagate returned `Response` from server middleware if `next` wasn't called ([#14093](https://github.com/remix-run/react-router/pull/14093))
- `react-router` - Allow server middlewares to return `data()` values which will be converted into a `Response` ([#14093](https://github.com/remix-run/react-router/pull/14093), [#14128](https://github.com/remix-run/react-router/pull/14128))
- `react-router` - Update middleware error handling so that the `next` function never throws and instead handles any middleware errors at the proper `ErrorBoundary` and returns the `Response` up through the ancestor `next` function ([#14118](https://github.com/remix-run/react-router/pull/14118))
- See the [error handling docs](https://reactrouter.com/how-to/middleware#next-and-error-handling) for more information
- ⚠️ This changes existing functionality so if you are currently wrapping `next` calls in `try`/`catch` you should be able to remove those
- `react-router` - Bubble client-side middleware errors prior to `next` to the appropriate ancestor error boundary ([#14138](https://github.com/remix-run/react-router/pull/14138))
- `react-router` - When middleware is enabled, make the `context` parameter read-only (`Readonly<unstable_RouterContextProvider>`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097))
- `react-router` - Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103))
- This only impacts users using `createStaticHandler()` for manual data loading during non-Framework Mode SSR
- The API has been renamed to `unstable_generateMiddlewareResponse` for clarity
- The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling
- The `query` version of the API now has a signature of `(query: (r: Request) => Promise<StaticHandlerContext | Response>) => Promise<Response>`
- The `queryRoute` version of the API now has a signature of `(queryRoute: (r: Request) => Promise<Response>) => Promise<Response>`
- This allows for more advanced usages such as running logic before/after calling `query` and direct error handling of errors thrown from query
- ⚠️ This is a breaking change if you've adopted the `staticHandler` `unstable_respond` API
```tsx
let response = await staticHandler.query(request, {
requestContext: new unstable_RouterContextProvider(),
async unstable_generateMiddlewareResponse(query) {
try {
// At this point we've run middleware top-down so we need to call the
// handlers and generate the Response to bubble back up the middleware
let result = await query(request);
if (isResponse(result)) {
return result; // Redirects, etc.
}
return await generateHtmlResponse(result);
} catch (error: unknown) {
return generateErrorResponse(error);
}
},
});
```
- `@react-router/{architect,cloudflare,express,node}` - Change the `getLoadContext` signature (`type GetLoadContextFunction`) when `future.unstable_middleware` is enabled so that it returns an `unstable_RouterContextProvider` instance instead of a `Map` used to construct the instance internally ([#14097](https://github.com/remix-run/react-router/pull/14097))
- This also removes the `type unstable_InitialContext` export
- See the [middleware `getLoadContext` docs](https://reactrouter.com/how-to/middleware#changes-to-getloadcontextapploadcontext) for more information
- ⚠️ This is a breaking change if you have adopted middleware and are using a custom server with a `getLoadContext` function
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/create-react-router/CHANGELOG.md#780)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router/CHANGELOG.md#780)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-architect/CHANGELOG.md#780)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-cloudflare/CHANGELOG.md#780)
- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-dev/CHANGELOG.md#780)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-express/CHANGELOG.md#780)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-fs-routes/CHANGELOG.md#780)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-node/CHANGELOG.md#780)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#780)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.8.0/packages/react-router-serve/CHANGELOG.md#780)
**Full Changelog**: [`v7.7.1...v7.8.0`](https://github.com/remix-run/react-router/compare/react-router@7.7.1...react-router@7.8.0)
## v7.7.1
Date: 2025-07-24
### Patch Changes
- `@react-router/dev` - Update to Prettier v3 for formatting when running `react-router reveal --no-typescript` ([#14049](https://github.com/remix-run/react-router/pull/14049))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - RSC Data Mode: fix bug where routes with errors weren't forced to revalidate when `shouldRevalidate` returned `false` ([#14026](https://github.com/remix-run/react-router/pull/14026))
- `react-router` - RSC Data Mode: fix `Matched leaf route at location "/..." does not have an element or Component` warnings when error boundaries are rendered ([#14021](https://github.com/remix-run/react-router/pull/14021))
**Full Changelog**: [`v7.7.0...v7.7.1`](https://github.com/remix-run/react-router/compare/react-router@7.7.0...react-router@7.7.1)
## v7.7.0
Date: 2025-07-16
### What's Changed
#### Unstable RSC APIs
We're excited to introduce experimental support for RSC in Data Mode via the following new APIs:
- [`unstable_RSCHydratedRouter`](https://reactrouter.com/api/rsc/RSCHydratedRouter)
- [`unstable_RSCStaticRouter`](https://reactrouter.com/api/rsc/RSCStaticRouter)
- [`unstable_createCallServer`](https://reactrouter.com/api/rsc/createCallServer)
- [`unstable_getRSCStream`](https://reactrouter.com/api/rsc/getRSCStream)
- [`unstable_matchRSCServerRequest`](https://reactrouter.com/api/rsc/matchRSCServerRequest)
- [`unstable_routeRSCServerRequest`](https://reactrouter.com/api/rsc/routeRSCServerRequest)
For more information, check out the [blog post](https://remix.run/blog/react-router-and-react-server-components) and the [RSC Docs](https://reactrouter.com/how-to/react-server-components).
### Minor Changes
- `create-react-router` - Add Deno as a supported and detectable package manager. Note that this detection will only work with Deno versions 2.0.5 and above. If you are using an older version version of Deno then you must specify the --package-manager CLI flag set to `deno`. ([#12327](https://github.com/remix-run/react-router/pull/12327))
- `@react-router/remix-config-routes-adapter` - Export `DefineRouteFunction` type alongside `DefineRoutesFunction` ([#13945](https://github.com/remix-run/react-router/pull/13945))
### Patch Changes
- `react-router` - Handle `InvalidCharacterError` when validating cookie signature ([#13847](https://github.com/remix-run/react-router/pull/13847))
- `react-router` - Pass a copy of `searchParams` to the `setSearchParams` callback function to avoid mutations of the internal `searchParams` instance ([#12784](https://github.com/remix-run/react-router/pull/12784))
- This causes bugs if you mutate the current stateful `searchParams` when a navigation is blocked because the internal instance gets out of sync with `useLocation().search`
- `react-router` - Support invalid `Date` in `turbo-stream` v2 fork ([#13684](https://github.com/remix-run/react-router/pull/13684))
- `react-router` - In Framework Mode, clear critical CSS in development after initial render ([#13872](https://github.com/remix-run/react-router/pull/13872), [#13995](https://github.com/remix-run/react-router/pull/13995))
- `react-router` - Strip search parameters from `patchRoutesOnNavigation` `path` param for fetcher calls ([#13911](https://github.com/remix-run/react-router/pull/13911))
- `react-router` - Skip scroll restoration on `useRevalidator()` calls because they're not new locations ([#13671](https://github.com/remix-run/react-router/pull/13671))
- `react-router` - Support unencoded UTF-8 routes in prerender config with `ssr` set to `false` ([#13699](https://github.com/remix-run/react-router/pull/13699))
- `react-router` - Do not throw if the url hash is not a valid URI component ([#13247](https://github.com/remix-run/react-router/pull/13247))
- `react-router` - Remove `Content-Length` header from Single Fetch responses ([#13902](https://github.com/remix-run/react-router/pull/13902))
- `react-router` - Fix a regression in `createRoutesStub` introduced with the middleware feature ([#13946](https://github.com/remix-run/react-router/pull/13946))
- As part of that work we altered the signature to align with the new middleware APIs without making it backwards compatible with the prior `AppLoadContext` API
- This permitted `createRoutesStub` to work if you were opting into middleware and the updated `context` typings, but broke `createRoutesStub` for users not yet opting into middleware
- We've reverted this change and re-implemented it in such a way that both sets of users can leverage it
- ⚠️ This may be a breaking bug for if you have adopted the unstable Middleware feature and are using `createRoutesStub` with the updated API.
```tsx
// If you have not opted into middleware, the old API should work again
let context: AppLoadContext = {
/*...*/
};
let Stub = createRoutesStub(routes, context);
// If you have opted into middleware, you should now pass an instantiated
// `unstable_routerContextProvider` instead of a `getContext` factory function.
let context = new unstable_RouterContextProvider();
context.set(SomeContext, someValue);
let Stub = createRoutesStub(routes, context);
```
- `@react-router/dev` - Update `vite-node` to `^3.2.2` to support Vite 7 ([#13781](https://github.com/remix-run/react-router/pull/13781))
- `@react-router/dev` - Properly handle `https` protocol in dev mode ([#13746](https://github.com/remix-run/react-router/pull/13746))
- `@react-router/dev` - Fix missing styles when Vite's `build.cssCodeSplit` option is disabled ([#13943](https://github.com/remix-run/react-router/pull/13943))
- `@react-router/dev` - Allow `.mts` and `.mjs` extensions for route config file ([#13931](https://github.com/remix-run/react-router/pull/13931))
- `@react-router/dev` - Fix prerender file locations when `cwd` differs from project root ([#13824](https://github.com/remix-run/react-router/pull/13824))
- `@react-router/dev` - Improve chunk error logging when a chunk cannot be found during the build ([#13799](https://github.com/remix-run/react-router/pull/13799))
- `@react-router/dev` - Fix incorrectly configured `externalConditions` which had enabled `module` condition for externals and broke builds with certain packages (like Emotion) ([#13871](https://github.com/remix-run/react-router/pull/13871))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- Add unstable RSC support for Data Mode ([#13700](https://github.com/remix-run/react-router/pull/13700))
- For more information, see the [RSC documentation](https://reactrouter.com/how-to/react-server-components)
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/create-react-router/CHANGELOG.md#770)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router/CHANGELOG.md#770)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-architect/CHANGELOG.md#770)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-cloudflare/CHANGELOG.md#770)
- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-dev/CHANGELOG.md#770)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-express/CHANGELOG.md#770)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-fs-routes/CHANGELOG.md#770)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-node/CHANGELOG.md#770)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#770)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.7.0/packages/react-router-serve/CHANGELOG.md#770)
**Full Changelog**: [`v7.6.3...v7.7.0`](https://github.com/remix-run/react-router/compare/react-router@7.6.3...react-router@7.7.0)
## v7.6.3
Date: 2025-06-27
### Patch Changes
- `react-router` - Do not serialize types for `useRouteLoaderData<typeof clientLoader>` ([#13752](https://github.com/remix-run/react-router/pull/13752))
- For types to distinguish a `clientLoader` from a `serverLoader`, you MUST annotate `clientLoader` args:
```ts
// 👇 annotation required to skip serializing types
export function clientLoader({}: Route.ClientLoaderArgs) {
return { fn: () => "earth" };
}
function SomeComponent() {
const data = useRouteLoaderData<typeof clientLoader>("routes/this-route");
const planet = data?.fn() ?? "world";
return <h1>Hello, {planet}!</h1>;
}
```
- `@react-router/cloudflare` - Remove `tsup` from `peerDependencies` ([#13757](https://github.com/remix-run/react-router/pull/13757))
- `@react-router/dev` - Add Vite 7 support ([#13748](https://github.com/remix-run/react-router/pull/13748))
- `@react-router/dev` - Skip `package.json` resolution checks when a custom `entry.server.(j|t)sx` file is provided ([#13744](https://github.com/remix-run/react-router/pull/13744))
- `@react-router/dev` - Add validation for a route's id not being 'root' ([#13792](https://github.com/remix-run/react-router/pull/13792))
- `@react-router/fs-routes` `@react-router/remix-config-routes-adapter` - Use `replaceAll` for normalizing windows file system slashes ([#13738](https://github.com/remix-run/react-router/pull/13738))
- `@react-router/node` - Remove old "install" package exports ([#13762](https://github.com/remix-run/react-router/pull/13762))
**Full Changelog**: [`v7.6.2...v7.6.3`](https://github.com/remix-run/react-router/compare/react-router@7.6.2...react-router@7.6.3)
## v7.6.2
Date: 2025-06-03
### Patch Changes
- `create-react-router` - Update `tar-fs` ([#13675](https://github.com/remix-run/react-router/pull/13675))
- `react-router` - (INTERNAL) Slight refactor of internal `headers()` function processing for use with RSC ([#13639](https://github.com/remix-run/react-router/pull/13639))
- `react-router` `@react-router/dev` - Avoid additional `with-props` chunk in Framework Mode by moving route module component prop logic from the Vite plugin to `react-router` ([#13650](https://github.com/remix-run/react-router/pull/13650))
- `@react-router/dev` - When `future.unstable_viteEnvironmentApi` is enabled and an absolute Vite `base` has been configured, ensure critical CSS is handled correctly during development ([#13598](https://github.com/remix-run/react-router/pull/13598))
- `@react-router/dev` - Update `vite-node` ([#13673](https://github.com/remix-run/react-router/pull/13673))
- `@react-router/dev` - Fix typegen for non-{.js,.jsx,.ts,.tsx} routes like .mdx ([#12453](https://github.com/remix-run/react-router/pull/12453))
- `@react-router/dev` - Fix href types for optional dynamic params ([#13725](https://github.com/remix-run/react-router/pull/13725))
7.6.1 introduced fixes for `href` when using optional static segments,
but those fixes caused regressions with how optional dynamic params worked in 7.6.0:
```ts
// 7.6.0
href("/users/:id?"); // ✅
href("/users/:id?", { id: 1 }); // ✅
// 7.6.1
href("/users/:id?"); // ❌
href("/users/:id?", { id: 1 }); // ❌
```
Now, optional static segments are expanded into different paths for `href`, but optional dynamic params are not.
This way `href` can unambiguously refer to an exact URL path, all while keeping the number of path options to a minimum.
```ts
// 7.6.2
// path: /users/:id?/edit?
href("
// ^ suggestions when cursor is here:
//
// /users/:id?
// /users/:id?/edit
```
Additionally, you can pass `params` from component props without needing to narrow them manually:
```ts
declare const params: { id?: number };
// 7.6.0
href("/users/:id?", params);
// 7.6.1
href("/users/:id?", params); // ❌
"id" in params ? href("/users/:id", params) : href("/users"); // works... but is annoying
// 7.6.2
href("/users/:id?", params); // restores behavior of 7.6.0
```
**Full Changelog**: [`v7.6.1...v7.6.2`](https://github.com/remix-run/react-router/compare/react-router@7.6.1...react-router@7.6.2)
## v7.6.1
Date: 2025-05-25
### Patch Changes
- `react-router` - Partially revert optimization added in `7.1.4` to reduce calls to `matchRoutes` because it surfaced other issues ([#13562](https://github.com/remix-run/react-router/pull/13562))
- `react-router` - Update `Route.MetaArgs` to reflect that `data` can be potentially `undefined` ([#13563](https://github.com/remix-run/react-router/pull/13563))
- This is primarily for cases where a route `loader` threw an error to it's own `ErrorBoundary`, but it also arises in the case of a 404 which renders the root `ErrorBoundary`/`meta` but the root `loader` did not run because not routes matched
- `react-router` - Avoid initial fetcher execution 404 error when Lazy Route Discovery is interrupted by a navigation ([#13564](https://github.com/remix-run/react-router/pull/13564))
- `react-router` - Properly `href` replaces splats `*` ([#13593](https://github.com/remix-run/react-router/pull/13593))
- `href("/products/*", { "*": "/1/edit" }); // -> /products/1/edit`
- `@react-router/architect` - Update `@architect/functions` from `^5.2.0` to `^7.0.0` ([#13556](https://github.com/remix-run/react-router/pull/13556))
- `@react-router/dev` - Prevent typegen with route files that are outside the `app/` directory ([#12996](https://github.com/remix-run/react-router/pull/12996))
- `@react-router/dev` - Add additional logging to `build` command output when cleaning assets from server build ([#13547](https://github.com/remix-run/react-router/pull/13547))
- `@react-router/dev` - Don't clean assets from server build when `build.ssrEmitAssets` has been enabled in Vite config ([#13547](https://github.com/remix-run/react-router/pull/13547))
- `@react-router/dev` - Fix typegen when same route is used at multiple paths ([#13574](https://github.com/remix-run/react-router/pull/13574))
- For example, `routes/route.tsx` is used at 4 different paths here:
```ts
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route("base/:base", "routes/base.tsx", [
route("home/:home", "routes/route.tsx", { id: "home" }),
route("changelog/:changelog", "routes/route.tsx", { id: "changelog" }),
route("splat/*", "routes/route.tsx", { id: "splat" }),
]),
route("other/:other", "routes/route.tsx", { id: "other" }),
] satisfies RouteConfig;
```
- Previously, typegen would arbitrarily pick one of these paths to be the "winner" and generate types for the route module based on that path
- Now, typegen creates unions as necessary for alternate paths for the same route file
- `@react-router/dev` - Better types for `params` ([#13543](https://github.com/remix-run/react-router/pull/13543))
- For example:
```ts
// routes.ts
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route("parent/:p", "routes/parent.tsx", [
route("route/:r", "routes/route.tsx", [
route("child1/:c1a/:c1b", "routes/child1.tsx"),
route("child2/:c2a/:c2b", "routes/child2.tsx"),
]),
]),
] satisfies RouteConfig;
```
- Previously, `params` for `routes/route` were calculated as `{ p: string, r: string }`.
- This incorrectly ignores params that could come from child routes
- If visiting `/parent/1/route/2/child1/3/4`, the actual params passed to `routes/route` will have a type of `{ p: string, r: string, c1a: string, c1b: string }`
- Now, `params` are aware of child routes and autocompletion will include child params as optionals:
```ts
params.|
// ^ cursor is here and you ask for autocompletion
// p: string
// r: string
// c1a?: string
// c1b?: string
// c2a?: string
// c2b?: string
```
- You can also narrow the types for `params` as it is implemented as a normalized union of params for each page that includes `routes/route`:
```ts
if (typeof params.c1a === 'string') {
params.|
// ^ cursor is here and you ask for autocompletion
// p: string
// r: string
// c1a: string
// c1b: string
}
```
- `@react-router/dev` - Fix `href` for optional segments ([#13595](https://github.com/remix-run/react-router/pull/13595))
- Type generation now expands paths with optionals into their corresponding non-optional paths
- For example, the path `/user/:id?` gets expanded into `/user` and `/user/:id` to more closely model visitable URLs
- `href` then uses these expanded (non-optional) paths to construct type-safe paths for your app:
```ts
// original: /user/:id?
// expanded: /user & /user/:id
href("/user"); // ✅
href("/user/:id", { id: 1 }); // ✅
```
- This becomes even more important for static optional paths where there wasn't a good way to indicate whether the optional should be included in the resulting path:
```ts
// original: /products/:id/detail?
// before
href("/products/:id/detail?"); // ❌ How can we tell `href` to include or omit `detail?` segment with a complex API?
// now
// expanded: /products/:id & /products/:id/detail
href("/product/:id"); // ✅
href("/product/:id/detail"); // ✅
```
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `@react-router/dev` - Renamed internal `react-router/route-module` export to `react-router/internal` ([#13543](https://github.com/remix-run/react-router/pull/13543))
- `@react-router/dev` - Removed `Info` export from generated `+types/*` files ([#13543](https://github.com/remix-run/react-router/pull/13543))
- `@react-router/dev` - Normalize dirent entry path across node versions when generating SRI manifest ([#13591](https://github.com/remix-run/react-router/pull/13591))
**Full Changelog**: [`v7.6.0...v7.6.1`](https://github.com/remix-run/react-router/compare/react-router@7.6.0...react-router@7.6.1)
## v7.6.0
Date: 2025-05-08
### What's Changed
#### `routeDiscovery` Config Option
We've added a new config option in `7.6.0` which grants you more control over the Lazy Route Discovery feature. You can now configure the `/__manifest` path if you're running multiple RR applications on the same server, or you can also disable the feature entirely if your application is small enough and the feature isn't necessary.
```ts
// react-router.config.ts
export default {
// You can modify the manifest path used:
routeDiscovery: { mode: "lazy", manifestPath: "/custom-manifest" }
// Or you can disable this feature entirely and include all routes in the
// manifest on initial document load:
routeDiscovery: { mode: "initial" }
// If you don't specify anything, the default config is as follows, which enables
// Lazy Route Discovery and makes manifest requests to the `/__manifest` path:
// routeDiscovery: { mode: "lazy", manifestPath: "/__manifest" }
} satisfies Config;
```
#### Automatic Types for Future Flags
Some future flags alter the way types should work in React Router. Previously, you had to remember to manually opt-in to the new types. For example, for `future.unstable_middleware`:
```ts
// react-router.config.ts
// Step 1: Enable middleware
export default {
future: {
unstable_middleware: true,
},
};
// Step 2: Enable middleware types
declare module "react-router" {
interface Future {
unstable_middleware: true; // 👈 Enable middleware types
}
}
```
It was up to you to keep the runtime future flags synced with the types for those flags. This was confusing and error-prone.
Now, React Router will automatically enable types for future flags. That means you only need to specify the runtime future flag:
```ts
// react-router.config.ts
// Step 1: Enable middleware
export default {
future: {
unstable_middleware: true,
},
};
// No step 2! That's it!
```
Behind the scenes, React Router will generate the corresponding `declare module` into `.react-router/types`. Currently this is done in `.react-router/types/+register.ts` but this is an implementation detail that may change in the future.
### Minor Changes
- `react-router` - Added a new `routeDiscovery` option in `react-router.config.ts` to configure Lazy Route Discovery behavior ([#13451](https://github.com/remix-run/react-router/pull/13451))
- `react-router` - Add support for route component props in `createRoutesStub` ([#13528](https://github.com/remix-run/react-router/pull/13528))
- This allows you to unit test your route components using the props instead of the hooks:
```tsx
let RoutesStub = createRoutesStub([
{
path: "/",
Component({ loaderData }) {
let data = loaderData as { message: string };
return <pre data-testid="data">Message: {data.message}</pre>;
},
loader() {
return { message: "hello" };
},
},
]);
render(<RoutesStub />);
await waitFor(() => screen.findByText("Message: hello"));
```
- `@react-router/dev` - Automatic types for future flags ([#13506](https://github.com/remix-run/react-router/pull/13506))
### Patch Changes
You may notice this list is a bit larger than usual! The team ate their vegetables last week and spent the week [squashing bugs](https://x.com/BrooksLybrand/status/1918406062920589731) to work on lowering the issue count that had ballooned a bit since the v7 release.
- `react-router` - Fix `react-router` module augmentation for `NodeNext` ([#13498](https://github.com/remix-run/react-router/pull/13498))
- `react-router` - Don't bundle `react-router` in `react-router/dom` CJS export ([#13497](https://github.com/remix-run/react-router/pull/13497))
- `react-router` - Fix bug where a submitting `fetcher` would get stuck in a `loading` state if a revalidating `loader` redirected ([#12873](https://github.com/remix-run/react-router/pull/12873))
- `react-router` - Fix hydration error if a server `loader` returned `undefined` ([#13496](https://github.com/remix-run/react-router/pull/13496))
- `react-router` - Fix initial load 404 scenarios in data mode ([#13500](https://github.com/remix-run/react-router/pull/13500))
- `react-router` - Stabilize `useRevalidator`'s `revalidate` function ([#13542](https://github.com/remix-run/react-router/pull/13542))
- `react-router` - Preserve status code if a `clientAction` throws a `data()` result in framework mode ([#13522](https://github.com/remix-run/react-router/pull/13522))
- `react-router` - Be defensive against leading double slashes in paths to avoid `Invalid URL` errors from the URL constructor ([#13510](https://github.com/remix-run/react-router/pull/13510))
- Note we do not sanitize/normalize these paths - we only detect them so we can avoid the error that would be thrown by `new URL("//", window.location.origin)`
- `react-router` - Remove `Navigator` declaration for `navigator.connection.saveData` to avoid messing with any other types beyond `saveData` in user land ([#13512](https://github.com/remix-run/react-router/pull/13512))
- `react-router` - Fix `handleError` `params` values on `.data` requests for routes with a dynamic param as the last URL segment ([#13481](https://github.com/remix-run/react-router/pull/13481))
- `react-router` - Don't trigger an `ErrorBoundary` UI before the reload when we detect a manifest version mismatch in Lazy Route Discovery ([#13480](https://github.com/remix-run/react-router/pull/13480))
- `react-router` - Inline `turbo-stream@2.4.1` dependency and fix decoding ordering of `Map`/`Set` instances ([#13518](https://github.com/remix-run/react-router/pull/13518))
- `react-router` - Only render dev warnings during dev ([#13461](https://github.com/remix-run/react-router/pull/13461))
- `react-router` - Short circuit post-processing on aborted `dataStrategy` requests ([#13521](https://github.com/remix-run/react-router/pull/13521))
- This resolves non-user-facing console errors of the form `Cannot read properties of undefined (reading 'result')`
- `@react-router/dev` - Support project root directories without a `package.json` if it exists in a parent directory ([#13472](https://github.com/remix-run/react-router/pull/13472))
- `@react-router/dev` - When providing a custom Vite config path via the CLI `--config`/`-c` flag, default the project root directory to the directory containing the Vite config when not explicitly provided ([#13472](https://github.com/remix-run/react-router/pull/13472))
- `@react-router/dev` - In a `routes.ts` context, ensure the `--mode` flag is respected for `import.meta.env.MODE` ([#13485](https://github.com/remix-run/react-router/pull/13485))
- Previously, `import.meta.env.MODE` within a `routes.ts` context was always `"development"` for the `dev` and `typegen --watch` commands, but otherwise resolved to `"production"`. These defaults are still in place, but if a `--mode` flag is provided, this will now take precedence.
- `@react-router/dev` - Ensure consistent project root directory resolution logic in CLI commands ([#13472](https://github.com/remix-run/react-router/pull/13472))
- `@react-router/dev` - When executing `react-router.config.ts` and `routes.ts` with `vite-node`, ensure that PostCSS config files are ignored ([#13489](https://github.com/remix-run/react-router/pull/13489))
- `@react-router/dev` - When extracting critical CSS during development, ensure it's loaded from the client environment to avoid issues with plugins that handle the SSR environment differently ([#13503](https://github.com/remix-run/react-router/pull/13503))
- `@react-router/dev` - Fix "Status message is not supported by HTTP/2" error during dev when using HTTPS ([#13460](https://github.com/remix-run/react-router/pull/13460))
- `@react-router/dev` - Update config when `react-router.config.ts` is created or deleted during development ([#12319](https://github.com/remix-run/react-router/pull/12319))
- `@react-router/dev` - Skip unnecessary `routes.ts` evaluation before Vite build is started ([#13513](https://github.com/remix-run/react-router/pull/13513))
- `@react-router/dev` - Fix `TS2300: Duplicate identifier` errors caused by generated types ([#13499](https://github.com/remix-run/react-router/pull/13499))
- Previously, routes that had the same full path would cause duplicate entries in the generated types for `href` (`.react-router/types/+register.ts`), causing type checking errors
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Fix a few bugs with error bubbling in middleware use-cases ([#13538](https://github.com/remix-run/react-router/pull/13538))
- `@react-router/dev` - When `future.unstable_viteEnvironmentApi` is enabled, ensure that `build.assetsDir` in Vite config is respected when `environments.client.build.assetsDir` is not configured ([#13491](https://github.com/remix-run/react-router/pull/13491))
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/create-react-router/CHANGELOG.md#760)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router/CHANGELOG.md#760)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-architect/CHANGELOG.md#760)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-cloudflare/CHANGELOG.md#760)
- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-dev/CHANGELOG.md#760)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-express/CHANGELOG.md#760)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-fs-routes/CHANGELOG.md#760)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-node/CHANGELOG.md#760)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#760)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.6.0/packages/react-router-serve/CHANGELOG.md#760)
**Full Changelog**: [`v7.5.3...v7.6.0`](https://github.com/remix-run/react-router/compare/react-router@7.5.3...react-router@7.6.0)
## v7.5.3
Date: 2025-04-28
### Patch Changes
- `react-router` - Fix bug where bubbled action errors would result in `loaderData` being cleared at the handling `ErrorBoundary` route ([#13476](https://github.com/remix-run/react-router/pull/13476))
- `react-router` - Handle redirects from `clientLoader.hydrate` initial load executions ([#13477](https://github.com/remix-run/react-router/pull/13477))
**Full Changelog**: [`v7.5.2...v7.5.3`](https://github.com/remix-run/react-router/compare/react-router@7.5.2...react-router@7.5.3)
## v7.5.2
Date: 2025-04-24
### Security Notice
Fixed 2 security vulnerabilities that could result in cache-poisoning attacks by sending specific headers intended for build-time usage for SPA Mode and Pre-rendering ([GHSA-f46r-rw29-r322](https://github.com/remix-run/react-router/security/advisories/GHSA-f46r-rw29-r322), [GHSA-cpj6-fhp6-mr6j](https://github.com/remix-run/react-router/security/advisories/GHSA-cpj6-fhp6-mr6j)).
### Patch Changes
- `react-router` - Adjust approach for Pre-rendering/SPA Mode via headers ([#13453](https://github.com/remix-run/react-router/pull/13453))
- `react-router` - Update Single Fetch to also handle the 204 redirects used in `?_data` requests in Remix v2 ([#13364](https://github.com/remix-run/react-router/pull/13364))
- This allows applications to trigger a redirect on `.data` requests from outside the scope of React Router (i.e., an `express`/`hono` middleware) the same way they did in Remix v2 before Single Fetch was implemented
- This is a bit of an escape hatch - the recommended way to handle this is redirecting from a root route middleware
- To use this functionality, you may return from a `.data` request wih a response as follows:
- Set a 204 status code
- Set an `X-Remix-Redirect: <new-location>` header
- Optionally, set `X-Remix-Replace: true` or `X-Remix-Reload-Document: true` headers to replicate `replace()`/`redirectDocument()` functionality
- ⚠️ Please note that these responses rely on implementation details that are subject to change without a SemVer major release, and it is recommended you set up integration tests for your application to confirm this functionality is working correctly with each future React Router upgrade
**Full Changelog**: [`v7.5.1...v7.5.2`](https://github.com/remix-run/react-router/compare/react-router@7.5.1...react-router@7.5.2)
## v7.5.1
Date: 2025-04-17
### Patch Changes
- `react-router` - When using the object-based `route.lazy` API, the `HydrateFallback` and `hydrateFallbackElement` properties are now skipped when lazy loading routes after hydration ([#13376](https://github.com/remix-run/react-router/pull/13376))
- If you move the code for these properties into a separate file, since the hydrate properties were unused already (if the route wasn't present during hydration), you can avoid downloading them at all. For example:
```ts
createBrowserRouter([
{
path: "/show/:showId",
lazy: {
loader: async () => (await import("./show.loader.js")).loader,
Component: async () =>
(await import("./show.component.js")).Component,
HydrateFallback: async () =>
(await import("./show.hydrate-fallback.js")).HydrateFallback,
},
},
]);
```
- `react-router` - Fix single fetch bug where no revalidation request would be made when navigating upwards to a reused parent route ([#13253](https://github.com/remix-run/react-router/pull/13253))
- `react-router` - Properly revalidate pre-rendered paths when param values change when using `ssr:false` + `prerender` configs ([#13380](https://github.com/remix-run/react-router/pull/13380))
- `react-router` - Fix pre-rendering when a loader returns a redirect ([#13365](https://github.com/remix-run/react-router/pull/13365))
- `react-router` - Do not automatically add `null` to `staticHandler.query()` `context.loaderData` if routes do not have loaders ([#13223](https://github.com/remix-run/react-router/pull/13223))
- This was a Remix v2 implementation detail inadvertently left in for React Router v7
- Now that we allow returning `undefined` from loaders, our prior check of `loaderData[routeId] !== undefined` was no longer sufficient and was changed to a `routeId in loaderData` check - these `null` values can cause issues for this new check
- ⚠️ This could be a "breaking bug fix" for you if you are doing manual SSR with `createStaticHandler()`/`<StaticRouterProvider>`, and using `context.loaderData` to control `<RouterProvider>` hydration behavior on the client
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add better error messaging when `getLoadContext` is not updated to return a `Map` ([#13242](https://github.com/remix-run/react-router/pull/13242))
- `react-router` - Update context type for `LoaderFunctionArgs`/`ActionFunctionArgs` when middleware is enabled ([#13381](https://github.com/remix-run/react-router/pull/13381))
- `react-router` - Add a new `unstable_runClientMiddleware` argument to `dataStrategy` to enable middleware execution in custom `dataStrategy` implementations ([#13395](https://github.com/remix-run/react-router/pull/13395))
- `react-router` - Add support for the new `unstable_shouldCallHandler`/`unstable_shouldRevalidateArgs` APIs in `dataStrategy` ([#13253](https://github.com/remix-run/react-router/pull/13253))
**Full Changelog**: [`v7.5.0...v7.5.1`](https://github.com/remix-run/react-router/compare/react-router@7.5.0...react-router@7.5.1)
## v7.5.0
Date: 2025-04-04
### What's Changed
#### `route.lazy` Object API
We've introduced a new `route.lazy` API which gives you more granular control over the lazy loading of route properties that you could not achieve with the `route.lazy()` function signature. This is useful for Framework mode and performance-critical library mode applications.
```ts
createBrowserRouter([
{
path: "/show/:showId",
lazy: {
loader: async () => (await import("./show.loader.js")).loader,
action: async () => (await import("./show.action.js")).action,
Component: async () => (await import("./show.component.js")).Component,
},
},
]);
```
⚠️ This is a breaking change if you have adopted the `route.unstable_lazyMiddleware` API which has been removed in favor of `route.lazy.unstable_middleware`. See the `Unstable Changes` section below for more information.
### Minor Changes
- `react-router` - Add granular object-based API for `route.lazy` to support lazy loading of individual route properties ([#13294](https://github.com/remix-run/react-router/pull/13294))
### Patch Changes
- `@react-router/dev` - Update optional `wrangler` peer dependency range to support `wrangler` v4 ([#13258](https://github.com/remix-run/react-router/pull/13258))
- `@react-router/dev` - Reinstate dependency optimization in the child compiler to fix `depsOptimizer is required in dev mode` errors when using `vite-plugin-cloudflare` and importing Node.js builtins ([#13317](https://github.com/remix-run/react-router/pull/13317))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Introduce `future.unstable_subResourceIntegrity` flag that enables generation of an `importmap` with `integrity` for the scripts that will be loaded by the browser ([#13163](https://github.com/remix-run/react-router/pull/13163))
- `react-router` - Remove support for the `route.unstable_lazyMiddleware` property ([#13294](https://github.com/remix-run/react-router/pull/13294))
- In order to lazily load middleware, you can use the new object-based `route.lazy.unstable_middleware` API
- `@react-router/dev` - When `future.unstable_viteEnvironmentApi` is enabled, ensure critical CSS in development works when using a custom Vite `base` has been configured ([#13305](https://github.com/remix-run/react-router/pull/13305))
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/create-react-router/CHANGELOG.md#750)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router/CHANGELOG.md#750)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-architect/CHANGELOG.md#750)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-cloudflare/CHANGELOG.md#750)
- [`@react-router/dev`](http://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-dev/CHANGELOG.md#750)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-express/CHANGELOG.md#750)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-fs-routes/CHANGELOG.md#750)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-node/CHANGELOG.md#750)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#750)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.5.0/packages/react-router-serve/CHANGELOG.md#750)
**Full Changelog**: [`v7.4.1...v7.5.0`](https://github.com/remix-run/react-router/compare/react-router@7.4.1...react-router@7.5.0)
## v7.4.1
Date: 2025-03-28
### Security Notice
Fixed a security vulnerability that allowed URL manipulation and potential cache pollution via the `Host` and `X-Forwarded-Host` headers due to inadequate port sanitization ([GHSA-4q56-crqp-v477/CVE-2025-31137](https://github.com/remix-run/react-router/security/advisories/GHSA-4q56-crqp-v477)).
### Patch Changes
- `react-router` - Dedupe calls to `route.lazy` functions ([#13260](https://github.com/remix-run/react-router/pull/13260))
- `@react-router/dev` - Fix path in prerender error messages ([#13257](https://github.com/remix-run/react-router/pull/13257))
- `@react-router/dev` - Fix typegen for virtual modules when `moduleDetection` is set to `force` ([#13267](https://github.com/remix-run/react-router/pull/13267))
- `@react-router/express` - Better validation of `x-forwarded-host` header to prevent potential security issues ([#13309](https://github.com/remix-run/react-router/pull/13309))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Fix types on `unstable_MiddlewareFunction` to avoid type errors when a middleware doesn't return a value ([#13311](https://github.com/remix-run/react-router/pull/13311))
- `react-router` - Add support for `route.unstable_lazyMiddleware` function to allow lazy loading of middleware logic ([#13210](https://github.com/remix-run/react-router/pull/13210))
- ⚠️ We do not recommend adoption of this API currently as we are likely going to change it prior to the stable release of middleware
- ⚠️ This may be a breaking change if your app is currently returning `unstable_middleware` from `route.lazy`
- The `route.unstable_middleware` property is no longer supported in the return value from `route.lazy`
- If you want to lazily load middleware, you must use `route.unstable_lazyMiddleware`
- `@react-router/dev` - When both `future.unstable_middleware` and `future.unstable_splitRouteModules` are enabled, split `unstable_clientMiddleware` route exports into separate chunks when possible ([#13210](https://github.com/remix-run/react-router/pull/13210))
- `@react-router/dev` - Improve performance of `future.unstable_middleware` by ensuring that route modules are only blocking during the middleware phase when the `unstable_clientMiddleware` has been defined ([#13210](https://github.com/remix-run/react-router/pull/13210))
**Full Changelog**: [`v7.4.0...v7.4.1`](https://github.com/remix-run/react-router/compare/react-router@7.4.0...react-router@7.4.1)
## v7.4.0
Date: 2025-03-19
### Minor Changes
- `@react-router/dev` - Generate types for `virtual:react-router/server-build` module ([#13152](https://github.com/remix-run/react-router/pull/13152))
### Patch Changes
- `react-router` - Fix root loader data on initial load redirects in SPA mode ([#13222](https://github.com/remix-run/react-router/pull/13222))
- `react-router` - Load ancestor pathless/index routes in lazy route discovery for upwards non-eager-discovery routing ([#13203](https://github.com/remix-run/react-router/pull/13203))
- `react-router` - Fix `shouldRevalidate` behavior for `clientLoader`-only routes in `ssr:true` apps ([#13221](https://github.com/remix-run/react-router/pull/13221))
- `@react-router/dev` - Fix conflicts with other Vite plugins that use the `configureServer` and/or `configurePreviewServer` hooks ([#13184](https://github.com/remix-run/react-router/pull/13184))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - If a middleware throws an error, ensure we only bubble the error itself via `next()` and are no longer leaking the `MiddlewareError` implementation detail ([#13180](https://github.com/remix-run/react-router/pull/13180))
- ⚠️ This may be a breaking change if you are `catch`-ing errors thrown by the `next()` function in your middlewares
- `react-router` - Fix `RequestHandler` `loadContext` parameter type when middleware is enabled ([#13204](https://github.com/remix-run/react-router/pull/13204))
- `react-router` - Update `Route.unstable_MiddlewareFunction` to have a return value of `Response | undefined` instead of `Response | void` ([#13199](https://github.com/remix-run/react-router/pull/13199))
- `@react-router/dev` - When `future.unstable_splitRouteModules` is set to `"enforce"`, allow both splittable and unsplittable root route exports since it's always in a single chunk ([#13238](https://github.com/remix-run/react-router/pull/13238))
- `@react-router/dev` - When `future.unstable_viteEnvironmentApi` is enabled, allow plugins that override the default SSR environment (such as `@cloudflare/vite-plugin`) to be placed before or after the React Router plugin ([#13183](https://github.com/remix-run/react-router/pull/13183))
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/create-react-router/CHANGELOG.md#740)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router/CHANGELOG.md#740)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-architect/CHANGELOG.md#740)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-cloudflare/CHANGELOG.md#740)
- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-dev/CHANGELOG.md#740)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-express/CHANGELOG.md#740)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-fs-routes/CHANGELOG.md#740)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-node/CHANGELOG.md#740)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#740)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.4.0/packages/react-router-serve/CHANGELOG.md#740)
**Full Changelog**: [`v7.3.0...v7.4.0`](https://github.com/remix-run/react-router/compare/react-router@7.3.0...react-router@7.4.0)
## v7.3.0
Date: 2025-03-06
### Minor Changes
- Add `fetcherKey` as a parameter to `patchRoutesOnNavigation` ([#13061](https://github.com/remix-run/react-router/pull/13061))
### Patch Changes
- `react-router` - Detect and handle manifest-skew issues on new deploys during active sessions ([#13061](https://github.com/remix-run/react-router/pull/13061))
- In framework mode, Lazy Route Discovery will now detect manifest version mismatches in active sessions after a new deploy
- On navigations to undiscovered routes, this mismatch will trigger a document reload of the destination path
- On `fetcher` calls to undiscovered routes, this mismatch will trigger a document reload of the current path
- `react-router` - Skip resource route flow in dev server in SPA mode ([#13113](https://github.com/remix-run/react-router/pull/13113))
- `react-router` - Fix single fetch `_root.data` requests when a `basename` is used ([#12898](https://github.com/remix-run/react-router/pull/12898))
- `react-router` - Fix types for `loaderData` and `actionData` that contained `Record`s ([#13139](https://github.com/remix-run/react-router/pull/13139))
- ⚠️ This is a breaking change for users who have already adopted `unstable_SerializesTo` - see the note in the `Unstable Changes` section below for more information
- `@react-router/dev` - Fix support for custom client `build.rollupOptions.output.entryFileNames` ([#13098](https://github.com/remix-run/react-router/pull/13098))
- `@react-router/dev` - Fix usage of `prerender` option when `serverBundles` option has been configured or provided by a preset, e.g. `vercelPreset` from `@vercel/react-router` ([#13082](https://github.com/remix-run/react-router/pull/13082))
- `@react-router/dev` - Fix support for custom `build.assetsDir` ([#13077](https://github.com/remix-run/react-router/pull/13077))
- `@react-router/dev` - Remove unused dependencies ([#13134](https://github.com/remix-run/react-router/pull/13134))
- `@react-router/dev` - Stub all routes except root in "SPA Mode" server builds to avoid issues when route modules or their dependencies import non-SSR-friendly modules ([#13023](https://github.com/remix-run/react-router/pull/13023))
- `@react-router/dev` - Remove unused Vite file system watcher ([#13133](https://github.com/remix-run/react-router/pull/13133))
- `@react-router/dev` - Fix support for custom SSR build input when `serverBundles` option has been configured ([#13107](https://github.com/remix-run/react-router/pull/13107))
- ⚠️ Note that for consumers using the `future.unstable_viteEnvironmentApi` and `serverBundles` options together, hyphens are no longer supported in server bundle IDs since they also need to be valid Vite environment names.
- `@react-router/dev` - Fix dev server when using HTTPS by stripping HTTP/2 pseudo headers from dev server requests ([#12830](https://github.com/remix-run/react-router/pull/12830))
- `@react-router/dev` - Lazy load Cloudflare platform proxy on first dev server request when using the `cloudflareDevProxy` Vite plugin to avoid creating unnecessary `workerd` processes ([#13016](https://github.com/remix-run/react-router/pull/13016))
- `@react-router/dev` - Fix duplicated entries in typegen for layout routes and their corresponding index route ([#13140](https://github.com/remix-run/react-router/pull/13140))
- `@react-router/express` - Update `express` `peerDependency` to include v5 (https://github.com/remix-run/react-router/pull/13064) ([#12961](https://github.com/remix-run/react-router/pull/12961))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add `context` support to client side data routers (unstable) ([#12941](https://github.com/remix-run/react-router/pull/12941))
- `react-router` - Support middleware on routes (unstable) ([#12941](https://github.com/remix-run/react-router/pull/12941))
- `@react-router/dev` - Fix errors with `future.unstable_viteEnvironmentApi` when the `ssr` environment has been configured by another plugin to be a custom `Vite.DevEnvironment` rather than the default `Vite.RunnableDevEnvironment` ([#13008](https://github.com/remix-run/react-router/pull/13008))
- `@react-router/dev` - When `future.unstable_viteEnvironmentApi` is enabled and the `ssr` environment has `optimizeDeps.noDiscovery` disabled, define `optimizeDeps.entries` and `optimizeDeps.include` ([#13007](https://github.com/remix-run/react-router/pull/13007))
#### Client-side `context` (unstable)
Your application `clientLoader`/`clientAction` functions (or `loader`/`action` in library mode) will now receive a `context` parameter on the client. This is an instance of `unstable_RouterContextProvider` that you use with type-safe contexts (similar to `React.createContext`) and is most useful with the corresponding `unstable_clientMiddleware` API:
```ts
import { unstable_createContext } from "react-router";
type User = {
/*...*/
};
const userContext = unstable_createContext<User>();
const sessionMiddleware: Route.unstable_ClientMiddlewareFunction = async ({
context,
}) => {
let user = await getUser();
context.set(userContext, user);
};
export const unstable_clientMiddleware = [sessionMiddleware];
export function clientLoader({ context }: Route.ClientLoaderArgs) {
let user = context.get(userContext);
let profile = await getProfile(user.id);
return { profile };
}
```
Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app:
- Library mode - `createBrowserRouter(routes, { unstable_getContext })`
- Framework mode - `<HydratedRouter unstable_getContext>`
This function should return an value of type `unstable_InitialContext` which is a `Map<unstable_RouterContext, unknown>` of context's and initial values:
```ts
const loggerContext = unstable_createContext<(...args: unknown[]) => void>();
function logger(...args: unknown[]) {
console.log(new Date.toISOString(), ...args);
}
function unstable_getContext() {
let map = new Map();
map.set(loggerContext, logger);
return map;
}
```
#### Middleware (unstable)
Middleware is implemented behind a `future.unstable_middleware` flag. To enable, you must enable the flag and the types in your `react-router.config.ts` file:
```ts
import type { Config } from "@react-router/dev/config";
import type { Future } from "react-router";
declare module "react-router" {
interface Future {
unstable_middleware: true; // 👈 Enable middleware types
}
}
export default {
future: {
unstable_middleware: true, // 👈 Enable middleware
},
} satisfies Config;
```
⚠️ Middleware is unstable and should not be adopted in production. There is at least one known de-optimization in route module loading for `clientMiddleware` that we will be addressing this before a stable release.
⚠️ Enabling middleware contains a breaking change to the `context` parameter passed to your `loader`/`action` functions - see below for more information.
Once enabled, routes can define an array of middleware functions that will run sequentially before route handlers run. These functions accept the same parameters as `loader`/`action` plus an additional `next` parameter to run the remaining data pipeline. This allows middlewares to perform logic before and after handlers execute.
```tsx
// Framework mode
export const unstable_middleware = [serverLogger, serverAuth]; // server
export const unstable_clientMiddleware = [clientLogger]; // client
// Library mode
const routes = [
{
path: "/",
// Middlewares are client-side for library mode SPA's
unstable_middleware: [clientLogger, clientAuth],
loader: rootLoader,
Component: Root,
},
];
```
Here's a simple example of a client-side logging middleware that can be placed on the root route:
```tsx
const clientLogger: Route.unstable_ClientMiddlewareFunction = async (
{ request },
next,
) => {
let start = performance.now();
// Run the remaining middlewares and all route loaders
await next();
let duration = performance.now() - start;
console.log(`Navigated to ${request.url} (${duration}ms)`);
};
```
Note that in the above example, the `next`/`middleware` functions don't return anything. This is by design as on the client there is no "response" to send over the network like there would be for middlewares running on the server. The data is all handled behind the scenes by the stateful `router`.
For a server-side middleware, the `next` function will return the HTTP `Response` that React Router will be sending across the wire, thus giving you a chance to make changes as needed. You may throw a new response to short circuit and respond immediately, or you may return a new or altered response to override the default returned by `next()`.
```tsx
const serverLogger: Route.unstable_MiddlewareFunction = async (
{ request, params, context },
next,
) => {
let start = performance.now();
// 👇 Grab the response here
let res = await next();
let duration = performance.now() - start;
console.log(`Navigated to ${request.url} (${duration}ms)`);
// 👇 And return it here (optional if you don't modify the response)
return res;
};
```
You can throw a `redirect` from a middleware to short circuit any remaining processing:
```tsx
import { sessionContext } from "../context";
const serverAuth: Route.unstable_MiddlewareFunction = (
{ request, params, context },
next,
) => {
let session = context.get(sessionContext);
let user = session.get("user");
if (!user) {
session.set("returnTo", request.url);
throw redirect("/login", 302);
}
};
```
_Note that in cases like this where you don't need to do any post-processing you don't need to call the `next` function or return a `Response`._
Here's another example of using a server middleware to detect 404s and check the CMS for a redirect:
```tsx
const redirects: Route.unstable_MiddlewareFunction = async ({
request,
next,
}) => {
// attempt to handle the request
let res = await next();
// if it's a 404, check the CMS for a redirect, do it last
// because it's expensive
if (res.status === 404) {
let cmsRedirect = await checkCMSRedirects(request.url);
if (cmsRedirect) {
throw redirect(cmsRedirect, 302);
}
}
return res;
};
```
For more information on the `middleware` API/design, please see the [decision doc](https://github.com/remix-run/react-router/blob/release-next/decisions/0014-context-middleware.md).
##### Middleware `context` parameter
When middleware is enabled, your application will use a different type of `context` parameter in your loaders and actions to provide better type safety. Instead of `AppLoadContext`, `context` will now be an instance of `ContextProvider` that you can use with type-safe contexts (similar to `React.createContext`):
```ts
import { unstable_createContext } from "react-router";
import { Route } from "./+types/root";
import type { Session } from "./sessions.server";
import { getSession } from "./sessions.server";
let sessionContext = unstable_createContext<Session>();
const sessionMiddleware: Route.unstable_MiddlewareFunction = ({
context,
request,
}) => {
let session = await getSession(request);
context.set(sessionContext, session);
// ^ must be of type Session
};
// ... then in some downstream middleware
const loggerMiddleware: Route.unstable_MiddlewareFunction = ({
context,
request,
}) => {
let session = context.get(sessionContext);
// ^ typeof Session
console.log(session.get("userId"), request.method, request.url);
};
// ... or some downstream loader
export function loader({ context }: Route.LoaderArgs) {
let session = context.get(sessionContext);
let profile = await getProfile(session.get("userId"));
return { profile };
}
```
If you are using a custom server with a `getLoadContext` function, the return value for initial context values passed from the server adapter layer is no longer an object and should now return an `unstable_InitialContext` (`Map<RouterContext, unknown>`):
```ts
let adapterContext = unstable_createContext<MyAdapterContext>();
function getLoadContext(req, res): unstable_InitialContext {
let map = new Map();
map.set(adapterContext, getAdapterContext(req));
return map;
}
```
#### `unstable_SerializesTo`
`unstable_SerializesTo` added a way to register custom serialization types in Single Fetch for other library and framework authors like Apollo. It was implemented with branded type whose branded property that was made optional so that casting arbitrary values was easy:
```ts
// without the brand being marked as optional
let x1 = 42 as unknown as unstable_SerializesTo<number>;
// ^^^^^^^^^^
// with the brand being marked as optional
let x2 = 42 as unstable_SerializesTo<number>;
```
However, this broke type inference in `loaderData` and `actionData` for any `Record` types as those would now (incorrectly) match `unstable_SerializesTo`. This affected all users, not just those that depended on `unstable_SerializesTo`. To fix this, the branded property of `unstable_SerializesTo` is marked as required instead of optional.
For library and framework authors using `unstable_SerializesTo`, you may need to add `as unknown` casts before casting to `unstable_SerializesTo`.
### Changes by Package
- [`create-react-router`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/create-react-router/CHANGELOG.md#730)
- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router/CHANGELOG.md#730)
- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-architect/CHANGELOG.md#730)
- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-cloudflare/CHANGELOG.md#730)
- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-dev/CHANGELOG.md#730)
- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-express/CHANGELOG.md#730)
- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-fs-routes/CHANGELOG.md#730)
- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-node/CHANGELOG.md#730)
- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#730)
- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.3.0/packages/react-router-serve/CHANGELOG.md#730)
**Full Changelog**: [`v7.2.0...v7.3.0`](https://github.com/remix-run/react-router/compare/react-router@7.2.0...react-router@7.3.0)
## v7.2.0
Date: 2025-02-18
### What's Changed
#### Type-safe `href` utility
In framework mode, we now provide you with a fully type-safe `href` utility to give you all the warm and fuzzy feelings of path auto-completion and param validation for links in your application:
```tsx
import { href } from "react-router";
export default function Component() {
const link = href("/blog/:slug", { slug: "my-first-post" });
// ^ type-safe! ^ Also type-safe!
return (
<main>
<Link to={href("/products/:id", { id: "asdf" })} />
<NavLink to={href("/:lang?/about", { lang: "en" })} />
</main>
);
}
```
You'll now get type errors if you pass a bad path value or a bad param value:
```ts
const badPath = href("/not/a/valid/path");
// ^ Error!
const badParam = href("/blog/:slug", { oops: "bad param" });
// ^ Error!
```
#### Prerendering with a SPA Fallback
This release enhances the ability to use a combination of pre-rendered paths alongside other paths that operate in "SPA Mode" when pre-rendering with `ssr:false`.
- If you specify `ssr:false` without a `prerender` config, this is considered "SPA Mode" and the generated `index.html` file will only render down to the root route and will be able to hydrate for any valid application path
- If you specify `ssr:false` with a `prerender` config but _do not_ include the `/` path (i.e., `prerender: ['/blog/post']`), then we still generate a "SPA Mode" `index.html` file that can hydrate for any path in the application
- If you specify `ssr:false` and include the `/` path in your `prerender` config, the generated `index.html` file will be specific to the root index route, so we will now also generate a separate "SPA Mode" file in `__spa-fallback.html` that you can serve/hydrate for non-prerendered paths
For more info, see the [Pre-rendering](https://reactrouter.com/dev/how-to/pre-rendering#pre-rendering-with-a-spa-fallback) docs for more info.
#### Allow a root `loader` in SPA Mode
SPA Mode used to prohibit the use of loaders in all routes so that we could hydrate for any path in the application. However, because the root route is always rendered at build time, we can lift this restriction for the root route.
In order to use your build-time loader data during pre-rendering, we now also expose the `loaderData` as an optional prop for the `HydrateFallback` component on routes:
- This will be defined so long as the `HydrateFallback` is rendering because _children_ routes are loading
- This will be `undefined` if the `HydrateFallback` is rendering because the route itself has it's own hydrating `clientLoader`
- In SPA mode, this will allow you to render loader root data into the SPA Mode HTML file
### Minor Changes
- `react-router` - New type-safe `href` utility that guarantees links point to actual paths in your app ([#13012](https://github.com/remix-run/react-router/pull/13012))
- `@react-router/dev` - Generate a "SPA fallback" HTML file when pre-rendering the `/` route with `ssr:false` ([#12948](https://github.com/remix-run/react-router/pull/12948))
- `@react-router/dev` - Allow a `loader` in the root route in SPA mode because it can be called/server-rendered at build time ([#12948](https://github.com/remix-run/react-router/pull/12948))
- `Route.HydrateFallbackProps` now also receives `loaderData`
### Patch Changes
- `react-router` - Disable Lazy Route Discovery for all `ssr:false` apps and not just "SPA Mode" because there is no runtime server to serve the search-param-configured `__manifest` requests ([#12894](https://github.com/remix-run/react-router/pull/12894))
- We previously only disabled this for "SPA Mode" but we realized it should apply to all `ssr:false` apps
- In those `prerender` scenarios we would pre-render the `/__manifest` file but that makes some unnecessary assumptions about the static file server behaviors
- `react-router` - Don't apply Single Fetch revalidation de-optimization when in SPA mode since there is no server HTTP request ([#12948](https://github.com/remix-run/react-router/pull/12948))
- `react-router` - Properly handle revalidations to across a pre-render/SPA boundary ([#13021](https://github.com/remix-run/react-router/pull/13021))
- In "hybrid" applications where some routes are pre-rendered and some are served from a SPA fallback, we need to avoid making `.data` requests if the path wasn't pre-rendered because the request will 404
- We don't know all the pre-rendered paths client-side, however:
- All `loader` data in `ssr:false` mode is static because it's generated at build time
- A route must use a `clientLoader` to do anything dynamic
- Therefore, if a route only has a `loader` and not a `clientLoader`, we disable revalidation by default because there is no new data to retrieve
- We short circuit and skip single fetch `.data` request logic if there are no server loaders with `shouldLoad=true` in our single fetch `dataStrategy`
- This ensures that the route doesn't cause a `.data` request that would 404 after a submission
- `react-router` - Align dev server behavior with static file server behavior when `ssr:false` is set ([#12948](https://github.com/remix-run/react-router/pull/12948))
- When no `prerender` config exists, only SSR down to the root `HydrateFallback` (SPA Mode)
- When a `prerender` config exists but the current path is not pre-rendered, only SSR down to the root `HydrateFallback` (SPA Fallback)
- Return a 404 on `.data` requests to non-pre-rendered paths
- `react-router` - Improve prefetch performance of CSS side effects in framework mode ([#12889](https://github.com/remix-run/react-router/pull/12889))
- `react-router` - Properly handle interrupted manifest requests in lazy route discovery ([#12915](https://github.com/remix-run/react-router/pull/12915))
- `@react-router/dev` - Handle custom `envDir` in Vite config ([#12969](https://github.com/remix-run/react-router/pull/12969))
- `@react-router/dev` - Fix CLI parsing to allow argument-less `npx react-router` usage ([#12925](https://github.com/remix-run/react-router/pull/12925))
- `@react-router/dev` - Skip action-only resource routes when using `prerender:true` ([#13004](https://github.com/remix-run/react-router/pull/13004))
- `@react-router/dev` - Enhance invalid export detection when using `ssr:false` ([#12948](https://github.com/remix-run/react-router/pull/12948))
- `headers`/`action` functions are prohibited in all routes with `ssr:false` because there will be no runtime server on which to run them
- `loader` functions are more nuanced and depend on whether a given route is prerendered
- When using `ssr:false` without a `prerender` config, only the `root` route can have a `loader`
- When using `ssr:false` with a `prerender` config, only routes matched by a `prerender` path can have a `loader`
- `@react-router/dev` - Error at build time in `ssr:false` + `prerender` apps for the edge case scenario of: ([#13021](https://github.com/remix-run/react-router/pull/13021))
- A parent route has only a `loader` (does not have a `clientLoader`)
- The parent route is pre-rendered
- The parent route has children routes which are not prerendered
- This means that when the child paths are loaded via the SPA fallback, the parent won't have any `loaderData` because there is no server on which to run the `loader`
- This can be resolved by either adding a parent `clientLoader` or pre-rendering the child paths
- If you add a `clientLoader`, calling the `serverLoader()` on non-prerendered paths will throw a 404
- `@react-router/dev` - Limit prerendered resource route `.data` files to only the target route ([#13004](https://github.com/remix-run/react-router/pull/13004))
- `@react-router/dev` - Fix pre-rendering of binary files ([#13039](https://github.com/remix-run/react-router/pull/13039))
- `@react-router/dev` - Fix typegen for repeated params ([#13012](https://github.com/remix-run/react-router/pull/13012))
- In React Router, path parameters are keyed by their name, so for a path pattern like `/a/:id/b/:id?/c/:id`, the last `:id` will set the value for `id` in `useParams` and the `params` prop
- For example, `/a/1/b/2/c/3` will result in the value `{ id: 3 }` at runtime
- Previously, generated types for params incorrectly modeled repeated params with an array
- For example, `/a/1/b/2/c/3` generated a type like `{ id: [1,2,3] }`.
- To be consistent with runtime behavior, the generated types now correctly model the "last one wins" semantics of path parameters.
- For example, `/a/1/b/2/c/3` now generates a type like `{ id: 3 }`.
- `@react-router/dev` - Fix path to load `package.json` for `react-router --version` ([#13012](https://github.com/remix-run/react-router/pull/13012))
### Unstable Changes
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
- `react-router` - Add `unstable_SerializesTo` brand type for library authors to register types serializable by React Router's streaming format (`turbo-stream`) ([#12264](https://github.com/remix-run/react-router/pull/12264))
- `@react-router/dev` - Add unstable support for splitting route modules in framework mode via `future.unstable_splitRouteModules` ([#11871](https://github.com/remix-run/react-router/pull/11871))
- `@react-router/dev` - Add `future.unstable_viteEnvironmentApi` flag to enable experimental Vite Environment API support ([#12936](https://github.com/remix-run/react-router/pull/12936))
#### Split Route Modules (unstable)
> ⚠️ This feature is currently [unstable](https://reactrouter.com/community/api-development-strategy#unstable-flags), enabled by the `future.unstable_splitRouteModules` flag. We’d love any interested users to play with it locally and provide feedback, but we do not recommend using it in production yet.
>
> If you do choose to adopt this flag in production, please ensure you do sufficient testing against your production build to ensure that the optimization is working as expected.
One of the conveniences of the [Route Module API](https://reactrouter.com/start/framework/route-module) is that everything a route needs is in a single file. Unfortunately this comes with a performance cost in some cases when using the `clientLoader`, `clientAction`, and `HydrateFallback` APIs.
As a basic example, consider this route module:
```tsx filename=routes/example.tsx
import { MassiveComponent } from "~/components";
export async function clientLoader() {
return await fetch("https://example.com/api").then((response) =>
response.json(),
);
}
export default function Component({ loaderData }) {
return <MassiveComponent data={loaderData} />;
}
```
In this example we have a minimal `clientLoader` export that makes a basic fetch call, whereas the default component export is much larger. This is a problem for performance because it means that if we want to navigate to this route client-side, the entire route module must be downloaded before the client loader can start running.
To visualize this as a timeline:
<docs-info>In the following timeline diagrams, different characters are used within the Route Module bars to denote the different Route Module APIs being exported.</docs-info>
```
Get Route Module: |--=======|
Run clientLoader: |-----|
Render: |-|
```
Instead, we want to optimize this to the following:
```
Get clientLoader: |--|
Get Component: |=======|
Run clientLoader: |-----|
Render: |-|
```
To achieve this optimization, React Router will split the route module into multiple smaller modules during the production build process. In this case, we'll end up with two separate [virtual modules](https://vite.dev/guide/api-plugin#virtual-modules-convention) — one for the client loader and one for the component and its dependencies.
```tsx filename=routes/example.tsx?route-chunk=clientLoader
export async function clientLoader() {
return await fetch("https://example.com/api").then((response) =>
response.json(),
);
}
```
```tsx filename=routes/example.tsx?route-chunk=main
import { MassiveComponent } from "~/components";
export default function Component({ loaderData }) {
return <MassiveComponent data={loaderData} />;
}
```
> 💡 This optimization is automatically applied in framework mode, but you can also implement it in library mode via `route.lazy` and authoring your route in multiple files as covered in our blog post on [lazy loading route modules.](https://remix.run/blog/lazy-loading-routes#advanced-usage-and-optimizations)
Now that these are available as separate modules, the client loader and the component can be downloaded in parallel. This means that the client loader can be executed as soon as it's ready without having to wait for the component.
This optimization is even more pronounced when more Route Module APIs are used. For example, when using `clientLoader`, `clientAction` and `HydrateFallback`, the timeline for a single route module during a client-side navigation might look like this:
```
Get Route Module: |--~~++++=======|
Run clientLoader: |-----|
Render: |-|
```
This would instead be optimized to the following:
```
Get clientLoader: |--|
Get clientAction: |~~|
Get HydrateFallback: SKIPPED
Get Component: |=======|
Run clientLoader: |-----|
Render: |-|
```
Note that this optimization only works when the Route Module APIs being split don't share code within the same file. For example, the following route module can't be split:
```tsx filename=routes/example.tsx
import { MassiveComponent } from "~/components";
const shared = () => console.log("hello");
export async function clientLoader() {
shared();
return await fetch("https://example.com/api").then((response) =>
response.json(),
);
}
export default function Component({ loaderData }) {
shared();
return <MassiveComponent data={loaderData} />;
}
```
This route will still work, but since both the client loader and the component depend on the `shared` function defined within the same file, it will be de-optimized into a single route module.
To avoid this, you can extract any code shared between exports into a separate file. For example:
```tsx filename=routes/example/shared.tsx
export const shared = () => console.log("hello");
```
You can then import this shared code in your route module without triggering the de-optimization:
```tsx filename=routes/example/route.tsx
import { MassiveComponent } from "~/components";
import { shared } from "./shared";
export async function clientLoader() {
shared();
return await fetch("https://example.com/api").then((response) =>
response.json(),
);
}
export default function Component({ loaderData }) {
shared();
return <MassiveComponent data={loaderData} />;
}
```
Since the shared code is in its own module, React Router is now able to split this route module into two separate virtual modules:
```tsx filename=routes/example/route.tsx?route-chunk=clientLoader
import { shared } from "./shared";
export async function clientLoader() {
shared();
return await fetch("https://example.com/api").then((response) =>
response.json(),
);
}
```
```tsx filename=routes/example/route.tsx?route-chunk=main
import { MassiveComponent } from "~/components";
import { shared } from "./shared";
export default function Component({ loaderData }) {
shared();
return <MassiveComponent data={loaderData} />;
}
```
If your project is particularly performance sensitive, you can set the `unstable_splitRouteModules` future flag to `"enforce"`:
```tsx filename=react-router-config.ts
export default {
future: {
unstable_splitRouteModules: "enforce",
},
};
```
gitextract_wusxnjs2/ ├── .browserslistrc ├── .changeset/ │ ├── README.md │ └── config.json ├── .eslintignore ├── .eslintrc ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── documentation_isse.yml │ ├── dependabot.yml │ └── workflows/ │ ├── close-feature-pr.yml │ ├── close-no-repro-issue.yml │ ├── close-no-repro-issues.yml │ ├── deduplicate-lock-file.yml │ ├── docs.yml │ ├── format.yml │ ├── integration-full.yml │ ├── integration-pr-ubuntu.yml │ ├── integration-pr-windows-macos.yml │ ├── no-response.yml │ ├── release-comment-manual.yml │ ├── release.yml │ ├── shared-build.yml │ ├── shared-integration.yml │ ├── support.yml │ └── test.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .vscode/ │ └── settings.json ├── AGENTS.md ├── CHANGELOG.md ├── CLA.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DEVELOPMENT.md ├── GOVERNANCE.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── build.utils.ts ├── contributors.yml ├── decisions/ │ ├── 0001-use-blocker.md │ ├── 0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md │ ├── 0002-do-not-clone-request.md │ ├── 0002-lazy-route-modules.md │ ├── 0003-data-strategy.md │ ├── 0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md │ ├── 0004-streaming-apis.md │ ├── 0005-remixing-react-router.md │ ├── 0006-linear-workflow.md │ ├── 0007-remix-on-react-router-6-4-0.md │ ├── 0008-only-support-js-conversion-for-app-code.md │ ├── 0009-do-not-rely-on-treeshaking-for-correctness.md │ ├── 0010-splitting-up-client-and-server-code-in-vite.md │ ├── 0011-routes-ts.md │ ├── 0012-type-inference.md │ ├── 0013-react-router-config-ts.md │ ├── 0014-context-middleware.md │ ├── 0015-observability.md │ └── template.md ├── docs/ │ ├── api/ │ │ ├── components/ │ │ │ ├── Await.md │ │ │ ├── Form.md │ │ │ ├── Link.md │ │ │ ├── Links.md │ │ │ ├── Meta.md │ │ │ ├── NavLink.md │ │ │ ├── Navigate.md │ │ │ ├── Outlet.md │ │ │ ├── PrefetchPageLinks.md │ │ │ ├── Route.md │ │ │ ├── Routes.md │ │ │ ├── Scripts.md │ │ │ ├── ScrollRestoration.md │ │ │ └── index.md │ │ ├── data-routers/ │ │ │ ├── RouterProvider.md │ │ │ ├── StaticRouterProvider.md │ │ │ ├── createBrowserRouter.md │ │ │ ├── createHashRouter.md │ │ │ ├── createMemoryRouter.md │ │ │ ├── createStaticHandler.md │ │ │ ├── createStaticRouter.md │ │ │ └── index.md │ │ ├── declarative-routers/ │ │ │ ├── BrowserRouter.md │ │ │ ├── HashRouter.md │ │ │ ├── HistoryRouter.md │ │ │ ├── MemoryRouter.md │ │ │ ├── Router.md │ │ │ ├── StaticRouter.md │ │ │ └── index.md │ │ ├── framework-conventions/ │ │ │ ├── client-modules.md │ │ │ ├── entry.client.tsx.md │ │ │ ├── entry.server.tsx.md │ │ │ ├── index.md │ │ │ ├── react-router.config.ts.md │ │ │ ├── root.tsx.md │ │ │ ├── routes.ts.md │ │ │ └── server-modules.md │ │ ├── framework-routers/ │ │ │ ├── HydratedRouter.md │ │ │ ├── ServerRouter.md │ │ │ └── index.md │ │ ├── hooks/ │ │ │ ├── index.md │ │ │ ├── useActionData.md │ │ │ ├── useAsyncError.md │ │ │ ├── useAsyncValue.md │ │ │ ├── useBeforeUnload.md │ │ │ ├── useBlocker.md │ │ │ ├── useFetcher.md │ │ │ ├── useFetchers.md │ │ │ ├── useFormAction.md │ │ │ ├── useHref.md │ │ │ ├── useInRouterContext.md │ │ │ ├── useLinkClickHandler.md │ │ │ ├── useLoaderData.md │ │ │ ├── useLocation.md │ │ │ ├── useMatch.md │ │ │ ├── useMatches.md │ │ │ ├── useNavigate.md │ │ │ ├── useNavigation.md │ │ │ ├── useNavigationType.md │ │ │ ├── useOutlet.md │ │ │ ├── useOutletContext.md │ │ │ ├── useParams.md │ │ │ ├── usePrompt.md │ │ │ ├── useResolvedPath.md │ │ │ ├── useRevalidator.md │ │ │ ├── useRouteError.md │ │ │ ├── useRouteLoaderData.md │ │ │ ├── useRoutes.md │ │ │ ├── useSearchParams.md │ │ │ ├── useSubmit.md │ │ │ └── useViewTransitionState.md │ │ ├── index.md │ │ ├── other-api/ │ │ │ ├── adapter.md │ │ │ ├── dev.md │ │ │ ├── index.md │ │ │ └── serve.md │ │ ├── rsc/ │ │ │ ├── RSCHydratedRouter.md │ │ │ ├── RSCStaticRouter.md │ │ │ ├── createCallServer.md │ │ │ ├── getRSCStream.md │ │ │ ├── index.md │ │ │ ├── matchRSCServerRequest.md │ │ │ └── routeRSCServerRequest.md │ │ └── utils/ │ │ ├── IsCookieFunction.md │ │ ├── IsSessionFunction.md │ │ ├── RouterContextProvider.md │ │ ├── createContext.md │ │ ├── createCookie.md │ │ ├── createCookieSessionStorage.md │ │ ├── createMemorySessionStorage.md │ │ ├── createPath.md │ │ ├── createRequestHandler.md │ │ ├── createRoutesFromElements.md │ │ ├── createRoutesStub.md │ │ ├── createSearchParams.md │ │ ├── createSession.md │ │ ├── createSessionStorage.md │ │ ├── data.md │ │ ├── generatePath.md │ │ ├── href.md │ │ ├── index.md │ │ ├── isCookie.md │ │ ├── isRouteErrorResponse.md │ │ ├── isSession.md │ │ ├── matchPath.md │ │ ├── matchRoutes.md │ │ ├── parsePath.md │ │ ├── redirect.md │ │ ├── redirectDocument.md │ │ ├── renderMatches.md │ │ ├── replace.md │ │ └── resolvePath.md │ ├── community/ │ │ ├── api-development-strategy.md │ │ ├── contributing.md │ │ └── index.md │ ├── elements.md │ ├── explanation/ │ │ ├── README │ │ ├── backend-for-frontend.md │ │ ├── code-splitting.md │ │ ├── concurrency.md │ │ ├── form-vs-fetcher.md │ │ ├── hot-module-replacement.md │ │ ├── hydration.md │ │ ├── index-query-param.md │ │ ├── index.md │ │ ├── lazy-route-discovery.md │ │ ├── location.md │ │ ├── progressive-enhancement.md │ │ ├── race-conditions.md │ │ ├── react-transitions.md │ │ ├── route-matching.md │ │ ├── server-client-execution.md │ │ ├── sessions-and-cookies.md │ │ ├── special-files.md │ │ ├── state-management.md │ │ └── type-safety.md │ ├── how-to/ │ │ ├── README │ │ ├── accessibility.md │ │ ├── client-data.md │ │ ├── data-strategy.md │ │ ├── error-boundary.md │ │ ├── error-reporting.md │ │ ├── fetchers.md │ │ ├── file-route-conventions.md │ │ ├── file-uploads.md │ │ ├── form-validation.md │ │ ├── headers.md │ │ ├── index.md │ │ ├── instrumentation.md │ │ ├── meta.md │ │ ├── middleware.md │ │ ├── navigation-blocking.md │ │ ├── optimize-revalidation.md │ │ ├── pre-rendering.md │ │ ├── presets.md │ │ ├── react-server-components.md │ │ ├── resource-routes.md │ │ ├── route-module-type-safety.md │ │ ├── search-params.md │ │ ├── security.md │ │ ├── server-bundles.md │ │ ├── spa.md │ │ ├── status.md │ │ ├── suspense.md │ │ ├── using-handle.md │ │ ├── view-transitions.md │ │ └── webhook.md │ ├── index.md │ ├── prettier.config.js │ ├── start/ │ │ ├── README │ │ ├── data/ │ │ │ ├── actions.md │ │ │ ├── custom.md │ │ │ ├── data-loading.md │ │ │ ├── index.md │ │ │ ├── installation.md │ │ │ ├── navigating.md │ │ │ ├── pending-ui.md │ │ │ ├── route-object.md │ │ │ ├── routing.md │ │ │ └── testing.md │ │ ├── declarative/ │ │ │ ├── index.md │ │ │ ├── installation.md │ │ │ ├── navigating.md │ │ │ ├── routing.md │ │ │ └── url-values.md │ │ ├── framework/ │ │ │ ├── actions.md │ │ │ ├── data-loading.md │ │ │ ├── deploying.md │ │ │ ├── index.md │ │ │ ├── installation.md │ │ │ ├── navigating.md │ │ │ ├── pending-ui.md │ │ │ ├── rendering.md │ │ │ ├── route-module.md │ │ │ ├── routing.md │ │ │ └── testing.md │ │ ├── index.md │ │ └── modes.md │ ├── tutorials/ │ │ ├── README │ │ ├── address-book.md │ │ ├── advanced-data-fetching.md │ │ ├── index.md │ │ └── quickstart.md │ └── upgrading/ │ ├── README │ ├── component-routes.md │ ├── future.md │ ├── index.md │ ├── remix.md │ ├── router-provider.md │ └── v6.md ├── examples/ │ ├── README.md │ ├── auth/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── auth.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── auth-router-provider/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── auth.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── basic/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── basic-data-router/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── custom-filter-link/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── snkrs.ts │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── custom-link/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── custom-query-parsing/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ ├── types/ │ │ │ └── jsurl.d.ts │ │ └── vite.config.ts │ ├── data-router/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── todos.ts │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── error-boundaries/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── routes.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── lazy-loading/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── pages/ │ │ │ │ ├── About.tsx │ │ │ │ └── Dashboard.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── lazy-loading-router-provider/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── pages/ │ │ │ │ ├── About.tsx │ │ │ │ └── Dashboard.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── modal/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── images.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── modal-data-router/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── images.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── modal-route-with-outlet/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── images.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── multi-app/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── home/ │ │ │ ├── App.jsx │ │ │ ├── index.css │ │ │ ├── main.jsx │ │ │ └── no-match.jsx │ │ ├── inbox/ │ │ │ ├── App.jsx │ │ │ ├── index.css │ │ │ ├── index.html │ │ │ ├── main.jsx │ │ │ ├── messages.js │ │ │ └── no-match.jsx │ │ ├── index.html │ │ ├── package.json │ │ ├── server.js │ │ └── vite.config.js │ ├── navigation-blocking/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.tsx │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── notes/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.jsx │ │ │ ├── index.css │ │ │ ├── main.jsx │ │ │ ├── notes.js │ │ │ ├── routes/ │ │ │ │ ├── new.jsx │ │ │ │ ├── note.jsx │ │ │ │ ├── notes.jsx │ │ │ │ └── root.jsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── route-objects/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── scroll-restoration/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── search-params/ │ │ ├── .gitignore │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── ssr/ │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── server.js │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── entry.client.tsx │ │ │ ├── entry.server.tsx │ │ │ ├── index.css │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.js │ ├── ssr-data-router/ │ │ ├── .stackblitzrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── server.js │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── entry.client.tsx │ │ │ ├── entry.server.tsx │ │ │ ├── index.css │ │ │ ├── lazy.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vite.config.js │ └── view-transitions/ │ ├── .gitignore │ ├── .stackblitzrc │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src/ │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.json │ └── vite.config.ts ├── integration/ │ ├── CHANGELOG.md │ ├── abort-signal-test.ts │ ├── action-test.ts │ ├── assets/ │ │ ├── toupload.txt │ │ └── touploadtoobig.txt │ ├── blocking-test.ts │ ├── browser-entry-test.ts │ ├── bug-report-test.ts │ ├── catch-boundary-data-test.ts │ ├── catch-boundary-test.ts │ ├── cli-test.ts │ ├── client-data-test.ts │ ├── custom-entry-server-test.ts │ ├── deduped-route-modules-test.ts │ ├── defer-loader-test.ts │ ├── defer-test.ts │ ├── error-boundary-test.ts │ ├── error-boundary-v2-test.ts │ ├── error-data-request-test.ts │ ├── error-sanitization-test.ts │ ├── fetch-globals-test.ts │ ├── fetcher-layout-test.ts │ ├── fetcher-test.ts │ ├── fog-of-war-test.ts │ ├── form-data-test.ts │ ├── form-test.ts │ ├── fs-routes-test.ts │ ├── headers-test.ts │ ├── helpers/ │ │ ├── cleanup.mjs │ │ ├── cloudflare-dev-proxy-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── entry.server.tsx │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── create-fixture.ts │ │ ├── express.ts │ │ ├── fixtures.ts │ │ ├── playwright-fixture.ts │ │ ├── rsc-vite/ │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ ├── src/ │ │ │ │ ├── config/ │ │ │ │ │ ├── basename.ts │ │ │ │ │ ├── get-context.ts │ │ │ │ │ └── request-context.ts │ │ │ │ ├── entry.browser.tsx │ │ │ │ ├── entry.rsc.tsx │ │ │ │ ├── entry.ssr.tsx │ │ │ │ ├── routes/ │ │ │ │ │ ├── home.tsx │ │ │ │ │ └── root.tsx │ │ │ │ └── routes.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── rsc-vite-framework/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── package.json │ │ │ ├── start.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── stream.ts │ │ ├── templates.ts │ │ ├── vite-5-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── env.d.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── vite-6-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── env.d.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── vite-7-beta-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── env.d.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── vite-plugin-cloudflare-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── entry.server.tsx │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── package.json │ │ │ ├── react-router.config.ts │ │ │ ├── tsconfig.cloudflare.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.node.json │ │ │ ├── vite.config.ts │ │ │ ├── workers/ │ │ │ │ └── app.ts │ │ │ └── wrangler.toml │ │ ├── vite-rolldown-template/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── root.tsx │ │ │ │ ├── routes/ │ │ │ │ │ └── _index.tsx │ │ │ │ └── routes.ts │ │ │ ├── env.d.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ └── vite.ts │ ├── hook-useSubmit-test.ts │ ├── http-test.ts │ ├── layout-route-test.ts │ ├── link-test.ts │ ├── loader-test.ts │ ├── matches-test.ts │ ├── mdx-test.ts │ ├── middleware-test.ts │ ├── multiple-cookies-test.ts │ ├── navigation-state-test.ts │ ├── package.json │ ├── playwright.config.ts │ ├── prefetch-test.ts │ ├── react-router-serve-test.ts │ ├── redirects-test.ts │ ├── rendering-test.ts │ ├── request-test.ts │ ├── resource-routes-test.ts │ ├── revalidate-test.ts │ ├── root-route-test.ts │ ├── route-collisions-test.ts │ ├── route-config-test.ts │ ├── rsc/ │ │ ├── rsc-nojs-test.ts │ │ ├── rsc-test.ts │ │ └── utils.ts │ ├── scroll-test.ts │ ├── server-entry-test.ts │ ├── session-storage-denied-test.ts │ ├── set-cookie-revalidation-test.ts │ ├── single-fetch-test.ts │ ├── splat-routes-test.ts │ ├── split-route-modules-test.ts │ ├── sri-test.ts │ ├── transition-test.ts │ ├── tsconfig.json │ ├── typegen-test.ts │ ├── use-route-test.ts │ ├── vite-absolute-base-test.ts │ ├── vite-basename-test.ts │ ├── vite-build-test.ts │ ├── vite-cloudflare-test.ts │ ├── vite-css-lazy-loading-test.ts │ ├── vite-css-test.ts │ ├── vite-dev-custom-entry-test.ts │ ├── vite-dev-test.ts │ ├── vite-dot-client-test.ts │ ├── vite-dot-server-test.ts │ ├── vite-dotenv-test.ts │ ├── vite-hmr-hdr-rsc-test.ts │ ├── vite-hmr-hdr-test.ts │ ├── vite-loader-context-test.ts │ ├── vite-manifests-test.ts │ ├── vite-node-env-test.ts │ ├── vite-plugin-cloudflare-test.ts │ ├── vite-plugin-order-validation-test.ts │ ├── vite-prerender-test.ts │ ├── vite-presets-test.ts │ ├── vite-preview-test.ts │ ├── vite-route-added-test.ts │ ├── vite-route-exports-modified-offscreen-test.ts │ ├── vite-server-bundles-test.ts │ ├── vite-server-fs-allow-test.ts │ ├── vite-spa-mode-test.ts │ └── vite-unused-route-exports-test.ts ├── jest/ │ ├── jest.config.shared.js │ └── transform.js ├── package.json ├── packages/ │ ├── create-react-router/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── create-react-router-test.ts │ │ │ ├── fixtures/ │ │ │ │ ├── basic/ │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── README.md │ │ │ │ │ ├── app/ │ │ │ │ │ │ ├── root.tsx │ │ │ │ │ │ ├── routes/ │ │ │ │ │ │ │ └── home.tsx │ │ │ │ │ │ └── routes.ts │ │ │ │ │ ├── package.json │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── vite.config.ts │ │ │ │ ├── blank/ │ │ │ │ │ └── package.json │ │ │ │ ├── template.tgz │ │ │ │ └── with-ignored-dir/ │ │ │ │ └── package.json │ │ │ ├── github-mocks.ts │ │ │ ├── msw-register.ts │ │ │ ├── msw.ts │ │ │ └── setupAfterEnv.ts │ │ ├── cli.ts │ │ ├── copy-template.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── loading-indicator.ts │ │ ├── package.json │ │ ├── prompt.ts │ │ ├── prompts-confirm.ts │ │ ├── prompts-multi-select.ts │ │ ├── prompts-prompt-base.ts │ │ ├── prompts-select.ts │ │ ├── prompts-text.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── utils.ts │ ├── react-router/ │ │ ├── .eslintrc.js │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── .eslintrc │ │ │ ├── Route-test.tsx │ │ │ ├── Router-basename-test.tsx │ │ │ ├── Router-test.tsx │ │ │ ├── Routes-location-test.tsx │ │ │ ├── Routes-test.tsx │ │ │ ├── __snapshots__/ │ │ │ │ └── route-matching-test.tsx.snap │ │ │ ├── absolute-path-matching-test.tsx │ │ │ ├── createRoutesFromChildren-test.tsx │ │ │ ├── data-memory-router-test.tsx │ │ │ ├── data-router-no-dom-test.tsx │ │ │ ├── descendant-routes-params-test.tsx │ │ │ ├── descendant-routes-splat-matching-test.tsx │ │ │ ├── descendant-routes-warning-test.tsx │ │ │ ├── dom/ │ │ │ │ ├── client-on-error-test.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── LazyComponent.tsx │ │ │ │ ├── concurrent-mode-navigations-test.tsx │ │ │ │ ├── data-browser-router-legacy-formdata-test.tsx │ │ │ │ ├── data-browser-router-test.tsx │ │ │ │ ├── data-static-router-test.tsx │ │ │ │ ├── dom-export-test.tsx │ │ │ │ ├── fetcher-submit-tagname-test.tsx │ │ │ │ ├── flush-sync-navigations-test.tsx │ │ │ │ ├── link-click-test.tsx │ │ │ │ ├── link-href-test.tsx │ │ │ │ ├── link-push-test.tsx │ │ │ │ ├── nav-link-active-test.tsx │ │ │ │ ├── navigate-encode-params-test.tsx │ │ │ │ ├── partial-hydration-test.tsx │ │ │ │ ├── polyfills/ │ │ │ │ │ └── drop-FormData-submitter.ts │ │ │ │ ├── scroll-restoration-test.tsx │ │ │ │ ├── search-params-test.tsx │ │ │ │ ├── special-characters-test.tsx │ │ │ │ ├── ssr/ │ │ │ │ │ ├── components-test.tsx │ │ │ │ │ ├── links-test.tsx │ │ │ │ │ └── meta-test.tsx │ │ │ │ ├── static-link-test.tsx │ │ │ │ ├── static-location-test.tsx │ │ │ │ ├── static-navigate-test.tsx │ │ │ │ ├── stub-test.tsx │ │ │ │ ├── trailing-slashes-test.tsx │ │ │ │ ├── use-blocker-test.tsx │ │ │ │ ├── use-prompt-test.tsx │ │ │ │ └── useLinkClickHandler-test.tsx │ │ │ ├── generatePath-test.tsx │ │ │ ├── gh-issue-8127-test.tsx │ │ │ ├── gh-issue-8165-test.tsx │ │ │ ├── greedy-matching-test.tsx │ │ │ ├── href-test.ts │ │ │ ├── index-routes-test.tsx │ │ │ ├── layout-routes-test.tsx │ │ │ ├── matchPath-test.tsx │ │ │ ├── matchRoutes-test.tsx │ │ │ ├── navigate-test.tsx │ │ │ ├── params-decode-test.tsx │ │ │ ├── path-matching-test.tsx │ │ │ ├── react-transitions-test.tsx │ │ │ ├── resolvePath-test.tsx │ │ │ ├── route-depth-order-matching-test.tsx │ │ │ ├── route-matching-test.tsx │ │ │ ├── router/ │ │ │ │ ├── TestSequences/ │ │ │ │ │ ├── EncodedReservedCharacters.ts │ │ │ │ │ ├── GoBack.ts │ │ │ │ │ ├── GoForward.ts │ │ │ │ │ ├── InitialLocationDefaultKey.ts │ │ │ │ │ ├── InitialLocationHasKey.ts │ │ │ │ │ ├── Listen.ts │ │ │ │ │ ├── ListenPopOnly.ts │ │ │ │ │ ├── PushMissingPathname.ts │ │ │ │ │ ├── PushNewLocation.ts │ │ │ │ │ ├── PushRelativePathname.ts │ │ │ │ │ ├── PushRelativePathnameWarning.ts │ │ │ │ │ ├── PushSamePath.ts │ │ │ │ │ ├── PushState.ts │ │ │ │ │ ├── PushStateInvalid.ts │ │ │ │ │ ├── ReplaceNewLocation.ts │ │ │ │ │ ├── ReplaceSamePath.ts │ │ │ │ │ └── ReplaceState.ts │ │ │ │ ├── browser-test.ts │ │ │ │ ├── context-middleware-test.tsx │ │ │ │ ├── create-path-test.ts │ │ │ │ ├── data-strategy-test.ts │ │ │ │ ├── fetchers-test.ts │ │ │ │ ├── flush-sync-test.ts │ │ │ │ ├── hash-base-test.ts │ │ │ │ ├── hash-test.ts │ │ │ │ ├── instrumentation-test.ts │ │ │ │ ├── interruptions-test.ts │ │ │ │ ├── lazy-discovery-test.ts │ │ │ │ ├── lazy-test.ts │ │ │ │ ├── mask-test.ts │ │ │ │ ├── memory-test.ts │ │ │ │ ├── navigation-blocking-test.ts │ │ │ │ ├── navigation-test.ts │ │ │ │ ├── path-resolution-test.ts │ │ │ │ ├── redirects-test.ts │ │ │ │ ├── resolveTo-test.tsx │ │ │ │ ├── revalidate-test.ts │ │ │ │ ├── route-fallback-test.ts │ │ │ │ ├── router-memory-test.ts │ │ │ │ ├── router-test.ts │ │ │ │ ├── scroll-restoration-test.ts │ │ │ │ ├── should-revalidate-test.ts │ │ │ │ ├── ssr-test.ts │ │ │ │ ├── submission-test.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── custom-matchers.ts │ │ │ │ │ ├── data-router-setup.ts │ │ │ │ │ ├── urlDataStrategy.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── view-transition-test.ts │ │ │ ├── same-component-lifecycle-test.tsx │ │ │ ├── server-runtime/ │ │ │ │ ├── actions-test.ts │ │ │ │ ├── cookies-test.ts │ │ │ │ ├── data-test.ts │ │ │ │ ├── handle-error-test.ts │ │ │ │ ├── handler-test.ts │ │ │ │ ├── markup-test.ts │ │ │ │ ├── responses-test.ts │ │ │ │ ├── server-test.ts │ │ │ │ ├── sessions-test.ts │ │ │ │ └── utils.ts │ │ │ ├── setup.ts │ │ │ ├── use-revalidator-test.tsx │ │ │ ├── useHref-basename-test.tsx │ │ │ ├── useHref-test.tsx │ │ │ ├── useLocation-test.tsx │ │ │ ├── useMatch-test.tsx │ │ │ ├── useNavigate-test.tsx │ │ │ ├── useOutlet-test.tsx │ │ │ ├── useParams-test.tsx │ │ │ ├── useResolvedPath-test.tsx │ │ │ ├── useRoutes-test.tsx │ │ │ ├── utils/ │ │ │ │ ├── MemoryNavigate.tsx │ │ │ │ ├── framework.ts │ │ │ │ ├── getHtml.ts │ │ │ │ ├── getWindow.ts │ │ │ │ ├── renderStrict.tsx │ │ │ │ ├── tick.ts │ │ │ │ └── waitForRedirect.tsx │ │ │ └── vendor/ │ │ │ └── turbo-stream-test.ts │ │ ├── dom-export.ts │ │ ├── index-react-server-client.ts │ │ ├── index-react-server.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── lib/ │ │ │ ├── actions.ts │ │ │ ├── components.tsx │ │ │ ├── context.ts │ │ │ ├── dom/ │ │ │ │ ├── dom.ts │ │ │ │ ├── global.ts │ │ │ │ ├── lib.tsx │ │ │ │ ├── node-main.js │ │ │ │ ├── server.tsx │ │ │ │ └── ssr/ │ │ │ │ ├── components.tsx │ │ │ │ ├── data.ts │ │ │ │ ├── entry.ts │ │ │ │ ├── errorBoundaries.tsx │ │ │ │ ├── errors.ts │ │ │ │ ├── fallback.tsx │ │ │ │ ├── fog-of-war.ts │ │ │ │ ├── hydration.tsx │ │ │ │ ├── invariant.ts │ │ │ │ ├── links.ts │ │ │ │ ├── markup.ts │ │ │ │ ├── routeModules.ts │ │ │ │ ├── routes-test-stub.tsx │ │ │ │ ├── routes.tsx │ │ │ │ ├── server.tsx │ │ │ │ └── single-fetch.tsx │ │ │ ├── dom-export/ │ │ │ │ ├── dom-router-provider.tsx │ │ │ │ └── hydrated-router.tsx │ │ │ ├── errors.ts │ │ │ ├── hooks.tsx │ │ │ ├── href.ts │ │ │ ├── router/ │ │ │ │ ├── history.ts │ │ │ │ ├── instrumentation.ts │ │ │ │ ├── links.ts │ │ │ │ ├── router.ts │ │ │ │ └── utils.ts │ │ │ ├── rsc/ │ │ │ │ ├── browser.tsx │ │ │ │ ├── errorBoundaries.tsx │ │ │ │ ├── html-stream/ │ │ │ │ │ ├── browser.ts │ │ │ │ │ └── server.ts │ │ │ │ ├── route-modules.ts │ │ │ │ ├── server.rsc.ts │ │ │ │ └── server.ssr.tsx │ │ │ ├── server-runtime/ │ │ │ │ ├── .eslintrc.js │ │ │ │ ├── build.ts │ │ │ │ ├── cookies.ts │ │ │ │ ├── crypto.ts │ │ │ │ ├── data.ts │ │ │ │ ├── dev.ts │ │ │ │ ├── entry.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── headers.ts │ │ │ │ ├── invariant.ts │ │ │ │ ├── mode.ts │ │ │ │ ├── routeMatching.ts │ │ │ │ ├── routes.ts │ │ │ │ ├── server.ts │ │ │ │ ├── serverHandoff.ts │ │ │ │ ├── sessions/ │ │ │ │ │ ├── cookieStorage.ts │ │ │ │ │ └── memoryStorage.ts │ │ │ │ ├── sessions.ts │ │ │ │ ├── single-fetch.ts │ │ │ │ └── warnings.ts │ │ │ └── types/ │ │ │ ├── future.ts │ │ │ ├── internal.ts │ │ │ ├── params.ts │ │ │ ├── register.ts │ │ │ ├── route-data.ts │ │ │ ├── route-module-annotations.ts │ │ │ ├── route-module.ts │ │ │ ├── serializes-to.ts │ │ │ └── utils.ts │ │ ├── node-main-dom-export.js │ │ ├── node-main.js │ │ ├── package.json │ │ ├── tsconfig.dom.json │ │ ├── tsconfig.json │ │ ├── tsup.config.rsc.ts │ │ ├── tsup.config.ts │ │ ├── typedoc.mjs │ │ └── vendor/ │ │ └── turbo-stream-v2/ │ │ ├── flatten.ts │ │ ├── turbo-stream.ts │ │ ├── unflatten.ts │ │ └── utils.ts │ ├── react-router-architect/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── binaryTypes-test.ts │ │ │ └── server-test.ts │ │ ├── binaryTypes.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── server.ts │ │ ├── sessions/ │ │ │ └── arcTableSessionStorage.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── typedoc.mjs │ ├── react-router-cloudflare/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── index.ts │ │ ├── package.json │ │ ├── sessions/ │ │ │ └── workersKVStorage.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ ├── typedoc.mjs │ │ └── worker.ts │ ├── react-router-dev/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── fixtures/ │ │ │ │ └── basic/ │ │ │ │ ├── .gitignore │ │ │ │ ├── app/ │ │ │ │ │ ├── root.tsx │ │ │ │ │ ├── routes/ │ │ │ │ │ │ └── _index.tsx │ │ │ │ │ └── routes.ts │ │ │ │ ├── package.json │ │ │ │ └── tsconfig.json │ │ │ ├── route-config-test.ts │ │ │ ├── setupAfterEnv.ts │ │ │ ├── styles-test.ts │ │ │ └── utils/ │ │ │ ├── captureError.ts │ │ │ ├── cli.ts │ │ │ ├── eol.ts │ │ │ ├── git.ts │ │ │ └── withApp.ts │ │ ├── bin.js │ │ ├── cli/ │ │ │ ├── commands.ts │ │ │ ├── detectPackageManager.ts │ │ │ ├── index.ts │ │ │ ├── run.ts │ │ │ └── useJavascript.ts │ │ ├── config/ │ │ │ ├── config.ts │ │ │ ├── default-rsc-entries/ │ │ │ │ ├── entry.client.tsx │ │ │ │ ├── entry.rsc.tsx │ │ │ │ └── entry.ssr.tsx │ │ │ ├── defaults/ │ │ │ │ ├── entry.client.tsx │ │ │ │ └── entry.server.node.tsx │ │ │ ├── format.ts │ │ │ ├── is-react-router-repo.ts │ │ │ └── routes.ts │ │ ├── config.ts │ │ ├── invariant.ts │ │ ├── jest.config.js │ │ ├── manifest.ts │ │ ├── module-sync-enabled/ │ │ │ ├── false.cjs │ │ │ ├── index.d.mts │ │ │ ├── index.mjs │ │ │ └── true.mjs │ │ ├── package.json │ │ ├── routes.ts │ │ ├── rsc-types.d.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ ├── typedoc.mjs │ │ ├── typegen/ │ │ │ ├── context.ts │ │ │ ├── generate.ts │ │ │ ├── index.ts │ │ │ ├── params.ts │ │ │ └── route.ts │ │ ├── vite/ │ │ │ ├── babel.ts │ │ │ ├── build.ts │ │ │ ├── cache.ts │ │ │ ├── cloudflare-dev-proxy.ts │ │ │ ├── cloudflare.ts │ │ │ ├── combine-urls-test.ts │ │ │ ├── combine-urls.ts │ │ │ ├── dev.ts │ │ │ ├── has-dependency.ts │ │ │ ├── has-rsc-plugin.ts │ │ │ ├── load-dotenv.ts │ │ │ ├── node-adapter.ts │ │ │ ├── optimize-deps-entries.ts │ │ │ ├── plugin.ts │ │ │ ├── plugins/ │ │ │ │ ├── prerender.ts │ │ │ │ ├── validate-plugin-order.ts │ │ │ │ └── warn-on-client-source-maps.ts │ │ │ ├── profiler.ts │ │ │ ├── remove-exports-test.ts │ │ │ ├── remove-exports.ts │ │ │ ├── resolve-file-url.ts │ │ │ ├── resolve-relative-route-file-path.ts │ │ │ ├── route-chunks-test.ts │ │ │ ├── route-chunks.ts │ │ │ ├── rsc/ │ │ │ │ ├── plugin.ts │ │ │ │ ├── virtual-route-config.ts │ │ │ │ └── virtual-route-modules.ts │ │ │ ├── ssr-externals.ts │ │ │ ├── static/ │ │ │ │ ├── refresh-utils.mjs │ │ │ │ └── rsc-refresh-utils.mjs │ │ │ ├── styles.ts │ │ │ ├── virtual-module.ts │ │ │ ├── vite-node.ts │ │ │ ├── vite.ts │ │ │ └── with-props.ts │ │ └── vite.ts │ ├── react-router-dom/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── index.ts │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── react-router-express/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ └── server-test.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── server.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── typedoc.mjs │ ├── react-router-fs-routes/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── flatRoutes-test.ts │ │ │ └── routeManifestToRouteConfig-test.ts │ │ ├── flatRoutes.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── manifest.ts │ │ ├── normalizeSlashes.ts │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── typedoc.mjs │ ├── react-router-node/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ └── sessions-test.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── server.ts │ │ ├── sessions/ │ │ │ └── fileStorage.ts │ │ ├── stream.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── typedoc.mjs │ ├── react-router-remix-routes-option-adapter/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── __tests__/ │ │ │ ├── defineRoutes-test.ts │ │ │ └── routeManifestToRouteConfig-test.ts │ │ ├── defineRoutes.ts │ │ ├── index.ts │ │ ├── jest.config.js │ │ ├── manifest.ts │ │ ├── normalizeSlashes.ts │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── typedoc.mjs │ └── react-router-serve/ │ ├── CHANGELOG.md │ ├── README.md │ ├── bin.js │ ├── cli.ts │ ├── package.json │ ├── tsconfig.json │ ├── tsup.config.ts │ └── typedoc.mjs ├── patches/ │ ├── @changesets__assemble-release-plan.patch │ ├── @changesets__get-dependents-graph@1.3.6.patch │ └── @mdx-js__rollup.patch ├── playground/ │ ├── data/ │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ └── main.tsx │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── $.tsx │ │ │ │ ├── _index.tsx │ │ │ │ └── product.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework-express/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ └── _index.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── server.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework-rolldown-vite/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ └── product.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework-spa/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ └── _index.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework-vite-5/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ └── product.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── framework-vite-7-beta/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ └── product.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── middleware/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── contexts.ts │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ ├── client.a.b.tsx │ │ │ │ ├── client.a.tsx │ │ │ │ ├── server.a.b.tsx │ │ │ │ └── server.a.tsx │ │ │ └── routes.ts │ │ ├── dev-server.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── server.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── tsconfig.vite.json │ │ └── vite.config.ts │ ├── rsc-vite/ │ │ ├── .gitignore │ │ ├── package.json │ │ ├── server.js │ │ ├── src/ │ │ │ ├── counter.tsx │ │ │ ├── entry.browser.tsx │ │ │ ├── entry.rsc.tsx │ │ │ ├── entry.ssr.tsx │ │ │ ├── routes/ │ │ │ │ ├── about/ │ │ │ │ │ ├── about.client.tsx │ │ │ │ │ └── about.tsx │ │ │ │ ├── child/ │ │ │ │ │ └── child.tsx │ │ │ │ ├── home/ │ │ │ │ │ ├── home.client.css │ │ │ │ │ ├── home.client.tsx │ │ │ │ │ ├── home.css │ │ │ │ │ └── home.tsx │ │ │ │ ├── parent/ │ │ │ │ │ └── parent.tsx │ │ │ │ ├── parent-index/ │ │ │ │ │ └── parent-index.tsx │ │ │ │ ├── redirect.ts │ │ │ │ ├── render-redirects.tsx │ │ │ │ └── root/ │ │ │ │ ├── root.client.tsx │ │ │ │ ├── root.css │ │ │ │ └── root.tsx │ │ │ └── routes.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── rsc-vite-framework/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── entry.rsc.ts │ │ │ ├── entry.ssr.ts │ │ │ ├── root.css │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index/ │ │ │ │ │ ├── actions.ts │ │ │ │ │ ├── route.tsx │ │ │ │ │ └── styles.css │ │ │ │ ├── _layout-a.route-a.tsx │ │ │ │ ├── _layout-a.tsx │ │ │ │ ├── _layout-b.route-b.tsx │ │ │ │ ├── _layout-b.tsx │ │ │ │ ├── client-loader/ │ │ │ │ │ ├── route.tsx │ │ │ │ │ └── styles.module.css │ │ │ │ ├── client-loader-hydrate/ │ │ │ │ │ ├── route.tsx │ │ │ │ │ └── styles.module.css │ │ │ │ ├── client-loader-without-server-loader/ │ │ │ │ │ ├── route.tsx │ │ │ │ │ └── styles.module.css │ │ │ │ ├── fixture.client-component/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── fixture.server-component/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── mdx/ │ │ │ │ │ ├── message.tsx │ │ │ │ │ └── route.mdx │ │ │ │ ├── mdx-glob.$post/ │ │ │ │ │ ├── posts/ │ │ │ │ │ │ ├── hello/ │ │ │ │ │ │ │ ├── hello-component.module.css │ │ │ │ │ │ │ ├── hello-component.tsx │ │ │ │ │ │ │ └── hello.mdx │ │ │ │ │ │ ├── posts.ts │ │ │ │ │ │ └── world/ │ │ │ │ │ │ ├── world-component.module.css │ │ │ │ │ │ ├── world-component.tsx │ │ │ │ │ │ └── world.mdx │ │ │ │ │ └── route.tsx │ │ │ │ ├── mdx-glob._index/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── optimistic/ │ │ │ │ │ ├── actions.ts │ │ │ │ │ ├── form.tsx │ │ │ │ │ ├── liked.ts │ │ │ │ │ └── route.tsx │ │ │ │ └── server-loader/ │ │ │ │ ├── route.tsx │ │ │ │ └── styles.module.css │ │ │ └── routes.ts │ │ ├── mdx.d.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── start-vite-middleware.js │ │ ├── start.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── split-route-modules/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ ├── semi-splittable.tsx │ │ │ │ ├── splittable.tsx │ │ │ │ └── unsplittable.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── split-route-modules-spa/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── root.tsx │ │ │ ├── routes/ │ │ │ │ ├── _index.tsx │ │ │ │ ├── semi-splittable.tsx │ │ │ │ ├── splittable.tsx │ │ │ │ └── unsplittable.tsx │ │ │ └── routes.ts │ │ ├── package.json │ │ ├── react-router.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── vite-plugin-cloudflare/ │ ├── .gitignore │ ├── app/ │ │ ├── entry.server.tsx │ │ ├── root.tsx │ │ ├── routes/ │ │ │ ├── _index.tsx │ │ │ └── static.tsx │ │ └── routes.ts │ ├── package.json │ ├── react-router.config.ts │ ├── tsconfig.cloudflare.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.ts │ ├── workers/ │ │ └── app.ts │ └── wrangler.toml ├── pnpm-workspace.yaml ├── prettier.config.js ├── scripts/ │ ├── clean-v6-artifacts.sh │ ├── close-feature-pr.md │ ├── close-no-repro-issue.md │ ├── close-no-repro-issues.md │ ├── close-no-repro-issues.ts │ ├── constants.js │ ├── delete-pre-tags.sh │ ├── docs.ts │ ├── find-release-from-changeset.js │ ├── finish-stable-release.sh │ ├── playground.js │ ├── publish.js │ ├── remove-prerelease-changelogs.mjs │ ├── start-prerelease.sh │ ├── utils.js │ └── version.js ├── tutorials/ │ └── address-book/ │ ├── .gitignore │ ├── README.md │ ├── app/ │ │ ├── app.css │ │ ├── data.ts │ │ ├── root.tsx │ │ └── routes.ts │ ├── package.json │ ├── react-router.config.ts │ ├── tsconfig.json │ └── vite.config.ts └── typedoc.mjs
Showing preview only (242K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3037 symbols across 466 files)
FILE: build.utils.ts
function createBanner (line 1) | function createBanner(packageName: string, version: string) {
FILE: examples/auth-router-provider/src/App.tsx
method loader (line 21) | loader() {
method action (line 46) | async action() {
function App (line 54) | function App() {
function Layout (line 60) | function Layout() {
function AuthStatus (line 100) | function AuthStatus() {
function loginAction (line 123) | async function loginAction({ request }: LoaderFunctionArgs) {
function loginLoader (line 150) | async function loginLoader() {
function LoginPage (line 157) | function LoginPage() {
function PublicPage (line 187) | function PublicPage() {
function protectedLoader (line 191) | function protectedLoader({ request }: LoaderFunctionArgs) {
function ProtectedPage (line 203) | function ProtectedPage() {
FILE: examples/auth-router-provider/src/auth.ts
type AuthProvider (line 1) | interface AuthProvider {
method signin (line 14) | async signin(username: string) {
method signout (line 19) | async signout() {
FILE: examples/auth/src/App.tsx
function App (line 13) | function App() {
function Layout (line 55) | function Layout() {
type AuthContextType (line 74) | interface AuthContextType {
function AuthProvider (line 82) | function AuthProvider({ children }: { children: React.ReactNode }) {
function useAuth (line 104) | function useAuth() {
function AuthStatus (line 108) | function AuthStatus() {
function RequireAuth (line 130) | function RequireAuth({ children }: { children: JSX.Element }) {
function LoginPage (line 145) | function LoginPage() {
function PublicPage (line 183) | function PublicPage() {
function ProtectedPage (line 187) | function ProtectedPage() {
FILE: examples/auth/src/auth.ts
method signin (line 6) | signin(callback: VoidFunction) {
method signout (line 10) | signout(callback: VoidFunction) {
FILE: examples/basic-data-router/src/app.tsx
method Component (line 13) | Component() {
function App (line 20) | function App() {
FILE: examples/basic/src/App.tsx
function App (line 3) | function App() {
function Layout (line 35) | function Layout() {
function Home (line 67) | function Home() {
function About (line 75) | function About() {
function Dashboard (line 83) | function Dashboard() {
function NoMatch (line 91) | function NoMatch() {
FILE: examples/custom-filter-link/src/App.tsx
function App (line 15) | function App() {
type BrandLinkProps (line 39) | interface BrandLinkProps extends Omit<LinkProps, "to"> {
function BrandLink (line 43) | function BrandLink({ brand, children, ...props }: BrandLinkProps) {
function Layout (line 61) | function Layout() {
function SneakerGrid (line 85) | function SneakerGrid() {
function SneakerView (line 138) | function SneakerView() {
function NoMatch (line 171) | function NoMatch() {
FILE: examples/custom-filter-link/src/snkrs.ts
type Sneaker (line 1) | interface Sneaker {
constant SNEAKERS (line 9) | let SNEAKERS: Sneaker[] = [
function filterByBrand (line 68) | function filterByBrand(brand: string) {
function getSneakerById (line 74) | function getSneakerById(id: string) {
FILE: examples/custom-link/src/App.tsx
function App (line 11) | function App() {
function CustomLink (line 34) | function CustomLink({ children, to, ...props }: LinkProps) {
function Layout (line 52) | function Layout() {
function Home (line 73) | function Home() {
function About (line 81) | function About() {
function NoMatch (line 89) | function NoMatch() {
FILE: examples/custom-query-parsing/src/App.tsx
function App (line 6) | function App() {
function useQueryParam (line 44) | function useQueryParam<T>(
type Pizza (line 64) | interface Pizza {
function Home (line 70) | function Home() {
function NoMatch (line 182) | function NoMatch() {
FILE: examples/custom-query-parsing/types/jsurl.d.ts
type Nullable (line 2) | type Nullable<T> = T | null | undefined;
FILE: examples/data-router/src/app.tsx
function App (line 64) | function App() {
function sleep (line 68) | function sleep(n: number = 500) {
function Fallback (line 72) | function Fallback() {
function Layout (line 77) | function Layout() {
type HomeLoaderData (line 141) | interface HomeLoaderData {
function homeLoader (line 145) | async function homeLoader(): Promise<HomeLoaderData> {
function Home (line 152) | function Home() {
function todosAction (line 163) | async function todosAction({ request }: ActionFunctionArgs) {
function todosLoader (line 189) | async function todosLoader(): Promise<Todos> {
function TodosList (line 194) | function TodosList() {
function TodosBoundary (line 243) | function TodosBoundary() {
type TodoItemProps (line 253) | interface TodoItemProps {
function TodoItem (line 258) | function TodoItem({ id, todo }: TodoItemProps) {
function todoLoader (line 277) | async function todoLoader({
function Todo (line 292) | function Todo() {
type DeferredRouteLoaderData (line 305) | interface DeferredRouteLoaderData {
function deferredLoader (line 330) | async function deferredLoader() {
function DeferredPage (line 342) | function DeferredPage() {
function RenderAwaitedData (line 385) | function RenderAwaitedData() {
function RenderAwaitedError (line 390) | function RenderAwaitedError() {
FILE: examples/data-router/src/todos.ts
type Todos (line 1) | interface Todos {
constant TODOS_KEY (line 5) | const TODOS_KEY = "todos";
function saveTodos (line 9) | function saveTodos(todos: Todos): void {
function initializeTodos (line 13) | function initializeTodos(): Todos {
function getTodos (line 25) | function getTodos(): Todos {
function addTodo (line 37) | function addTodo(todo: string): void {
function deleteTodo (line 43) | function deleteTodo(id: string): void {
function resetTodos (line 49) | function resetTodos(): void {
FILE: examples/error-boundaries/src/app.tsx
function App (line 39) | function App() {
FILE: examples/error-boundaries/src/routes.tsx
function Fallback (line 11) | function Fallback() {
function Layout (line 15) | function Layout() {
function RootErrorBoundary (line 53) | function RootErrorBoundary() {
function projectLoader (line 66) | function projectLoader({ params }: LoaderFunctionArgs) {
function Project (line 94) | function Project() {
function ProjectErrorBoundary (line 107) | function ProjectErrorBoundary() {
FILE: examples/lazy-loading-router-provider/src/App.tsx
method lazy (line 25) | async lazy() {
method lazy (line 33) | async lazy() {
method lazy (line 40) | async lazy() {
function App (line 60) | function App() {
function Layout (line 64) | function Layout() {
function Home (line 120) | function Home() {
function NoMatch (line 128) | function NoMatch() {
FILE: examples/lazy-loading-router-provider/src/pages/About.tsx
function loader (line 3) | async function loader() {
function Component (line 8) | function Component() {
FILE: examples/lazy-loading-router-provider/src/pages/Dashboard.tsx
function DashboardLayout (line 3) | function DashboardLayout() {
function DashboardIndex (line 24) | function DashboardIndex() {
type MessagesData (line 32) | interface MessagesData {
function dashboardMessagesLoader (line 36) | async function dashboardMessagesLoader() {
function DashboardMessages (line 47) | function DashboardMessages() {
FILE: examples/lazy-loading/src/App.tsx
function App (line 7) | function App() {
function Layout (line 63) | function Layout() {
function Home (line 87) | function Home() {
function NoMatch (line 95) | function NoMatch() {
FILE: examples/lazy-loading/src/pages/About.tsx
function AboutPage (line 1) | function AboutPage() {
FILE: examples/lazy-loading/src/pages/Dashboard.tsx
function Dashboard (line 3) | function Dashboard() {
function DashboardLayout (line 16) | function DashboardLayout() {
function DashboardIndex (line 37) | function DashboardIndex() {
function Messages (line 45) | function Messages() {
FILE: examples/modal-data-router/src/App.tsx
method loader (line 31) | async loader({ request }: LoaderFunctionArgs) {
method loader (line 44) | async loader({ params }: LoaderFunctionArgs) {
function App (line 58) | function App() {
function Root (line 63) | function Root() {
function Layout (line 101) | function Layout() {
function Home (line 122) | function Home() {
function Gallery (line 140) | function Gallery() {
function ImageView (line 186) | function ImageView() {
function Modal (line 200) | function Modal({ image }: { image: ReturnType<typeof getImageById> }) {
function NoMatch (line 250) | function NoMatch() {
type DialogProps (line 261) | type DialogProps = {
function Dialog (line 269) | function Dialog({
function getFocusableElements (line 374) | function getFocusableElements(container: HTMLElement) {
FILE: examples/modal-data-router/src/images.ts
constant IMAGES (line 1) | const IMAGES = [
function getImageById (line 24) | function getImageById(id: number) {
function loadImage (line 28) | function loadImage(id: string | number) {
FILE: examples/modal-route-with-outlet/src/App.tsx
function App (line 38) | function App() {
function Layout (line 42) | function Layout() {
function Home (line 69) | function Home() {
function Gallery (line 82) | function Gallery() {
function ImageView (line 120) | function ImageView() {
FILE: examples/modal-route-with-outlet/src/images.ts
constant IMAGES (line 1) | let IMAGES = [
function getImageById (line 24) | function getImageById(id: number) {
FILE: examples/modal/src/App.tsx
function App (line 16) | function App() {
function Layout (line 75) | function Layout() {
function Home (line 96) | function Home() {
function Gallery (line 114) | function Gallery() {
function ImageView (line 155) | function ImageView() {
function Modal (line 169) | function Modal() {
function NoMatch (line 221) | function NoMatch() {
FILE: examples/modal/src/images.ts
constant IMAGES (line 1) | let IMAGES = [
function getImageById (line 24) | function getImageById(id: number) {
FILE: examples/multi-app/home/App.jsx
function HomeApp (line 5) | function HomeApp() {
function Layout (line 17) | function Layout() {
function Home (line 53) | function Home() {
function About (line 61) | function About() {
FILE: examples/multi-app/home/no-match.jsx
function NoMatch (line 3) | function NoMatch() {
FILE: examples/multi-app/inbox/App.jsx
function InboxApp (line 6) | function InboxApp() {
function Layout (line 22) | function Layout() {
function Inbox (line 51) | function Inbox() {
function Message (line 102) | function Message() {
FILE: examples/multi-app/inbox/messages.js
function getMessageById (line 69) | function getMessageById(id) {
FILE: examples/multi-app/inbox/no-match.jsx
function NoMatch (line 3) | function NoMatch() {
FILE: examples/multi-app/server.js
function createServer (line 7) | async function createServer() {
FILE: examples/navigation-blocking/src/app.tsx
function App (line 46) | function App() {
function Layout (line 50) | function Layout() {
function ImportantForm (line 85) | function ImportantForm() {
function ConfirmNavigation (line 138) | function ConfirmNavigation({ blocker }: { blocker: Blocker }) {
FILE: examples/notes/src/app.jsx
function App (line 37) | function App() {
FILE: examples/notes/src/notes.js
function getNotes (line 3) | async function getNotes() {
function createNote (line 9) | async function createNote({ title, content }) {
function getNote (line 18) | async function getNote(id) {
function deleteNote (line 24) | async function deleteNote(id) {
function set (line 35) | function set(notes) {
FILE: examples/notes/src/routes/new.jsx
function NewNote (line 5) | function NewNote() {
function action (line 27) | async function action({ request }) {
FILE: examples/notes/src/routes/note.jsx
function Note (line 4) | function Note() {
function loader (line 17) | async function loader({ params }) {
function action (line 23) | async function action({ params }) {
FILE: examples/notes/src/routes/notes.jsx
function Notes (line 1) | function Notes() {
FILE: examples/notes/src/routes/root.jsx
function loader (line 4) | async function loader() {
function Root (line 8) | function Root() {
FILE: examples/route-objects/src/App.tsx
function App (line 4) | function App() {
function Layout (line 55) | function Layout() {
function Home (line 79) | function Home() {
function Courses (line 87) | function Courses() {
function CoursesIndex (line 96) | function CoursesIndex() {
function Course (line 118) | function Course() {
function capitalizeString (line 134) | function capitalizeString(s: string): string {
function NoMatch (line 138) | function NoMatch() {
FILE: examples/scroll-restoration/src/app.tsx
function App (line 49) | function App() {
function Layout (line 53) | function Layout() {
type ArrayLoaderData (line 162) | interface ArrayLoaderData {
function getArrayLoader (line 166) | async function getArrayLoader(): Promise<ArrayLoaderData> {
function LongPage (line 173) | function LongPage() {
FILE: examples/search-params/src/App.tsx
function App (line 4) | function App() {
function randomUser (line 24) | function randomUser() {
function Home (line 29) | function Home() {
function NoMatch (line 122) | function NoMatch() {
FILE: examples/ssr-data-router/server.js
function resolve (line 8) | function resolve(p) {
function createServer (line 12) | async function createServer() {
FILE: examples/ssr-data-router/src/App.tsx
function Layout (line 39) | function Layout() {
function homeLoader (line 99) | async function homeLoader() {
function Home (line 104) | function Home() {
function About (line 114) | function About() {
function dashboardLoader (line 122) | async function dashboardLoader() {
function Dashboard (line 127) | function Dashboard() {
function redirectLoader (line 137) | async function redirectLoader() {
function NoMatch (line 142) | function NoMatch() {
FILE: examples/ssr-data-router/src/entry.client.tsx
function hydrate (line 13) | async function hydrate() {
FILE: examples/ssr-data-router/src/entry.server.tsx
function render (line 11) | async function render(
function createFetchRequest (line 35) | function createFetchRequest(
FILE: examples/ssr-data-router/src/lazy.tsx
type LazyLoaderData (line 3) | interface LazyLoaderData {
function LazyPage (line 14) | function LazyPage() {
FILE: examples/ssr/server.js
function resolve (line 8) | function resolve(p) {
function createServer (line 12) | async function createServer() {
FILE: examples/ssr/src/App.tsx
function App (line 3) | function App() {
function Layout (line 49) | function Layout() {
function Home (line 81) | function Home() {
function About (line 89) | function About() {
function Dashboard (line 97) | function Dashboard() {
function NoMatch (line 105) | function NoMatch() {
FILE: examples/ssr/src/entry.server.tsx
function render (line 7) | function render(url: string) {
FILE: examples/view-transitions/src/main.tsx
method Component (line 34) | Component() {
method Component (line 52) | Component() {
method loader (line 61) | async loader() {
method Component (line 65) | Component() {
method action (line 80) | async action() {
method Component (line 84) | Component() {
method loader (line 99) | async loader({ request }) {
method Component (line 105) | Component() {
method loader (line 131) | async loader({ request }) {
method Component (line 141) | Component() {
method Component (line 166) | Component() {
method Component (line 209) | Component() {
function NavImage (line 227) | function NavImage({ src, idx }: { src: string; idx: number }) {
function Nav (line 253) | function Nav() {
FILE: integration/catch-boundary-data-test.ts
constant ROOT_BOUNDARY_TEXT (line 17) | let ROOT_BOUNDARY_TEXT = "ROOT_TEXT" as const;
constant LAYOUT_BOUNDARY_TEXT (line 18) | let LAYOUT_BOUNDARY_TEXT = "LAYOUT_BOUNDARY_TEXT" as const;
constant OWN_BOUNDARY_TEXT (line 19) | let OWN_BOUNDARY_TEXT = "OWN_BOUNDARY_TEXT" as const;
constant NO_BOUNDARY_LOADER_FILE (line 21) | let NO_BOUNDARY_LOADER_FILE = "/no.loader" as const;
constant NO_BOUNDARY_LOADER (line 22) | let NO_BOUNDARY_LOADER = "/no/loader" as const;
constant HAS_BOUNDARY_LAYOUT_NESTED_LOADER_FILE (line 24) | let HAS_BOUNDARY_LAYOUT_NESTED_LOADER_FILE =
constant HAS_BOUNDARY_LAYOUT_NESTED_LOADER (line 26) | let HAS_BOUNDARY_LAYOUT_NESTED_LOADER = "/yes/loader-layout-boundary" as...
constant HAS_BOUNDARY_NESTED_LOADER_FILE (line 28) | let HAS_BOUNDARY_NESTED_LOADER_FILE = "/yes.loader-self-boundary" as const;
constant HAS_BOUNDARY_NESTED_LOADER (line 29) | let HAS_BOUNDARY_NESTED_LOADER = "/yes/loader-self-boundary" as const;
constant ROOT_DATA (line 31) | let ROOT_DATA = "root data";
constant LAYOUT_DATA (line 32) | let LAYOUT_DATA = "root data";
FILE: integration/client-data-test.ts
function getFiles (line 20) | function getFiles(
FILE: integration/defer-test.ts
constant ROOT_ID (line 12) | const ROOT_ID = "ROOT_ID";
constant INDEX_ID (line 13) | const INDEX_ID = "INDEX_ID";
constant DEFERRED_ID (line 14) | const DEFERRED_ID = "DEFERRED_ID";
constant RESOLVED_DEFERRED_ID (line 15) | const RESOLVED_DEFERRED_ID = "RESOLVED_DEFERRED_ID";
constant FALLBACK_ID (line 16) | const FALLBACK_ID = "FALLBACK_ID";
constant ERROR_ID (line 17) | const ERROR_ID = "ERROR_ID";
constant ERROR_BOUNDARY_ID (line 18) | const ERROR_BOUNDARY_ID = "ERROR_BOUNDARY_ID";
constant MANUAL_RESOLVED_ID (line 19) | const MANUAL_RESOLVED_ID = "MANUAL_RESOLVED_ID";
constant MANUAL_FALLBACK_ID (line 20) | const MANUAL_FALLBACK_ID = "MANUAL_FALLBACK_ID";
constant MANUAL_ERROR_ID (line 21) | const MANUAL_ERROR_ID = "MANUAL_ERROR_ID";
function counterHtml (line 551) | function counterHtml(id: string, val: number) {
function getCriticalHTML (line 556) | function getCriticalHTML(html: string) {
function getDeferredHTML (line 562) | function getDeferredHTML(html: string) {
function ensureInteractivity (line 1261) | async function ensureInteractivity(page: Page, id: string, expect: numbe...
function monitorConsole (line 1268) | function monitorConsole(page: Page) {
FILE: integration/error-boundary-test.ts
function getFiles (line 593) | function getFiles({
FILE: integration/error-boundary-v2-test.ts
function runBoundaryTests (line 186) | function runBoundaryTests() {
function waitForAndAssert (line 249) | async function waitForAndAssert(
FILE: integration/error-data-request-test.ts
function assertLoggedErrorInstance (line 103) | function assertLoggedErrorInstance(message: string) {
FILE: integration/fog-of-war-test.ts
function getFiles (line 12) | function getFiles() {
FILE: integration/form-test.ts
function runFormTests (line 521) | function runFormTests() {
FILE: integration/fs-routes-test.ts
function runTests (line 157) | function runTests() {
function runTests (line 424) | function runTests() {
FILE: integration/helpers/cloudflare-dev-proxy-template/app/entry.server.tsx
function handleRequest (line 6) | async function handleRequest(
FILE: integration/helpers/cloudflare-dev-proxy-template/app/root.tsx
function Layout (line 3) | function Layout({ children }: { children: React.ReactNode }) {
function App (line 21) | function App() {
FILE: integration/helpers/cloudflare-dev-proxy-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/create-fixture.ts
constant TMP_DIR (line 26) | const TMP_DIR = path.join(root, ".tmp", "integration");
function spawnTestServer (line 28) | async function spawnTestServer({
type FixtureInit (line 87) | interface FixtureInit {
type Fixture (line 97) | type Fixture = Awaited<ReturnType<typeof createFixture>>;
type AppFixture (line 98) | type AppFixture = Awaited<ReturnType<typeof createAppFixture>>;
function json (line 103) | function json(value: JsonObject) {
function createFixture (line 109) | async function createFixture(init: FixtureInit, mode?: ServerMode) {
function createAppFixture (line 282) | async function createAppFixture(fixture: Fixture, mode?: ServerMode) {
function createFixtureProject (line 435) | async function createFixtureProject(
function reactRouterBuild (line 490) | function reactRouterBuild(
function writeTestFiles (line 538) | async function writeTestFiles(
FILE: integration/helpers/express.ts
function server (line 3) | function server() {
function rsc (line 45) | function rsc() {
FILE: integration/helpers/fixtures.ts
type Page (line 18) | interface Page {
constant ROOT (line 24) | const ROOT = Path.join(__filename, "../../..");
constant TMP (line 25) | const TMP = Path.join(ROOT, ".tmp/integration");
type Edits (line 29) | type Edits = Record<string, string | ((contents: string) => string)>;
function applyEdits (line 31) | async function applyEdits(cwd: string, edits: Edits) {
FILE: integration/helpers/playwright-fixture.ts
class PlaywrightFixture (line 11) | class PlaywrightFixture {
method constructor (line 15) | constructor(app: AppFixture, page: Page) {
method goto (line 31) | async goto(href: string, waitForHydration?: boolean): Promise<Response> {
method clickLink (line 54) | async clickLink(href: string, options: { wait: boolean } = { wait: tru...
method uploadFile (line 73) | async uploadFile(inputSelector: string, ...filePaths: string[]) {
method clickSubmitButton (line 89) | async clickSubmitButton(
method clickElement (line 122) | async clickElement(selector: string) {
method waitForNetworkAfter (line 137) | async waitForNetworkAfter(fn: () => Promise<unknown>) {
method goBack (line 145) | async goBack(options: { wait: boolean } = { wait: true }) {
method reload (line 156) | async reload(options: { wait: boolean } = { wait: true }) {
method collectSingleFetchResponses (line 169) | collectSingleFetchResponses() {
method collectResponses (line 180) | collectResponses(filter?: (url: URL) => boolean) {
method getHtml (line 198) | getHtml(selector?: string) {
method getElement (line 207) | async getElement(selector: string) {
method poke (line 217) | async poke(seconds: number = 10, href: string = "/") {
function getHtml (line 228) | async function getHtml(page: Page, selector?: string) {
function getElement (line 236) | function getElement(source: string, selector: string) {
function selectHtml (line 244) | async function selectHtml(source: string, selector: string) {
function prettyHtml (line 250) | async function prettyHtml(source: string) {
function doAndWait (line 254) | async function doAndWait(
FILE: integration/helpers/rsc-vite-framework/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/rsc-vite-framework/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/rsc-vite/src/entry.rsc.tsx
function fetchServer (line 15) | async function fetchServer(request: Request) {
function handler (line 35) | async function handler(request: Request) {
FILE: integration/helpers/rsc-vite/src/entry.ssr.tsx
function handler (line 9) | async function handler(
FILE: integration/helpers/rsc-vite/src/routes/home.tsx
function HomeRoute (line 1) | function HomeRoute() {
FILE: integration/helpers/rsc-vite/src/routes/root.tsx
function Layout (line 3) | function Layout({ children }: { children: React.ReactNode }) {
function RootRoute (line 20) | function RootRoute() {
FILE: integration/helpers/stream.ts
function match (line 3) | async function match(
FILE: integration/helpers/templates.ts
type Template (line 17) | type Template = (typeof templates)[number];
function getTemplates (line 19) | function getTemplates(names?: Array<Template["name"]>) {
FILE: integration/helpers/vite-5-template/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/vite-5-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/vite-6-template/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/vite-6-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/vite-7-beta-template/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/vite-7-beta-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/vite-plugin-cloudflare-template/app/entry.server.tsx
function handleRequest (line 6) | async function handleRequest(
FILE: integration/helpers/vite-plugin-cloudflare-template/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/vite-plugin-cloudflare-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/vite-plugin-cloudflare-template/workers/app.ts
type CloudflareEnvironment (line 4) | interface CloudflareEnvironment extends Env {}
type AppLoadContext (line 8) | interface AppLoadContext {
method fetch (line 22) | async fetch(request, env, ctx) {
FILE: integration/helpers/vite-rolldown-template/app/root.tsx
function App (line 3) | function App() {
FILE: integration/helpers/vite-rolldown-template/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: integration/helpers/vite.ts
constant TMP_DIR (line 24) | const TMP_DIR = path.join(root, ".tmp/integration");
type ViteConfigServerArgs (line 46) | type ViteConfigServerArgs = {
type ViteConfigBuildArgs (line 51) | type ViteConfigBuildArgs = {
type ViteConfigBaseArgs (line 57) | type ViteConfigBaseArgs = {
type ViteConfigArgs (line 65) | type ViteConfigArgs = (
type FrameworkModeViteMajorTemplateName (line 230) | type FrameworkModeViteMajorTemplateName =
type FrameworkModeRscTemplateName (line 237) | type FrameworkModeRscTemplateName = "rsc-vite-framework";
type FrameworkModeCloudflareTemplateName (line 239) | type FrameworkModeCloudflareTemplateName =
type RscBundlerTemplateName (line 243) | type RscBundlerTemplateName = "rsc-vite";
type TemplateName (line 245) | type TemplateName =
function createProject (line 271) | async function createProject(
type ServerArgs (line 378) | type ServerArgs = {
type Page (line 429) | interface Page {
type Files (line 434) | type Files = (args: { port: number }) => Promise<Record<string, string>>;
type Fixtures (line 435) | type Fixtures = {
function node (line 539) | function node(
function waitForServer (line 557) | async function waitForServer(
function bufferize (line 587) | function bufferize(stream: Readable): () => string {
function createEditor (line 593) | function createEditor(projectDir: string) {
function grep (line 608) | function grep(cwd: string, pattern: RegExp): string[] {
FILE: integration/navigation-state-test.ts
constant STATES (line 11) | const STATES = {
constant IDLE_STATE (line 21) | const IDLE_STATE = {
FILE: integration/prefetch-test.ts
type PrefetchType (line 17) | type PrefetchType = "intent" | "render" | "none" | "viewport";
function fixtureFactory (line 20) | function fixtureFactory(
FILE: integration/resource-routes-test.ts
function runTests (line 176) | function runTests() {
function runTests (line 386) | function runTests() {
FILE: integration/route-collisions-test.ts
constant ROOT_FILE_CONTENTS (line 6) | let ROOT_FILE_CONTENTS = js`
constant LAYOUT_FILE_CONTENTS (line 21) | let LAYOUT_FILE_CONTENTS = js`
constant LEAF_FILE_CONTENTS (line 29) | let LEAF_FILE_CONTENTS = js`
function setup (line 52) | async function setup(files: Record<string, string>) {
FILE: integration/rsc/utils.ts
type Implementation (line 12) | type Implementation = {
function setupRscTest (line 44) | async function setupRscTest({
FILE: integration/scroll-test.ts
function runTests (line 84) | function runTests() {
FILE: integration/session-storage-denied-test.ts
method get (line 87) | get() {
method set (line 90) | set() {
FILE: integration/set-cookie-revalidation-test.ts
constant BANNER_MESSAGE (line 14) | let BANNER_MESSAGE = "you do not have permission to view /protected";
FILE: integration/single-fetch-test.ts
constant ISO_DATE (line 22) | const ISO_DATE = "2024-03-12T12:00:00.000Z";
FILE: integration/split-route-modules-test.ts
function splittableHydrateFallbackDownloaded (line 228) | async function splittableHydrateFallbackDownloaded(page: Page) {
function unsplittableHydrateFallbackDownloaded (line 234) | async function unsplittableHydrateFallbackDownloaded(page: Page) {
function mixedHydrateFallbackDownloaded (line 239) | async function mixedHydrateFallbackDownloaded(page: Page) {
function unblockClientLoader (line 245) | async function unblockClientLoader(page: Page) {
FILE: integration/transition-test.ts
method start (line 251) | async start(controller) {
FILE: integration/vite-basename-test.ts
function configFiles (line 65) | async function configFiles({
function setup (line 181) | async function setup({
function setup (line 323) | async function setup({
function setup (line 382) | async function setup({
function setup (line 445) | async function setup({
function workflowDev (line 588) | async function workflowDev({
function workflowBuild (line 668) | async function workflowBuild({
FILE: integration/vite-cloudflare-test.ts
function getFiles (line 7) | function getFiles({
function workflow (line 166) | async function workflow({ page, port }: { page: Page; port: number }) {
FILE: integration/vite-css-lazy-loading-test.ts
constant FORCIBLY_UNIQUE_HREF_SELECTOR (line 15) | const FORCIBLY_UNIQUE_HREF_SELECTOR = "[href$='#']";
constant CSS_LINK_SELECTOR (line 16) | const CSS_LINK_SELECTOR = "link[rel='stylesheet']";
constant ANY_FORCIBLY_UNIQUE_CSS_LINK_SELECTOR (line 17) | const ANY_FORCIBLY_UNIQUE_CSS_LINK_SELECTOR = `link[rel='stylesheet']${F...
constant CSS_COMPONENT_LINK_SELECTOR (line 18) | const CSS_COMPONENT_LINK_SELECTOR =
constant CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR (line 20) | const CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR = `link[rel='styleshee...
function getColor (line 22) | function getColor(page: Page, selector: string) {
FILE: integration/vite-css-test.ts
constant PADDING (line 22) | const PADDING = "20px";
constant NEW_PADDING (line 23) | const NEW_PADDING = "30px";
type RouteBasePath (line 37) | type RouteBasePath =
function pageLoadWorkflow (line 479) | async function pageLoadWorkflow({
function hmrWorkflow (line 513) | async function hmrWorkflow({
FILE: integration/vite-dev-test.ts
function editFile (line 463) | async function editFile(edit: (data: string) => string) {
FILE: integration/vite-hmr-hdr-test.ts
function workflow (line 147) | async function workflow({
FILE: integration/vite-manifests-test.ts
function createRoute (line 11) | function createRoute(path: string) {
constant TEST_ROUTES (line 21) | const TEST_ROUTES = [
FILE: integration/vite-plugin-cloudflare-test.ts
function defineFiles (line 9) | function defineFiles({
FILE: integration/vite-prerender-test.ts
function listAllFiles (line 137) | function listAllFiles(_dir: string) {
function captureRequests (line 940) | function captureRequests(page: Page) {
function clearRequests (line 954) | function clearRequests(requests: string[]) {
FILE: integration/vite-presets-test.ts
function pathStartsWithCwd (line 165) | function pathStartsWithCwd(pathname: string) {
function relativeToCwd (line 169) | function relativeToCwd(pathname: string) {
FILE: integration/vite-server-bundles-test.ts
constant ROUTE_FILE_COMMENT (line 28) | const ROUTE_FILE_COMMENT = "// THIS IS A ROUTE FILE";
function createRoute (line 30) | function createRoute(path: string) {
constant TEST_ROUTES (line 56) | const TEST_ROUTES = [
FILE: packages/create-react-router/__tests__/create-react-router-test.ts
constant DOWN (line 28) | const DOWN = "\x1B\x5B\x42";
constant ENTER (line 29) | const ENTER = "\x0D";
constant TEMP_DIR (line 31) | const TEMP_DIR = path.join(
function maskTempDir (line 35) | function maskTempDir(string: string) {
function getProjectDir (line 63) | function getProjectDir(name: string) {
function execCreateReactRouter (line 1176) | async function execCreateReactRouter({
type ShellResult (line 1218) | interface ShellResult {
type ShellInteractions (line 1224) | type ShellInteractions = Array<
function interactWithShell (line 1229) | async function interactWithShell(
function defer (line 1312) | function defer<Value>() {
FILE: packages/create-react-router/__tests__/fixtures/basic/app/root.tsx
function Layout (line 3) | function Layout({ children }: { children: React.ReactNode }) {
function App (line 21) | function App() {
FILE: packages/create-react-router/__tests__/fixtures/basic/app/routes/home.tsx
function Index (line 10) | function Index() {
FILE: packages/create-react-router/__tests__/github-mocks.ts
type RequestHandler (line 7) | type RequestHandler = Parameters<typeof setupServer>[0];
function isDirectory (line 9) | async function isDirectory(d: string) {
function isFile (line 16) | async function isFile(d: string) {
type GHContentsDescription (line 24) | type GHContentsDescription = {
type GHContent (line 41) | type GHContent = {
FILE: packages/create-react-router/copy-template.ts
function agent (line 17) | function agent(url: string) {
function copyTemplate (line 21) | async function copyTemplate(
type CopyTemplateOptions (line 75) | interface CopyTemplateOptions {
function isLocalFilePath (line 82) | function isLocalFilePath(input: string): boolean {
function copyTemplateFromRemoteTarball (line 95) | async function copyTemplateFromRemoteTarball(
function copyTemplateFromGithubRepoShorthand (line 103) | async function copyTemplateFromGithubRepoShorthand(
function copyTemplateFromGithubRepoUrl (line 118) | async function copyTemplateFromGithubRepoUrl(
function copyTemplateFromGenericUrl (line 126) | async function copyTemplateFromGenericUrl(
function copyTemplateFromLocalFilePath (line 134) | async function copyTemplateFromLocalFilePath(
function extractLocalTarball (line 155) | async function extractLocalTarball(
type TarballDownloadOptions (line 175) | interface TarballDownloadOptions {
function downloadAndExtractRepoTarball (line 181) | async function downloadAndExtractRepoTarball(
type DownloadAndExtractTarballOptions (line 210) | interface DownloadAndExtractTarballOptions {
function downloadAndExtractTarball (line 215) | async function downloadAndExtractTarball(
function writeReadableStreamToWritable (line 364) | async function writeReadableStreamToWritable(
function isValidGithubRepoUrl (line 391) | function isValidGithubRepoUrl(
function isGithubRepoShorthand (line 418) | function isGithubRepoShorthand(value: string) {
function isGithubReleaseAssetUrl (line 428) | function isGithubReleaseAssetUrl(url: string) {
function getGithubReleaseAssetInfo (line 442) | function getGithubReleaseAssetInfo(browserUrl: string): ReleaseAssetInfo {
function getRepoInfo (line 466) | function getRepoInfo(validatedGithubUrl: string): RepoInfo {
class CopyTemplateError (line 497) | class CopyTemplateError extends Error {
method constructor (line 498) | constructor(message: string) {
type RepoInfo (line 504) | interface RepoInfo {
type GitHubApiReleaseAsset (line 512) | interface GitHubApiReleaseAsset {
type GitHubApiUploader (line 528) | interface GitHubApiUploader {
type ReleaseAssetInfo (line 552) | interface ReleaseAssetInfo {
type GithubUrlString (line 560) | type GithubUrlString =
FILE: packages/create-react-router/index.ts
function createReactRouter (line 33) | async function createReactRouter(argv: string[]) {
function getContext (line 68) | async function getContext(argv: string[]): Promise<Context> {
type Context (line 169) | interface Context {
function introStep (line 191) | async function introStep(ctx: Context) {
function projectNameStep (line 208) | async function projectNameStep(ctx: Context) {
function copyTemplateToTempDirStep (line 248) | async function copyTemplateToTempDirStep(ctx: Context) {
function copyTempDirToAppDirStep (line 302) | async function copyTempDirToAppDirStep(ctx: Context) {
function installDependenciesQuestionStep (line 383) | async function installDependenciesQuestionStep(ctx: Context) {
function installDependenciesStep (line 397) | async function installDependenciesStep(ctx: Context) {
function gitInitQuestionStep (line 436) | async function gitInitQuestionStep(ctx: Context) {
function gitInitStep (line 457) | async function gitInitStep(ctx: Context) {
function doneStep (line 488) | async function doneStep(ctx: Context) {
type PackageManager (line 518) | type PackageManager = (typeof validPackageManagers)[number];
function validatePackageManager (line 520) | function validatePackageManager(pkgManager: string): PackageManager {
function installDependencies (line 524) | async function installDependencies({
function updatePackageJSON (line 544) | async function updatePackageJSON(ctx: Context) {
function loadingIndicator (line 610) | async function loadingIndicator(args: {
function title (line 623) | function title(text: string) {
function printHelp (line 627) | function printHelp(ctx: Context) {
function align (line 688) | function align(text: string, dir: "start" | "end" | "center", len: numbe...
FILE: packages/create-react-router/loading-indicator.ts
constant GRADIENT_COLORS (line 9) | const GRADIENT_COLORS: Array<`#${string}`> = [
constant MAX_FRAMES (line 37) | const MAX_FRAMES = 8;
constant LEADING_FRAMES (line 39) | const LEADING_FRAMES = Array.from(
constant TRAILING_FRAMES (line 43) | const TRAILING_FRAMES = Array.from(
constant INDICATOR_FULL_FRAMES (line 47) | const INDICATOR_FULL_FRAMES = [
constant INDICATOR_GRADIENT (line 53) | const INDICATOR_GRADIENT = reverse(
function renderLoadingIndicator (line 57) | async function renderLoadingIndicator({
function loadingIndicatorFrame (line 87) | function loadingIndicatorFrame(offset = 0) {
function getGradientAnimationFrames (line 98) | function getGradientAnimationFrames() {
function gradient (line 104) | async function gradient(
function getColorlessFrame (line 167) | function getColorlessFrame(frameIndex: number) {
function getMotionlessFrame (line 173) | function getMotionlessFrame(frameIndex: number) {
FILE: packages/create-react-router/prompt.ts
function prompt (line 30) | async function prompt<
function toPrompt (line 74) | function toPrompt<
type UnionToIntersection (line 106) | type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) e...
type BasePromptType (line 112) | interface BasePromptType {
type TextPromptType (line 116) | interface TextPromptType extends BasePromptType {
type ConfirmPromptType (line 120) | interface ConfirmPromptType extends BasePromptType {
type SelectPromptType (line 124) | interface SelectPromptType<
type MultiSelectPromptType (line 131) | interface MultiSelectPromptType<
type SelectChoiceType (line 138) | interface SelectChoiceType {
type PromptType (line 144) | type PromptType<
type PromptChoices (line 152) | type PromptChoices<T extends PromptType<any>> =
type Answer (line 159) | type Answer<
type Answers (line 172) | type Answers<
type PromptTypeOptions (line 181) | interface PromptTypeOptions<
FILE: packages/create-react-router/prompts-confirm.ts
type ConfirmPromptOptions (line 10) | interface ConfirmPromptOptions extends PromptOptions {
type ConfirmPromptChoices (line 19) | type ConfirmPromptChoices = [
class ConfirmPrompt (line 24) | class ConfirmPrompt extends Prompt {
method constructor (line 38) | constructor(opts: ConfirmPromptOptions) {
method type (line 53) | get type() {
method exit (line 57) | exit() {
method abort (line 61) | abort() {
method submit (line 69) | submit() {
method moveCursor (line 80) | moveCursor(n: number) {
method reset (line 86) | reset() {
method first (line 92) | first() {
method last (line 97) | last() {
method left (line 102) | left() {
method right (line 111) | right() {
method _ (line 120) | _(c: string, key: ActionKey) {
method render (line 138) | render() {
FILE: packages/create-react-router/prompts-multi-select.ts
type MultiSelectPromptOptions (line 11) | interface MultiSelectPromptOptions<
class MultiSelectPrompt (line 23) | class MultiSelectPrompt<
method constructor (line 39) | constructor(opts: MultiSelectPromptOptions<Choices>) {
method type (line 59) | get type() {
method exit (line 63) | exit() {
method abort (line 67) | abort() {
method submit (line 76) | submit() {
method finish (line 80) | finish() {
method moveCursor (line 91) | moveCursor(n: number) {
method toggle (line 96) | toggle() {
method _ (line 103) | _(c: string, key: ActionKey) {
method reset (line 113) | reset() {
method first (line 119) | first() {
method last (line 124) | last() {
method up (line 129) | up() {
method down (line 138) | down() {
method render (line 147) | render() {
FILE: packages/create-react-router/prompts-prompt-base.ts
class Prompt (line 12) | class Prompt extends EventEmitter {
method constructor (line 23) | constructor(opts: PromptOptions = {}) {
method type (line 69) | get type(): string {
method bell (line 73) | bell() {
method fire (line 77) | fire() {
method render (line 86) | render() {
method _ (line 91) | _(c: string, key: ActionKey) {
type PromptOptions (line 96) | interface PromptOptions {
FILE: packages/create-react-router/prompts-select.ts
type SelectChoice (line 10) | interface SelectChoice {
type SelectPromptOptions (line 16) | interface SelectPromptOptions<
class SelectPrompt (line 28) | class SelectPrompt<
method constructor (line 46) | constructor(opts: SelectPromptOptions<Choices>) {
method type (line 66) | get type() {
method exit (line 70) | exit() {
method abort (line 74) | abort() {
method submit (line 83) | submit() {
method delete (line 94) | delete() {
method _ (line 99) | _(c: string, key: ActionKey) {
method moveCursor (line 122) | moveCursor(n: number) {
method reset (line 128) | reset() {
method first (line 134) | first() {
method last (line 139) | last() {
method up (line 144) | up() {
method down (line 153) | down() {
method highlight (line 162) | highlight(label: string) {
method render (line 173) | render() {
FILE: packages/create-react-router/prompts-text.ts
type TextPromptOptions (line 17) | interface TextPromptOptions extends PromptOptions {
class TextPrompt (line 27) | class TextPrompt extends Prompt {
method constructor (line 53) | constructor(opts: TextPromptOptions) {
method type (line 70) | get type() {
method value (line 74) | set value(v: string) {
method value (line 86) | get value() {
method reset (line 90) | reset() {
method exit (line 98) | exit() {
method abort (line 102) | abort() {
method validate (line 113) | async validate() {
method submit (line 122) | async submit() {
method next (line 141) | next() {
method moveCursor (line 149) | moveCursor(n: number) {
method _ (line 155) | _(c: string, key: ActionKey) {
method delete (line 164) | delete() {
method deleteForward (line 181) | deleteForward() {
method first (line 198) | first() {
method last (line 203) | last() {
method left (line 208) | left() {
method right (line 214) | right() {
method isCursorAtStart (line 221) | isCursorAtStart() {
method isCursorAtEnd (line 225) | isCursorAtEnd() {
method render (line 232) | render() {
FILE: packages/create-react-router/utils.ts
constant SUPPORTS_COLOR (line 11) | const SUPPORTS_COLOR = chalk.supportsColor && !process.env.NO_COLOR;
function safeColor (line 57) | function safeColor(style: chalk.Chalk) {
function isInteractive (line 66) | function isInteractive() {
function log (line 80) | function log(message: string) {
function setStderr (line 86) | function setStderr(writable: typeof process.stderr) {
function logError (line 90) | function logError(message: string) {
function logBullet (line 94) | function logBullet(
function debug (line 121) | function debug(prefix: string, text?: string | string[]) {
function info (line 125) | function info(prefix: string, text?: string | string[]) {
function success (line 129) | function success(text: string) {
function error (line 133) | function error(prefix: string, text?: string | string[]) {
function sleep (line 138) | function sleep(ms: number) {
function toValidProjectName (line 142) | function toValidProjectName(projectName: string) {
function isValidProjectName (line 156) | function isValidProjectName(projectName: string) {
function identity (line 162) | function identity<V>(v: V) {
function strip (line 166) | function strip(str: string) {
function reverse (line 175) | function reverse<T>(arr: T[]): T[] {
function isValidJsonObject (line 179) | function isValidJsonObject(obj: any): obj is Record<string, unknown> {
function directoryExists (line 183) | async function directoryExists(p: string) {
function fileExists (line 192) | async function fileExists(p: string) {
function ensureDirectory (line 201) | async function ensureDirectory(dir: string) {
function pathContains (line 207) | function pathContains(path: string, dir: string) {
function isUrl (line 212) | function isUrl(value: string | URL) {
function clear (line 221) | function clear(prompt: string, perLine: number) {
function lines (line 232) | function lines(msg: string, perLine: number) {
function action (line 240) | function action(key: ActionKey, isSelect: boolean) {
function stripDirectoryFromPath (line 276) | function stripDirectoryFromPath(dir: string, filePath: string) {
constant IGNORED_TEMPLATE_DIRECTORIES (line 292) | const IGNORED_TEMPLATE_DIRECTORIES = [".git", "node_modules"];
function getDirectoryFilesRecursive (line 294) | async function getDirectoryFilesRecursive(dir: string) {
FILE: packages/react-router-architect/__tests__/server-test.ts
function createMockEvent (line 31) | function createMockEvent(event: Partial<APIGatewayProxyEventV2> = {}) {
FILE: packages/react-router-architect/binaryTypes.ts
function isBinaryType (line 65) | function isBinaryType(contentType: string | null | undefined) {
FILE: packages/react-router-architect/server.ts
type MaybePromise (line 18) | type MaybePromise<T> = T | Promise<T>;
type GetLoadContextFunction (line 27) | type GetLoadContextFunction = (
type RequestHandler (line 33) | type RequestHandler = APIGatewayProxyHandlerV2;
function createRequestHandler (line 39) | function createRequestHandler({
function createReactRouterRequest (line 60) | function createReactRouterRequest(
function createReactRouterHeaders (line 87) | function createReactRouterHeaders(
function sendReactRouterResponse (line 106) | async function sendReactRouterResponse(
FILE: packages/react-router-architect/sessions/arcTableSessionStorage.ts
type ArcTableSessionStorageOptions (line 10) | interface ArcTableSessionStorageOptions {
function createArcTableSessionStorage (line 46) | function createArcTableSessionStorage<
FILE: packages/react-router-cloudflare/sessions/workersKVStorage.ts
type WorkersKVSessionStorageOptions (line 8) | interface WorkersKVSessionStorageOptions {
function createWorkersKVSessionStorage (line 27) | function createWorkersKVSessionStorage<
FILE: packages/react-router-cloudflare/worker.ts
type MaybePromise (line 10) | type MaybePromise<T> = T | Promise<T>;
type GetLoadContextFunction (line 19) | type GetLoadContextFunction<
type RequestHandler (line 43) | type RequestHandler<Env = any> = PagesFunction<Env>;
type createPagesFunctionHandlerParams (line 45) | interface createPagesFunctionHandlerParams<Env = any> {
function createRequestHandler (line 51) | function createRequestHandler<Env = any>({
function createPagesFunctionHandler (line 87) | function createPagesFunctionHandler<Env = any>({
FILE: packages/react-router-dev/__tests__/fixtures/basic/app/root.tsx
function App (line 3) | function App() {
FILE: packages/react-router-dev/__tests__/fixtures/basic/app/routes/_index.tsx
function Index (line 10) | function Index() {
FILE: packages/react-router-dev/__tests__/utils/captureError.ts
class NoErrorThrownError (line 1) | class NoErrorThrownError extends Error {}
function captureError (line 3) | async function captureError(
FILE: packages/react-router-dev/__tests__/utils/withApp.ts
function withApp (line 19) | async function withApp<Result>(
FILE: packages/react-router-dev/cli/commands.ts
function routes (line 20) | async function routes(
function build (line 43) | async function build(
function dev (line 60) | async function dev(root?: string, options: ViteDevOptions = {}) {
function generateEntry (line 83) | async function generateEntry(
function resolveRootDirectory (line 194) | function resolveRootDirectory(root?: string, flags?: { config?: string }) {
function checkForEntry (line 205) | async function checkForEntry(
function createServerEntry (line 221) | async function createServerEntry(
function createClientEntry (line 231) | async function createClientEntry(
function typegen (line 241) | async function typegen(
FILE: packages/react-router-dev/cli/detectPackageManager.ts
type PackageManager (line 1) | type PackageManager = "npm" | "pnpm" | "yarn" | "bun";
FILE: packages/react-router-dev/cli/run.ts
function run (line 84) | async function run(argv: string[] = process.argv.slice(2)) {
FILE: packages/react-router-dev/cli/useJavascript.ts
function transpile (line 8) | async function transpile(
FILE: packages/react-router-dev/config/config.ts
type ExcludedConfigPresetKey (line 30) | type ExcludedConfigPresetKey = (typeof excludedConfigPresetKeys)[number];
type ConfigPreset (line 32) | type ConfigPreset = Omit<ReactRouterConfig, ExcludedConfigPresetKey>;
type Preset (line 34) | type Preset = {
type BranchRoute (line 51) | type BranchRoute = Pick<
type ServerBundlesFunction (line 60) | type ServerBundlesFunction = (args: {
type BaseBuildManifest (line 64) | type BaseBuildManifest = {
type DefaultBuildManifest (line 68) | type DefaultBuildManifest = BaseBuildManifest & {
type ServerBundlesBuildManifest (line 73) | type ServerBundlesBuildManifest = BaseBuildManifest & {
type ServerModuleFormat (line 83) | type ServerModuleFormat = "esm" | "cjs";
type ValidateConfigFunction (line 85) | type ValidateConfigFunction = (config: ReactRouterConfig) => string | void;
type FutureConfig (line 87) | interface FutureConfig {
type BuildManifest (line 109) | type BuildManifest = DefaultBuildManifest | ServerBundlesBuildManifest;
type BuildEndHook (line 111) | type BuildEndHook = (args: {
type PrerenderPaths (line 117) | type PrerenderPaths =
type ReactRouterConfig (line 127) | type ReactRouterConfig = {
type ResolvedReactRouterConfig (line 262) | type ResolvedReactRouterConfig = Readonly<{
type Result (line 400) | type Result<T> =
type ConfigResult (line 412) | type ConfigResult = Result<ResolvedReactRouterConfig>;
function ok (line 414) | function ok<T>(value: T): Result<T> {
function err (line 418) | function err<T>(error: string): Result<T> {
function resolveConfig (line 422) | async function resolveConfig({
type ChokidarEventName (line 727) | type ChokidarEventName = ChokidarEmitArgs[0];
type ChangeHandler (line 729) | type ChangeHandler = (args: {
type ConfigLoader (line 739) | type ConfigLoader = {
function createConfigLoader (line 745) | async function createConfigLoader({
function loadConfig (line 938) | async function loadConfig({
function resolveEntryFiles (line 958) | async function resolveEntryFiles({
function resolveRSCEntryFiles (line 1042) | async function resolveRSCEntryFiles({
function omitRoutes (line 1074) | function omitRoutes(
function isEntryFile (line 1085) | function isEntryFile(entryBasename: string, filename: string) {
function findEntry (line 1089) | function findEntry(
function isEntryFileDependency (line 1124) | function isEntryFileDependency(
FILE: packages/react-router-dev/config/default-rsc-entries/entry.rsc.tsx
function fetchServer (line 21) | function fetchServer(
method fetch (line 49) | async fetch(request: Request, requestContext?: RouterContextProvider) {
FILE: packages/react-router-dev/config/default-rsc-entries/entry.ssr.tsx
function generateHTML (line 9) | async function generateHTML(
FILE: packages/react-router-dev/config/defaults/entry.server.node.tsx
function handleRequest (line 12) | function handleRequest(
FILE: packages/react-router-dev/config/format.ts
type RoutesFormat (line 3) | type RoutesFormat = "json" | "jsx";
function formatRoutes (line 5) | function formatRoutes(
type JsonFormattedRoute (line 17) | type JsonFormattedRoute = {
function formatRoutesAsJson (line 26) | function formatRoutesAsJson(routeManifest: RouteManifest): string {
function formatRoutesAsJsx (line 56) | function formatRoutesAsJsx(routeManifest: RouteManifest) {
FILE: packages/react-router-dev/config/is-react-router-repo.ts
function isReactRouterRepo (line 3) | function isReactRouterRepo() {
FILE: packages/react-router-dev/config/routes.ts
function setAppDirectory (line 11) | function setAppDirectory(directory: string) {
function getAppDirectory (line 19) | function getAppDirectory() {
type RouteManifestEntry (line 24) | interface RouteManifestEntry {
type RouteManifest (line 59) | interface RouteManifest {
type RouteConfigEntry (line 68) | interface RouteConfigEntry {
type ResolvedRouteConfig (line 130) | type ResolvedRouteConfig = v.InferInput<typeof resolvedRouteConfigSchema>;
type RouteConfig (line 135) | type RouteConfig = ResolvedRouteConfig | Promise<ResolvedRouteConfig>;
function validateRouteConfig (line 137) | function validateRouteConfig({
type CreateRouteOptions (line 191) | type CreateRouteOptions = Pick<
function route (line 210) | function route(
type CreateIndexOptions (line 235) | type CreateIndexOptions = Pick<
function index (line 243) | function index(file: string, options?: CreateIndexOptions): RouteConfigE...
type CreateLayoutOptions (line 254) | type CreateLayoutOptions = Pick<
function layout (line 268) | function layout(
function prefix (line 292) | function prefix(
function relative (line 320) | function relative(directory: string): typeof helpers {
function configRoutesToRouteManifest (line 356) | function configRoutesToRouteManifest(
function createRouteId (line 396) | function createRouteId(file: string) {
function stripFileExtension (line 400) | function stripFileExtension(file: string) {
function joinRoutePaths (line 404) | function joinRoutePaths(path1: string, path2: string): string {
FILE: packages/react-router-dev/invariant.ts
function invariant (line 11) | function invariant(value: any, message?: string) {
FILE: packages/react-router-dev/manifest.ts
type ManifestRoute (line 1) | type ManifestRoute = {
type Manifest (line 22) | type Manifest = {
FILE: packages/react-router-dev/tsup.config.ts
method buildEnd (line 39) | async buildEnd() {
FILE: packages/react-router-dev/typegen/context.ts
type Context (line 7) | type Context = {
function createContext (line 14) | async function createContext({
FILE: packages/react-router-dev/typegen/generate.ts
type VirtualFile (line 11) | type VirtualFile = { filename: string; content: string };
function typesDirectory (line 13) | function typesDirectory(ctx: Context) {
function generateFuture (line 17) | function generateFuture(ctx: Context): VirtualFile {
function generateServerBuild (line 33) | function generateServerBuild(ctx: Context): VirtualFile {
function generateRoutes (line 59) | function generateRoutes(ctx: Context): Array<VirtualFile> {
function pagesType (line 131) | function pagesType(pages: Set<string>) {
function routeFilesType (line 153) | function routeFilesType({
function routeModulesType (line 200) | function routeModulesType(ctx: Context) {
function isInAppDirectory (line 225) | function isInAppDirectory(ctx: Context, routeFile: string): boolean {
function getRouteAnnotations (line 230) | function getRouteAnnotations({
function relativeImportSource (line 353) | function relativeImportSource(from: string, to: string) {
function rootDirsPath (line 371) | function rootDirsPath(ctx: Context, typesPath: string): string {
function paramsType (line 376) | function paramsType(path: string) {
function expand (line 390) | function expand(fullpath: string): Set<string> {
FILE: packages/react-router-dev/typegen/index.ts
function clearRouteModuleAnnotations (line 16) | async function clearRouteModuleAnnotations(ctx: Context) {
function write (line 23) | async function write(...files: Array<VirtualFile>) {
function run (line 32) | async function run(
type Watcher (line 45) | type Watcher = {
function watch (line 49) | async function watch(
FILE: packages/react-router-dev/typegen/params.ts
function parse (line 1) | function parse(fullpath: string) {
FILE: packages/react-router-dev/typegen/route.ts
function lineage (line 3) | function lineage(
function fullpath (line 17) | function fullpath(lineage: RouteManifestEntry[]) {
FILE: packages/react-router-dev/vite/build.ts
type ViteBuildOptions (line 19) | interface ViteBuildOptions {
function build (line 33) | async function build(root: string, viteBuildOptions: ViteBuildOptions) {
function viteAppBuild (line 69) | async function viteAppBuild(
function viteBuild (line 134) | async function viteBuild(
FILE: packages/react-router-dev/vite/cache.ts
type CacheEntry (line 1) | type CacheEntry<T> = { value: T; version: string };
type Cache (line 3) | type Cache = Map<string, CacheEntry<any>>;
function getOrSetFromCache (line 5) | function getOrSetFromCache<T>(
FILE: packages/react-router-dev/vite/cloudflare-dev-proxy.ts
type MaybePromise (line 17) | type MaybePromise<T> = T | Promise<T>;
type CfProperties (line 19) | type CfProperties = Record<string, unknown>;
type LoadContext (line 21) | type LoadContext<Env, Cf extends CfProperties> = {
type GetLoadContext (line 25) | type GetLoadContext<Env, Cf extends CfProperties> = (args: {
function importWrangler (line 32) | function importWrangler() {
constant PLUGIN_NAME (line 40) | const PLUGIN_NAME = "react-router-cloudflare-vite-dev-proxy";
FILE: packages/react-router-dev/vite/combine-urls.ts
function combineURLs (line 2) | function combineURLs(baseURL: string, relativeURL: string) {
FILE: packages/react-router-dev/vite/dev.ts
type ViteDevOptions (line 7) | interface ViteDevOptions {
function dev (line 21) | async function dev(
FILE: packages/react-router-dev/vite/has-dependency.ts
function hasDependency (line 1) | function hasDependency({
FILE: packages/react-router-dev/vite/has-rsc-plugin.ts
function hasReactRouterRscPlugin (line 3) | async function hasReactRouterRscPlugin({
FILE: packages/react-router-dev/vite/load-dotenv.ts
function loadDotenv (line 3) | async function loadDotenv({
FILE: packages/react-router-dev/vite/node-adapter.ts
type NodeRequestHandler (line 6) | type NodeRequestHandler = (
function fromNodeRequest (line 11) | async function fromNodeRequest(
FILE: packages/react-router-dev/vite/optimize-deps-entries.ts
function getOptimizeDepsEntries (line 6) | function getOptimizeDepsEntries({
FILE: packages/react-router-dev/vite/plugin.ts
type LoadCssContents (line 91) | type LoadCssContents = (
function resolveViteConfig (line 96) | async function resolveViteConfig({
function extractPluginContext (line 123) | function extractPluginContext(
constant SERVER_ONLY_ROUTE_EXPORTS (line 131) | const SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "middleware", "he...
constant CLIENT_NON_COMPONENT_EXPORTS (line 132) | const CLIENT_NON_COMPONENT_EXPORTS = [
constant CLIENT_ROUTE_EXPORTS (line 141) | const CLIENT_ROUTE_EXPORTS = [
constant BUILD_CLIENT_ROUTE_QUERY_STRING (line 153) | const BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-ro...
type EnvironmentName (line 155) | type EnvironmentName = "client" | SsrEnvironmentName;
constant SSR_BUNDLE_PREFIX (line 157) | const SSR_BUNDLE_PREFIX = "ssrBundle_";
type SsrBundleEnvironmentName (line 158) | type SsrBundleEnvironmentName = `${typeof SSR_BUNDLE_PREFIX}${string}`;
type SsrEnvironmentName (line 159) | type SsrEnvironmentName = "ssr" | SsrBundleEnvironmentName;
function isSsrBundleEnvironmentName (line 161) | function isSsrBundleEnvironmentName(
type EnvironmentOptions (line 167) | type EnvironmentOptions = Pick<Vite.EnvironmentOptions, "build" | "resol...
type EnvironmentOptionsResolver (line 169) | type EnvironmentOptionsResolver = (options: {
type EnvironmentOptionsResolvers (line 173) | type EnvironmentOptionsResolvers = Partial<
type EnvironmentBuildContext (line 177) | type EnvironmentBuildContext = {
function getServerEnvironmentEntries (line 182) | function getServerEnvironmentEntries<T>(
function getServerEnvironmentKeys (line 193) | function getServerEnvironmentKeys(
function getServerEnvironmentValues (line 200) | function getServerEnvironmentValues<T>(
type ServerBundleBuildConfig (line 237) | type ServerBundleBuildConfig = {
type ResolvedEnvironmentBuildContext (line 242) | type ResolvedEnvironmentBuildContext = {
type ReactRouterPluginContext (line 247) | type ReactRouterPluginContext = {
function resolveDependantChunks (line 425) | function resolveDependantChunks(
function getAllDynamicCssFiles (line 452) | function getAllDynamicCssFiles(
function dedupe (line 505) | function dedupe<T>(array: T[]): T[] {
type MaybePromise (line 674) | type MaybePromise<T> = T | Promise<T>;
type ReactRouterVitePlugin (line 690) | type ReactRouterVitePlugin = () => Vite.Plugin[];
method buildApp (line 1409) | async buildApp(builder) {
method configEnvironment (line 1450) | configEnvironment(name, options) {
method configResolved (line 1494) | async configResolved(resolvedViteConfig) {
method transform (line 1574) | async transform(code, id) {
method configureServer (line 1579) | async configureServer(viteDevServer) {
method configurePreviewServer (line 1712) | configurePreviewServer(previewServer) {
method handler (line 1809) | async handler() {
method buildEnd (line 1999) | async buildEnd() {
method transform (line 2020) | async transform(code, id, options) {
method transform (line 2082) | async transform(code, id, options) {
method transform (line 2118) | async transform(code, id, options) {
method resolveId (line 2179) | resolveId(id) {
method load (line 2183) | async load(id) {
method resolveId (line 2238) | async resolveId(id, importer, options) {
method transform (line 2305) | async transform(code, id, options) {
method transform (line 2326) | async transform(code, id, options) {
method resolveId (line 2386) | resolveId(id) {
method load (line 2391) | async load(id) {
method resolveId (line 2406) | resolveId(id) {
method load (line 2409) | async load(id) {
method transform (line 2430) | async transform(code, id, options) {
method handleHotUpdate (line 2472) | async handleHotUpdate({ server, file, modules, read }) {
method hotUpdate (line 2530) | hotUpdate(this, { server, modules }) {
method config (line 2545) | config() {
method requests (line 2553) | async requests() {
method postProcess (line 2657) | async postProcess(request, response, metadata) {
method logFile (line 2782) | logFile(outputPath, metadata) {
method finalize (line 2793) | async finalize(buildDirectory) {
function getParentClientNodes (line 2850) | function getParentClientNodes(
function addRefreshWrapper (line 2873) | function addRefreshWrapper(
constant REACT_REFRESH_HEADER (line 2889) | const REACT_REFRESH_HEADER = `
constant REACT_REFRESH_FOOTER (line 2911) | const REACT_REFRESH_FOOTER = `
function getRoute (line 2926) | function getRoute(
function isRoute (line 2940) | function isRoute(
function getRouteMetadata (line 2947) | async function getRouteMetadata(
function isPrerenderingEnabled (line 3016) | function isPrerenderingEnabled(
function isSpaModeEnabled (line 3024) | function isSpaModeEnabled(
function getPrerenderBuildAndHandler (line 3047) | async function getPrerenderBuildAndHandler(
function handleSpaMode (line 3061) | async function handleSpaMode(
function handlePrerender (line 3125) | async function handlePrerender(
function getStaticPrerenderPaths (line 3235) | function getStaticPrerenderPaths(routes: DataRouteObject[]) {
function prerenderData (line 3266) | async function prerenderData(
function prerenderRoute (line 3322) | async function prerenderRoute(
function prerenderResourceRoute (line 3383) | async function prerenderResourceRoute(
type GenericRouteManifest (line 3418) | interface GenericRouteManifest {
function getPrerenderPaths (line 3422) | async function getPrerenderPaths(
function groupRoutesByParentId (line 3474) | function groupRoutesByParentId(manifest: GenericRouteManifest) {
function createPrerenderRoutes (line 3491) | function createPrerenderRoutes(
function validateSsrFalsePrerenderExports (line 3516) | async function validateSsrFalsePrerenderExports(
function getAddressableRoutes (line 3607) | function getAddressableRoutes(routes: RouteManifest): RouteManifestEntry...
function getRouteBranch (line 3633) | function getRouteBranch(routes: RouteManifest, routeId: string) {
function getServerBundleIds (line 3647) | function getServerBundleIds(ctx: ReactRouterPluginContext) {
function getRoutesByServerBundleId (line 3653) | function getRoutesByServerBundleId(
type ResolveRouteFileCodeInput (line 3675) | type ResolveRouteFileCodeInput =
function isRootRouteModuleId (line 3696) | function isRootRouteModuleId(ctx: ReactRouterPluginContext, id: string) {
function detectRouteChunksIfEnabled (line 3703) | async function detectRouteChunksIfEnabled(
function getRouteChunkIfEnabled (line 3746) | async function getRouteChunkIfEnabled(
function validateRouteChunks (line 3766) | function validateRouteChunks({
function cleanBuildDirectory (line 3807) | async function cleanBuildDirectory(
function cleanViteManifests (line 3822) | async function cleanViteManifests(
function getBuildManifest (line 3853) | async function getBuildManifest({
function mergeEnvironmentOptions (line 3934) | function mergeEnvironmentOptions(
function getEnvironmentOptionsResolvers (line 3946) | async function getEnvironmentOptionsResolvers(
function resolveEnvironmentsOptions (line 4174) | function resolveEnvironmentsOptions(
function getEnvironmentsOptions (line 4187) | async function getEnvironmentsOptions(
function isNonNullable (line 4202) | function isNonNullable<T>(x: T): x is NonNullable<T> {
type AsyncFlatten (line 4207) | type AsyncFlatten<T extends unknown[]> = T extends (infer U)[]
function asyncFlatten (line 4211) | async function asyncFlatten<T extends unknown[]>(
type PrerenderMetadata (line 4220) | type PrerenderMetadata = {
function assertPrerenderPathsMatchRoutes (line 4226) | function assertPrerenderPathsMatchRoutes(
function getPrerenderConcurrencyConfig (line 4242) | function getPrerenderConcurrencyConfig(
function createDataRequest (line 4253) | function createDataRequest(
function createRouteRequest (line 4275) | function createRouteRequest(
function createResourceRouteRequest (line 4303) | function createResourceRouteRequest(
function createSpaModeRequest (line 4318) | function createSpaModeRequest(
FILE: packages/react-router-dev/vite/plugins/prerender.ts
type PrerenderFile (line 5) | interface PrerenderFile {
type PrerenderRequest (line 22) | type PrerenderRequest<Metadata extends Record<string, unknown>> =
type PostProcessResult (line 33) | type PostProcessResult<Metadata extends Record<string, unknown>> =
type PrerenderConfig (line 40) | interface PrerenderConfig {
type PrerenderPluginOptions (line 79) | interface PrerenderPluginOptions<
function normalizePrerenderRequest (line 187) | function normalizePrerenderRequest<Metadata extends Record<string, unkno...
function normalizePostProcessResult (line 200) | function normalizePostProcessResult<Metadata extends Record<string, unkn...
function prerender (line 216) | function prerender<Metadata extends Record<string, unknown>>(
function defaultPostProcess (line 427) | async function defaultPostProcess(
function defaultHandleError (line 447) | function defaultHandleError(request: Request, error: Error): void {
function startPreviewServer (line 461) | async function startPreviewServer(
function getResolvedUrl (line 482) | function getResolvedUrl(previewServer: Vite.PreviewServer): URL {
FILE: packages/react-router-dev/vite/plugins/validate-plugin-order.ts
function validatePluginOrder (line 3) | function validatePluginOrder(): Vite.Plugin {
FILE: packages/react-router-dev/vite/plugins/warn-on-client-source-maps.ts
function warnOnClientSourceMaps (line 5) | function warnOnClientSourceMaps(): Vite.Plugin {
FILE: packages/react-router-dev/vite/remove-exports-test.ts
function transform (line 4) | function transform(code: string, exportsToRemove: string[]) {
FILE: packages/react-router-dev/vite/remove-exports.ts
method ExportDeclaration (line 21) | ExportDeclaration(path) {
method ExpressionStatement (line 131) | ExpressionStatement(path) {
function validateDestructuredExports (line 161) | function validateDestructuredExports(
function invalidDestructureError (line 236) | function invalidDestructureError(name: string) {
FILE: packages/react-router-dev/vite/resolve-relative-route-file-path.ts
function resolveRelativeRouteFilePath (line 6) | function resolveRelativeRouteFilePath(
FILE: packages/react-router-dev/vite/route-chunks.ts
type ExportDeclaration (line 13) | type ExportDeclaration = Babel.ExportDeclaration;
type Identifier (line 14) | type Identifier = Babel.Identifier;
type Pattern (line 15) | type Pattern = Babel.Pattern;
type Statement (line 16) | type Statement = Babel.Statement;
type VariableDeclarator (line 17) | type VariableDeclarator = Babel.VariableDeclarator;
type ExportDependencies (line 19) | type ExportDependencies = Map<string, Dependencies>;
type Dependencies (line 21) | type Dependencies = {
function codeToAst (line 28) | function codeToAst(code: string, cache: Cache, cacheKey: string): Babel....
function assertNodePath (line 37) | function assertNodePath(
function assertNodePathIsStatement (line 50) | function assertNodePathIsStatement(
function assertNodePathIsVariableDeclarator (line 61) | function assertNodePathIsVariableDeclarator(
function assertNodePathIsPattern (line 72) | function assertNodePathIsPattern(
function getExportDependencies (line 83) | function getExportDependencies(
function getDependentIdentifiersForPath (line 281) | function getDependentIdentifiersForPath(
function getTopLevelStatementPathForPath (line 376) | function getTopLevelStatementPathForPath(path: NodePath): NodePath<State...
function getTopLevelStatementsForPaths (line 386) | function getTopLevelStatementsForPaths(paths: Set<NodePath>): Set<Statem...
function getIdentifiersForPatternPath (line 397) | function getIdentifiersForPatternPath(
function setsIntersect (line 446) | function setsIntersect(set1: Set<any>, set2: Set<any>): boolean {
function hasChunkableExport (line 464) | function hasChunkableExport(
function getChunkedExport (line 548) | function getChunkedExport(
function omitChunkedExports (line 701) | function omitChunkedExports(
function detectRouteChunks (line 909) | function detectRouteChunks(
type RouteChunkExportName (line 944) | type RouteChunkExportName = (typeof routeChunkExportNames)[number];
type RouteChunkName (line 948) | type RouteChunkName = (typeof routeChunkNames)[number];
function getRouteChunkCode (line 950) | function getRouteChunkCode(
type RouteChunkQueryString (line 964) | type RouteChunkQueryString =
function getRouteChunkModuleId (line 975) | function getRouteChunkModuleId(
function isRouteChunkModuleId (line 982) | function isRouteChunkModuleId(id: string): boolean {
function isRouteChunkName (line 988) | function isRouteChunkName(name: string): name is RouteChunkName {
function getRouteChunkNameFromModuleId (line 992) | function getRouteChunkNameFromModuleId(
FILE: packages/react-router-dev/vite/rsc/plugin.ts
function reactRouterRSCVitePlugin (line 32) | function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
function invalidateVirtualModules (line 617) | function invalidateVirtualModules(viteDevServer: Vite.ViteDevServer) {
function getRootDirectory (line 628) | function getRootDirectory(viteUserConfig: Vite.UserConfig) {
function getModulesWithImporters (line 632) | function getModulesWithImporters(
function addRefreshWrapper (line 656) | function addRefreshWrapper({
constant REACT_REFRESH_HEADER (line 676) | const REACT_REFRESH_HEADER = `
constant REACT_REFRESH_FOOTER (line 698) | const REACT_REFRESH_FOOTER = `
FILE: packages/react-router-dev/vite/rsc/virtual-route-config.ts
function createVirtualRouteConfig (line 4) | function createVirtualRouteConfig({
function createRouteId (line 58) | function createRouteId(file: string, appDirectory: string) {
FILE: packages/react-router-dev/vite/rsc/virtual-route-modules.ts
constant SERVER_ONLY_COMPONENT_EXPORTS (line 6) | const SERVER_ONLY_COMPONENT_EXPORTS = ["ServerComponent"] as const;
constant SERVER_ONLY_ROUTE_EXPORTS (line 8) | const SERVER_ONLY_ROUTE_EXPORTS = [
type ServerOnlyRouteExport (line 15) | type ServerOnlyRouteExport = (typeof SERVER_ONLY_ROUTE_EXPORTS)[number];
constant SERVER_ONLY_ROUTE_EXPORTS_SET (line 16) | const SERVER_ONLY_ROUTE_EXPORTS_SET = new Set(SERVER_ONLY_ROUTE_EXPORTS);
function isServerOnlyRouteExport (line 17) | function isServerOnlyRouteExport(name: string): name is ServerOnlyRouteE...
constant COMMON_COMPONENT_EXPORTS (line 21) | const COMMON_COMPONENT_EXPORTS = [
constant SERVER_FIRST_COMPONENT_EXPORTS (line 27) | const SERVER_FIRST_COMPONENT_EXPORTS = [
type ServerFirstComponentExport (line 31) | type ServerFirstComponentExport =
constant SERVER_FIRST_COMPONENT_EXPORTS_SET (line 33) | const SERVER_FIRST_COMPONENT_EXPORTS_SET = new Set(
function isServerFirstComponentExport (line 36) | function isServerFirstComponentExport(
constant CLIENT_COMPONENT_EXPORTS (line 44) | const CLIENT_COMPONENT_EXPORTS = [
constant CLIENT_NON_COMPONENT_EXPORTS (line 49) | const CLIENT_NON_COMPONENT_EXPORTS = [
type ClientNonComponentExport (line 58) | type ClientNonComponentExport = (typeof CLIENT_NON_COMPONENT_EXPORTS)[nu...
constant CLIENT_NON_COMPONENT_EXPORTS_SET (line 59) | const CLIENT_NON_COMPONENT_EXPORTS_SET = new Set(CLIENT_NON_COMPONENT_EX...
function isClientNonComponentExport (line 60) | function isClientNonComponentExport(
constant CLIENT_ROUTE_EXPORTS (line 66) | const CLIENT_ROUTE_EXPORTS = [
type ClientRouteExport (line 70) | type ClientRouteExport = (typeof CLIENT_ROUTE_EXPORTS)[number];
constant CLIENT_ROUTE_EXPORTS_SET (line 71) | const CLIENT_ROUTE_EXPORTS_SET = new Set(CLIENT_ROUTE_EXPORTS);
function isClientRouteExport (line 72) | function isClientRouteExport(name: string): name is ClientRouteExport {
constant ROUTE_EXPORTS (line 76) | const ROUTE_EXPORTS = [
type RouteExport (line 80) | type RouteExport = (typeof ROUTE_EXPORTS)[number];
constant ROUTE_EXPORTS_SET (line 81) | const ROUTE_EXPORTS_SET = new Set(ROUTE_EXPORTS);
function isRouteExport (line 82) | function isRouteExport(name: string): name is RouteExport {
function isCustomRouteExport (line 85) | function isCustomRouteExport(name: string) {
function hasReactServerCondition (line 89) | function hasReactServerCondition(viteEnvironment: Vite.Environment) {
type ViteCommand (line 93) | type ViteCommand = Vite.ConfigEnv["command"];
function transformVirtualRouteModules (line 95) | function transformVirtualRouteModules({
function createVirtualRouteModuleCode (line 138) | async function createVirtualRouteModuleCode({
function createVirtualServerRouteModuleCode (line 210) | function createVirtualServerRouteModuleCode({
function createVirtualClientRouteModuleCode (line 253) | function createVirtualClientRouteModuleCode({
function parseRouteExports (line 297) | function parseRouteExports(code: string) {
function getVirtualClientModuleId (line 312) | function getVirtualClientModuleId(id: string): string {
function getVirtualServerModuleId (line 316) | function getVirtualServerModuleId(id: string): string {
function isVirtualRouteModuleId (line 320) | function isVirtualRouteModuleId(id: string): boolean {
function isVirtualClientRouteModuleId (line 324) | function isVirtualClientRouteModuleId(id: string): boolean {
function isVirtualServerRouteModuleId (line 328) | function isVirtualServerRouteModuleId(id: string): boolean {
function isRootRouteFile (line 332) | function isRootRouteFile({
FILE: packages/react-router-dev/vite/static/refresh-utils.mjs
function debounce (line 4) | function debounce(fn, delay) {
function registerExportsForReactRefresh (line 84) | function registerExportsForReactRefresh(filename, moduleExports) {
function validateRefreshBoundaryAndEnqueueUpdate (line 98) | function validateRefreshBoundaryAndEnqueueUpdate(
function predicateOnExport (line 141) | function predicateOnExport(moduleExports, predicate) {
function __hmr_import (line 153) | function __hmr_import(module) {
FILE: packages/react-router-dev/vite/static/rsc-refresh-utils.mjs
function debounce (line 4) | function debounce(fn, delay) {
function registerExportsForReactRefresh (line 39) | function registerExportsForReactRefresh(filename, moduleExports) {
function validateRefreshBoundaryAndEnqueueUpdate (line 53) | function validateRefreshBoundaryAndEnqueueUpdate(
function predicateOnExport (line 96) | function predicateOnExport(moduleExports, predicate) {
function __hmr_import (line 108) | function __hmr_import(module) {
FILE: packages/react-router-dev/vite/styles.ts
function addFromNode (line 136) | async function addFromNode(node: ModuleNode) {
function addFromUrl (line 143) | async function addFromUrl(url: string) {
type RouteManifestEntryWithChildren (line 180) | type RouteManifestEntryWithChildren = Omit<RouteManifestEntry, "index"> &
method VariableDeclaration (line 260) | VariableDeclaration(path) {
FILE: packages/react-router-dev/vite/virtual-module.ts
function create (line 1) | function create(name: string) {
FILE: packages/react-router-dev/vite/vite-node.ts
type Context (line 10) | type Context = {
function createContext (line 16) | async function createContext({
FILE: packages/react-router-dev/vite/vite.ts
type Vite (line 7) | type Vite = typeof import("vite");
function preloadVite (line 22) | async function preloadVite(): Promise<void> {
function getVite (line 28) | function getVite(): Vite {
FILE: packages/react-router-dev/vite/with-props.ts
type NamedComponentExport (line 5) | type NamedComponentExport = (typeof namedComponentExports)[number];
function isNamedComponentExport (line 6) | function isNamedComponentExport(name: string): name is NamedComponentExp...
type HocName (line 10) | type HocName =
function getHocUid (line 19) | function getHocUid(path: NodePath, hocName: HocName) {
method ExportDeclaration (line 26) | ExportDeclaration(path) {
function toFunctionExpression (line 91) | function toFunctionExpression(decl: Babel.FunctionDeclaration) {
FILE: packages/react-router-express/__tests__/server-test.ts
function createApp (line 28) | function createApp() {
FILE: packages/react-router-express/server.ts
type MaybePromise (line 18) | type MaybePromise<T> = T | Promise<T>;
type GetLoadContextFunction (line 28) | type GetLoadContextFunction = (
type RequestHandler (line 35) | type RequestHandler = (
function createRequestHandler (line 44) | function createRequestHandler({
function createRemixHeaders (line 75) | function createRemixHeaders(
function createRemixRequest (line 95) | function createRemixRequest(
function sendRemixResponse (line 138) | async function sendRemixResponse(
FILE: packages/react-router-fs-routes/__tests__/flatRoutes-test.ts
constant APP_DIR (line 16) | let APP_DIR = path.join("test", "root", "app");
FILE: packages/react-router-fs-routes/flatRoutes.ts
type PrefixLookupNode (line 18) | type PrefixLookupNode = {
class PrefixLookupTrie (line 22) | class PrefixLookupTrie {
method add (line 27) | add(value: string) {
method findAndRemove (line 42) | findAndRemove(
method #findAndRemoveRecursive (line 55) | #findAndRemoveRecursive(
function flatRoutes (line 74) | function flatRoutes(
function flatRoutesUniversal (line 127) | function flatRoutesUniversal(
function findRouteModuleForFile (line 300) | function findRouteModuleForFile(
function findRouteModuleForFolder (line 311) | function findRouteModuleForFolder(
type State (line 341) | type State =
function getRouteSegments (line 351) | function getRouteSegments(routeId: string): [string[], string[]] {
function createRoutePath (line 482) | function createRoutePath(
function getRoutePathConflictErrorMessage (line 513) | function getRoutePathConflictErrorMessage(
function getRouteIdConflictErrorMessage (line 532) | function getRouteIdConflictErrorMessage(
function isSegmentSeparator (line 547) | function isSegmentSeparator(checkChar: string | undefined) {
function findFile (line 552) | function findFile(
FILE: packages/react-router-fs-routes/index.ts
function flatRoutes (line 18) | async function flatRoutes(
FILE: packages/react-router-fs-routes/manifest.ts
type RouteManifestEntry (line 3) | interface RouteManifestEntry {
type RouteManifest (line 12) | interface RouteManifest {
function routeManifestToRouteConfig (line 16) | function routeManifestToRouteConfig(
FILE: packages/react-router-fs-routes/normalizeSlashes.ts
function normalizeSlashes (line 3) | function normalizeSlashes(file: string) {
FILE: packages/react-router-node/__tests__/sessions-test.ts
function getCookieFromSetCookie (line 11) | function getCookieFromSetCookie(setCookie: string): string {
FILE: packages/react-router-node/server.ts
type MaybePromise (line 13) | type MaybePromise<T> = T | Promise<T>;
type RequestListenerOptions (line 15) | interface RequestListenerOptions {
function createRequestListener (line 32) | function createRequestListener(
FILE: packages/react-router-node/sessions/fileStorage.ts
type FileSessionStorageOptions (line 10) | interface FileSessionStorageOptions {
function createFileSessionStorage (line 31) | function createFileSessionStorage<Data = SessionData, FlashData = Data>({
function getFile (line 115) | function getFile(dir: string, id: string): string | null {
FILE: packages/react-router-node/stream.ts
function writeReadableStreamToWritable (line 4) | async function writeReadableStreamToWritable(
function writeAsyncIterableToWritable (line 31) | async function writeAsyncIterableToWritable(
function readableStreamToString (line 46) | async function readableStreamToString(
class StreamPump (line 74) | class StreamPump {
method constructor (line 86) | constructor(
method size (line 105) | size(chunk: Uint8Array) {
method start (line 109) | start(controller: ReadableStreamController<Uint8Array>) {
method pull (line 117) | pull() {
method cancel (line 121) | cancel(reason?: Error) {
method enqueue (line 132) | enqueue(chunk: Uint8Array | string) {
method pause (line 153) | pause() {
method resume (line 159) | resume() {
method close (line 165) | close() {
method error (line 172) | error(error: Error) {
FILE: packages/react-router-remix-routes-option-adapter/defineRoutes.ts
type DefineRoutesFunction (line 4) | type DefineRoutesFunction = (
type DefineRouteOptions (line 8) | interface DefineRouteOptions {
type DefineRouteChildren (line 27) | interface DefineRouteChildren {
type DefineRouteFunction (line 31) | interface DefineRouteFunction {
function createRouteId (line 124) | function createRouteId(file: string) {
function stripFileExtension (line 128) | function stripFileExtension(file: string) {
FILE: packages/react-router-remix-routes-option-adapter/index.ts
function remixRoutesOptionAdapter (line 17) | async function remixRoutesOptionAdapter(
FILE: packages/react-router-remix-routes-option-adapter/manifest.ts
type RouteManifestEntry (line 3) | interface RouteManifestEntry {
type RouteManifest (line 12) | interface RouteManifest {
function routeManifestToRouteConfig (line 16) | function routeManifestToRouteConfig(
FILE: packages/react-router-remix-routes-option-adapter/normalizeSlashes.ts
function normalizeSlashes (line 3) | function normalizeSlashes(file: string) {
FILE: packages/react-router-serve/cli.ts
type RSCServerBuildModule (line 36) | type RSCServerBuildModule = {
type NormalizedBuild (line 46) | type NormalizedBuild = {
function isRSCServerBuild (line 52) | function isRSCServerBuild(build: unknown): build is RSCServerBuildModule {
function parseNumber (line 64) | function parseNumber(raw?: string) {
function run (line 71) | async function run() {
FILE: packages/react-router/__tests__/Router-test.tsx
function CaptureLocation1 (line 31) | function CaptureLocation1() {
function CaptureLocation2 (line 48) | function CaptureLocation2() {
FILE: packages/react-router/__tests__/Routes-location-test.tsx
function Home (line 6) | function Home() {
function User (line 10) | function User() {
FILE: packages/react-router/__tests__/absolute-path-matching-test.tsx
function pickPaths (line 4) | function pickPaths(routes: RouteObject[], pathname: string): string[] | ...
FILE: packages/react-router/__tests__/data-memory-router-test.tsx
function Root (line 165) | function Root() {
function Root (line 217) | function Root() {
function Parent (line 226) | function Parent() {
function Comp (line 286) | function Comp() {
function FallbackElement (line 334) | function FallbackElement() {
function Foo (line 338) | function Foo() {
function Bar (line 343) | function Bar() {
function Foo (line 382) | function Foo() {
function Bar (line 387) | function Bar() {
function FallbackElement (line 425) | function FallbackElement() {
function Foo (line 429) | function Foo() {
function Bar (line 434) | function Bar() {
function FallbackElement (line 463) | function FallbackElement() {
function Foo (line 472) | function Foo() {
function Layout (line 510) | function Layout() {
function Foo (line 520) | function Foo() {
function Bar (line 524) | function Bar() {
function Layout (line 549) | function Layout() {
function Foo (line 560) | function Foo() {
function Bar (line 563) | function Bar() {
function Layout (line 648) | function Layout() {
function Foo (line 661) | function Foo() {
function Bar (line 664) | function Bar() {
function Layout (line 768) | function Layout() {
function Foo (line 778) | function Foo() {
function Bar (line 783) | function Bar() {
function Layout (line 867) | function Layout() {
function GrandChild (line 938) | function GrandChild() {
function Child (line 951) | function Child() {
method Component (line 973) | Component() {
method ErrorBoundary (line 988) | ErrorBoundary() {
method Component (line 1023) | Component() {
method loader (line 1043) | async loader() {
method loader (line 1076) | async loader() {
method Component (line 1082) | Component() {
method Component (line 1131) | Component() {
method loader (line 1151) | async loader() {
method loader (line 1184) | async loader() {
method Component (line 1190) | Component() {
method loader (line 1233) | async loader() {
method Component (line 1239) | Component() {
method action (line 1283) | async action() {
method loader (line 1289) | async loader() {
method Component (line 1295) | Component() {
function Comp (line 1365) | function Comp() {
function ErrorBoundary (line 1379) | function ErrorBoundary() {
function Comp (line 1426) | function Comp() {
function Comp (line 1474) | function Comp() {
function ErrorBoundary (line 1488) | function ErrorBoundary() {
function Layout (line 1536) | function Layout() {
function Foo (line 1548) | function Foo() {
function FooError (line 1552) | function FooError() {
function Bar (line 1556) | function Bar() {
function BarError (line 1560) | function BarError() {
function Layout (line 1678) | function Layout() {
function Foo (line 1690) | function Foo() {
function FooError (line 1694) | function FooError() {
function Bar (line 1698) | function Bar() {
function BarError (line 1702) | function BarError() {
function Layout (line 1819) | function Layout() {
function LayoutError (line 1830) | function LayoutError() {
function Foo (line 1834) | function Foo() {
function FooError (line 1838) | function FooError() {
function Bar (line 1842) | function Bar() {
function Boundary (line 1918) | function Boundary() {
function Boundary (line 1974) | function Boundary() {
function Layout (line 2064) | function Layout() {
function Foo (line 2075) | function Foo() {
function Bar (line 2079) | function Bar() {
function Layout (line 2146) | function Layout() {
function Bar (line 2156) | function Bar() {
function BarError (line 2160) | function BarError() {
function ChildComp (line 2226) | function ChildComp(): React.ReactElement {
function ErrorBoundary (line 2230) | function ErrorBoundary() {
function ChildComp (line 2268) | function ChildComp(): React.ReactElement {
function ErrorBoundary (line 2272) | function ErrorBoundary() {
function ChildComp (line 2310) | function ChildComp(): React.ReactElement {
function ChildComp (line 2344) | function ChildComp(): React.ReactElement {
method Component (line 2353) | Component() {
method ErrorBoundary (line 2357) | ErrorBoundary() {
method loader (line 2372) | loader() {
method Component (line 2377) | Component() {
method ErrorBoundary (line 2385) | ErrorBoundary() {
function Parent (line 2419) | function Parent() {
function Child (line 2427) | function Child(): React.ReactElement {
function ErrorBoundary (line 2431) | function ErrorBoundary() {
function Parent (line 2490) | function Parent() {
function Child (line 2499) | function Child(): React.ReactElement {
function setupDeferredTest (line 2540) | function setupDeferredTest({
function Bar (line 3191) | function Bar() {
function ErrorElement (line 3299) | function ErrorElement() {
function Layout (line 3357) | function Layout() {
function Foo (line 3368) | function Foo() {
function Bar (line 3371) | function Bar() {
FILE: packages/react-router/__tests__/data-router-no-dom-test.tsx
method loader (line 222) | loader() {
method action (line 285) | async action({ request }) {
FILE: packages/react-router/__tests__/descendant-routes-params-test.tsx
function ShowParams (line 7) | function ShowParams() {
function ShowParams (line 38) | function ShowParams() {
FILE: packages/react-router/__tests__/descendant-routes-splat-matching-test.tsx
function ReactCourses (line 9) | function ReactCourses() {
function Courses (line 23) | function Courses() {
function PrintParams (line 62) | function PrintParams() {
function ReactCourses (line 65) | function ReactCourses() {
function Courses (line 84) | function Courses() {
function renderNestedSplatRoute (line 93) | function renderNestedSplatRoute(initialEntries: InitialEntry[]) {
FILE: packages/react-router/__tests__/descendant-routes-warning-test.tsx
function ReactCourses (line 17) | function ReactCourses() {
function Courses (line 33) | function Courses() {
function ReactCourses (line 65) | function ReactCourses() {
function ReactCourses (line 101) | function ReactCourses() {
function Courses (line 116) | function Courses() {
FILE: packages/react-router/__tests__/dom/client-on-error-test.tsx
method lazy (line 38) | async lazy() {
method loader (line 96) | async loader() {
method lazy (line 130) | async lazy() {
method loader (line 197) | loader() {
method action (line 229) | action() {
method loader (line 266) | loader() {
method action (line 296) | action() {
method loader (line 365) | loader() {
method Component (line 372) | Component() {
method loader (line 408) | loader() {
method Component (line 413) | Component() {
function RenderAwait (line 426) | function RenderAwait() {
method loader (line 460) | loader() {
method Component (line 467) | Component() {
function RenderError (line 481) | function RenderError() {
method loader (line 520) | loader() {
method ErrorBoundary (line 524) | ErrorBoundary() {
method loader (line 537) | loader() {
method ErrorBoundary (line 575) | ErrorBoundary() {
method loader (line 588) | loader() {
FILE: packages/react-router/__tests__/dom/components/LazyComponent.tsx
function LazyComponent (line 3) | function LazyComponent() {
FILE: packages/react-router/__tests__/dom/concurrent-mode-navigations-test.tsx
function getComponents (line 25) | function getComponents() {
function assertNavigation (line 74) | async function assertNavigation(
function assertNavigation (line 245) | async function assertNavigation(
FILE: packages/react-router/__tests__/dom/data-browser-router-legacy-formdata-test.tsx
function testDomRouter (line 26) | function testDomRouter(
FILE: packages/react-router/__tests__/dom/data-browser-router-test.tsx
function testDomRouter (line 53) | function testDomRouter(
FILE: packages/react-router/__tests__/dom/data-static-router-test.tsx
function HooksChecker1 (line 38) | function HooksChecker1() {
function HooksChecker2 (line 47) | function HooksChecker2() {
function HooksChecker1 (line 193) | function HooksChecker1() {
function HooksChecker2 (line 202) | function HooksChecker2() {
function GetLocation (line 343) | function GetLocation() {
FILE: packages/react-router/__tests__/dom/dom-export-test.tsx
function ShowParams (line 8) | function ShowParams() {
FILE: packages/react-router/__tests__/dom/fetcher-submit-tagname-test.tsx
method Component (line 17) | Component() {
method Component (line 57) | Component() {
FILE: packages/react-router/__tests__/dom/flush-sync-navigations-test.tsx
method Component (line 19) | Component() {
method Component (line 31) | Component() {
method Component (line 82) | Component() {
method Component (line 101) | Component() {
method Component (line 150) | Component() {
method Component (line 211) | Component() {
FILE: packages/react-router/__tests__/dom/link-click-test.tsx
function click (line 6) | function click(anchor: HTMLAnchorElement, eventInit?: MouseEventInit) {
function Home (line 30) | function Home() {
function Home (line 65) | function Home() {
function Home (line 101) | function Home() {
function Home (line 136) | function Home() {
function Home (line 175) | function Home() {
function Home (line 209) | function Home() {
function Home (line 247) | function Home() {
function Home (line 284) | function Home() {
function Home (line 324) | function Home() {
function Home (line 365) | function Home() {
function Home (line 402) | function Home() {
function Home (line 439) | function Home() {
FILE: packages/react-router/__tests__/dom/link-href-test.tsx
function MessagesLayout (line 400) | function MessagesLayout({ link }: { link: React.ReactElement }) {
FILE: packages/react-router/__tests__/dom/link-push-test.tsx
function ShowNavigationType (line 11) | function ShowNavigationType() {
function Home (line 18) | function Home() {
function Home (line 61) | function Home() {
function Home (line 117) | function Home() {
function Home (line 173) | function Home() {
function About (line 183) | function About() {
function Home (line 234) | function Home() {
function About (line 246) | function About() {
function Home (line 297) | function Home() {
FILE: packages/react-router/__tests__/dom/nav-link-active-test.tsx
function Layout (line 679) | function Layout() {
function Layout (line 718) | function Layout() {
function Layout (line 773) | function Layout() {
function Layout (line 828) | function Layout() {
function Layout (line 877) | function Layout() {
function Layout (line 923) | function Layout() {
function Layout (line 976) | function Layout() {
function createDeferred (line 1040) | function createDeferred() {
FILE: packages/react-router/__tests__/dom/navigate-encode-params-test.tsx
function Start (line 27) | function Start() {
function Blog (line 37) | function Blog() {
function Start (line 60) | function Start() {
function Blog (line 70) | function Blog() {
FILE: packages/react-router/__tests__/dom/partial-hydration-test.tsx
method Component (line 41) | Component() {
method Component (line 55) | Component() {
method patchRoutesOnNavigation (line 72) | patchRoutesOnNavigation({ path, patch }) {
method Component (line 131) | Component() {
method Component (line 144) | Component() {
method patchRoutesOnNavigation (line 161) | patchRoutesOnNavigation({ path, patch }) {
method Component (line 218) | Component() {
method Component (line 231) | Component() {
method Component (line 243) | Component() {
method patchRoutesOnNavigation (line 254) | async patchRoutesOnNavigation({ path, patch }) {
function testPartialHydration (line 315) | function testPartialHydration(
FILE: packages/react-router/__tests__/dom/polyfills/drop-FormData-submitter.ts
method constructor (line 5) | constructor(form?: HTMLFormElement) {
FILE: packages/react-router/__tests__/dom/scroll-restoration-test.tsx
method Component (line 33) | Component() {
method Component (line 86) | Component() {
method Component (line 97) | Component() {
method Component (line 103) | Component() {
method Component (line 146) | Component() {
method Component (line 328) | Component() {
method Component (line 339) | Component() {
FILE: packages/react-router/__tests__/dom/search-params-test.tsx
function SearchPage (line 28) | function SearchPage() {
function SearchPage (line 79) | function SearchPage() {
function SearchPage (line 139) | function SearchPage() {
function SearchPage (line 175) | function SearchPage() {
method Component (line 199) | Component() {
FILE: packages/react-router/__tests__/dom/special-characters-test.tsx
function CaptureLocation (line 130) | function CaptureLocation() {
function testParamValues (line 157) | async function testParamValues(
function App (line 566) | function App() {
function Parent (line 574) | function Parent() {
function Child (line 582) | function Child() {
function Grandchild (line 597) | function Grandchild() {
function App (line 645) | function App() {
function Parent (line 653) | function Parent() {
function Child (line 661) | function Child() {
function Grandchild (line 676) | function Grandchild() {
function App (line 724) | function App() {
function Parent (line 732) | function Parent() {
function Child (line 740) | function Child() {
function Grandchild (line 755) | function Grandchild() {
function assertRouteMatch (line 767) | async function assertRouteMatch(
function ShowPath (line 966) | function ShowPath() {
function Start (line 987) | function Start() {
function Start (line 1021) | function Start() {
function Start (line 1061) | function Start() {
function Start (line 1102) | function Start() {
method Component (line 1132) | Component() {
function Start (line 1193) | function Start() {
function Start (line 1236) | function Start() {
FILE: packages/react-router/__tests__/dom/ssr/components-test.tsx
type PrefetchEventHandlerProps (line 29) | type PrefetchEventHandlerProps = {
function itPrefetchesPageLinks (line 33) | function itPrefetchesPageLinks<
method start (line 273) | start(controller) {
function TestComponent (line 394) | function TestComponent({
method constructor (line 427) | constructor(cb: IntersectionObserverCallback) {
FILE: packages/react-router/__tests__/dom/ssr/links-test.tsx
method Component (line 14) | Component() {
method Component (line 43) | Component() {
method Component (line 78) | Component() {
method Component (line 115) | Component() {
method Component (line 150) | Component() {
FILE: packages/react-router/__tests__/dom/ssr/meta-test.tsx
method Component (line 20) | Component() {
method Component (line 31) | Component() {
method Component (line 79) | Component() {
method Component (line 112) | Component() {
method meta (line 123) | meta({ matches }) {
method Component (line 129) | Component() {
method Component (line 328) | Component() {
method Component (line 389) | Component() {
method Component (line 406) | Component() {
method ErrorBoundary (line 409) | ErrorBoundary() {
FILE: packages/react-router/__tests__/dom/static-location-test.tsx
function LocationChecker (line 9) | function LocationChecker() {
function LocationChecker (line 35) | function LocationChecker() {
function LocationChecker (line 61) | function LocationChecker() {
FILE: packages/react-router/__tests__/dom/stub-test.tsx
method Component (line 37) | Component() {
method Component (line 70) | Component() {
method Component (line 76) | Component() {
method Component (line 95) | Component() {
method loader (line 100) | loader({ context }) {
method Component (line 117) | Component() {
method loader (line 121) | loader() {
method Component (line 138) | Component({ loaderData }) {
method loader (line 142) | loader() {
method Component (line 158) | Component() {
method action (line 167) | action() {
method Component (line 184) | Component({ actionData }) {
method action (line 193) | action() {
method Component (line 211) | Component() {
method ErrorBoundary (line 214) | ErrorBoundary() {
method Component (line 233) | Component() {
method ErrorBoundary (line 236) | ErrorBoundary({ error }) {
method Component (line 254) | Component() {
method loader (line 265) | loader() {
function loader (line 282) | async function loader(_args: LoaderFunctionArgs) {
method Component (line 300) | Component() {
method loader (line 309) | loader({ context }) {
method Component (line 315) | Component() {
method loader (line 319) | loader({ context }) {
method Component (line 344) | Component() {
method loader (line 353) | loader({ context }) {
method Component (line 359) | Component() {
method loader (line 363) | loader({ context }) {
method Component (line 386) | Component() {
method Component (line 397) | Component() {
FILE: packages/react-router/__tests__/dom/trailing-slashes-test.tsx
function SetSearchParams (line 604) | function SetSearchParams() {
function SetSearchParams (line 632) | function SetSearchParams() {
function SingleNavigate (line 656) | function SingleNavigate({ to }: { to: To }) {
FILE: packages/react-router/__tests__/dom/use-blocker-test.tsx
type Router (line 15) | type Router = ReturnType<typeof createMemoryRouter>;
constant LOADER_LATENCY_MS (line 17) | const LOADER_LATENCY_MS = 200;
function slowLoader (line 19) | async function slowLoader() {
method Component (line 72) | Component() {
method Component (line 163) | Component() {
function sleep (line 1165) | function sleep(n: number = 500) {
function click (line 1169) | function click(target: EventTarget | null | undefined) {
FILE: packages/react-router/__tests__/dom/use-prompt-test.tsx
method Component (line 28) | Component() {
method Component (line 61) | Component() {
method Component (line 96) | Component() {
FILE: packages/react-router/__tests__/dom/useLinkClickHandler-test.tsx
function CustomLink (line 13) | function CustomLink({ to, replace, state, target, ...rest }: LinkProps) {
FILE: packages/react-router/__tests__/gh-issue-8165-test.tsx
function App (line 49) | function App() {
FILE: packages/react-router/__tests__/matchRoutes-test.tsx
function pickPaths (line 5) | function pickPaths(
FILE: packages/react-router/__tests__/navigate-test.tsx
function Contacts (line 425) | function Contacts() {
method loader (line 541) | async loader() {
method Component (line 580) | Component() {
method Component (line 590) | Component() {
method Component (line 645) | Component() {
method Component (line 657) | Component() {
method Component (line 716) | Component() {
method loader (line 726) | async loader() {
method Component (line 730) | Component() {
method Component (line 786) | Component() {
method loader (line 801) | async loader() {
method Component (line 805) | Component() {
FILE: packages/react-router/__tests__/params-decode-test.tsx
function Content (line 7) | function Content() {
FILE: packages/react-router/__tests__/path-matching-test.tsx
function pickPaths (line 4) | function pickPaths(routes: RouteObject[], pathname: string): string[] | ...
function pickPathsAndParams (line 9) | function pickPathsAndParams(routes: RouteObject[], pathname: string) {
FILE: packages/react-router/__tests__/react-transitions-test.tsx
method Component (line 38) | Component() {
method Component (line 54) | Component() {
method Component (line 66) | Component() {
method Component (line 103) | Component() {
method Component (line 119) | Component() {
method Component (line 137) | Component() {
method Component (line 177) | Component() {
method Component (line 198) | Component() {
method Component (line 216) | Component() {
method Component (line 254) | Component() {
method Component (line 275) | Component() {
method Component (line 296) | Component() {
method Component (line 342) | Component() {
method Component (line 363) | Component() {
method Component (line 375) | Component() {
method Component (line 414) | Component() {
method Component (line 435) | Component() {
method Component (line 453) | Component() {
method Component (line 496) | Component() {
method Component (line 517) | Component() {
method Component (line 529) | Component() {
method Component (line 568) | Component() {
method Component (line 589) | Component() {
method Component (line 601) | Component() {
method Component (line 640) | Component() {
method Component (line 661) | Component() {
method Component (line 678) | Component() {
method Component (line 719) | Component() {
method Component (line 740) | Component() {
method Component (line 754) | Component() {
method Component (line 798) | Component() {
method Component (line 819) | Component() {
method Component (line 837) | Component() {
method Component (line 881) | Component() {
method Component (line 902) | Component() {
method Component (line 924) | Component() {
method Component (line 973) | Component() {
method Component (line 1030) | Component() {
method Component (line 1089) | Component() {
method Component (line 1154) | Component() {
method Component (line 1170) | Component() {
method Component (line 1181) | Component() {
method Component (line 1229) | Component() {
method Component (line 1300) | Component() {
FILE: packages/react-router/__tests__/route-depth-order-matching-test.tsx
function First (line 35) | function First() {
function Second (line 43) | function Second() {
function Third (line 51) | function Third() {
function First (line 86) | function First() {
function Second (line 94) | function Second() {
function Third (line 102) | function Third() {
function First (line 128) | function First() {
function Second (line 132) | function Second() {
FILE: packages/react-router/__tests__/route-matching-test.tsx
function describeRouteMatching (line 14) | function describeRouteMatching(routes: React.ReactNode) {
function RoutesRenderer (line 70) | function RoutesRenderer({ routes }: { routes: RouteObject[] }) {
function Courses (line 101) | function Courses() {
function Course (line 110) | function Course() {
function CourseGrades (line 120) | function CourseGrades() {
function NewCourse (line 124) | function NewCourse() {
function CoursesIndex (line 128) | function CoursesIndex() {
function CoursesNotFound (line 132) | function CoursesNotFound() {
function Landing (line 136) | function Landing() {
function ReactFundamentals (line 145) | function ReactFundamentals() {
function AdvancedReact (line 149) | function AdvancedReact() {
function Home (line 153) | function Home() {
function NotFound (line 157) | function NotFound() {
function NeverRender (line 161) | function NeverRender(): React.ReactElement {
FILE: packages/react-router/__tests__/router/TestSequences/EncodedReservedCharacters.ts
function EncodeReservedCharacters (line 3) | function EncodeReservedCharacters(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/GoBack.ts
function GoBack (line 3) | async function GoBack(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/GoForward.ts
function GoForward (line 3) | async function GoForward(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/InitialLocationDefaultKey.ts
function InitialLocationDefaultKey (line 3) | function InitialLocationDefaultKey(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/InitialLocationHasKey.ts
function InitialLocationHasKey (line 3) | function InitialLocationHasKey(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/Listen.ts
function Listen (line 3) | function Listen(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/ListenPopOnly.ts
function ListenPopOnly (line 3) | function ListenPopOnly(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushMissingPathname.ts
function PushMissingPathname (line 3) | function PushMissingPathname(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushNewLocation.ts
function PushNewLocation (line 3) | function PushNewLocation(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushRelativePathname.ts
function PushRelativePathname (line 3) | function PushRelativePathname(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushRelativePathnameWarning.ts
function PushRelativePathnameWarning (line 3) | function PushRelativePathnameWarning(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushSamePath.ts
function PushSamePath (line 3) | async function PushSamePath(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushState.ts
function PushState (line 3) | function PushState(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/PushStateInvalid.ts
function PushState (line 3) | function PushState(history: History, window: Window) {
FILE: packages/react-router/__tests__/router/TestSequences/ReplaceNewLocation.ts
function ReplaceNewLocation (line 3) | function ReplaceNewLocation(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/ReplaceSamePath.ts
function ReplaceSamePath (line 3) | function ReplaceSamePath(history: History) {
FILE: packages/react-router/__tests__/router/TestSequences/ReplaceState.ts
function ReplaceState (line 3) | function ReplaceState(history: History) {
FILE: packages/react-router/__tests__/router/context-middleware-test.tsx
type RouterContext (line 32) | interface RouterContext {
function respondWithJson (line 38) | function respondWithJson(staticContext: StaticHandlerContext | Response) {
method loader (line 80) | loader({ context }) {
method action (line 88) | action({ context }) {
method loader (line 92) | loader({ context }) {
method loader (line 121) | async loader({ context }) {
method loader (line 129) | loader({ context }) {
method dataStrategy (line 137) | async dataStrategy({ matches }) {
method middleware (line 169) | middleware(context: RouterContextProvider) {
method middleware (line 182) | middleware(context: RouterContextProvider) {
method dataStrategy (line 194) | async dataStrategy({ context, matches }) {
function getOrderMiddleware (line 227) | function getOrderMiddleware(
method loader (line 267) | loader({ context }) {
method loader (line 278) | loader({ context }) {
method loader (line 427) | loader({ context }) {
method action (line 438) | action({ context }) {
method loader (line 441) | loader({ context }) {
method action (line 508) | action({ context }) {
method loader (line 569) | loader() {
method loader (line 586) | loader() {
method loader (line 630) | loader({ context }) {
method loader (line 642) | loader({ context }) {
method loader (line 676) | loader() {
method action (line 707) | action({ context }) {
method loader (line 710) | loader({ context }) {
method loader (line 828) | loader({ context }) {
method loader (line 841) | loader({ context }) {
method loader (line 886) | loader({ context }) {
method loader (line 899) | loader({ context }) {
method loader (line 951) | loader({ context }) {
method loader (line 965) | loader({ context }) {
method loader (line 1014) | loader() {
method loader (line 1034) | loader() {
method loader (line 1071) | loader() {
method loader (line 1085) | loader() {
method loader (line 1134) | loader() {
method action (line 1165) | action() {
method loader (line 1168) | loader() {
method loader (line 1234) | loader() {
method action (line 1267) | action() {
method loader (line 1270) | loader() {
method loader (line 1333) | loader() {
method action (line 1363) | action() {
method loader (line 1366) | loader() {
method loader (line 1423) | loader() {
method action (line 1455) | action() {
method loader (line 1458) | loader() {
method loader (line 1506) | loader() {
method loader (line 1542) | loader() {
function getOrderMiddleware (line 1794) | function getOrderMiddleware(name: string): MiddlewareFunction {
method loader (line 1831) | loader() {
method loader (line 1850) | loader() {
method loader (line 1905) | loader() {
method loader (line 1926) | loader() {
method loader (line 1973) | loader() {
method loader (line 2013) | loader() {
method loader (line 2046) | loader() {
method loader (line 2080) | loader() {
method loader (line 2130) | loader() {
method loader (line 2165) | loader() {
method loader (line 2205) | loader({ context }) {
method loader (line 2216) | loader({ context }) {
method loader (line 2258) | loader({ context }) {
method action (line 2269) | action({ context }) {
method loader (line 2275) | loader({ context }) {
method loader (line 2326) | loader() {
method loader (line 2338) | loader() {
method loader (line 2380) | loader() {
method loader (line 2421) | loader() {
method loader (line 2435) | loader() {
method loader (line 2477) | loader() {
method loader (line 2491) | loader() {
method loader (line 2537) | loader() {
method action (line 2557) | action() {
method loader (line 2560) | loader() {
method loader (line 2608) | loader() {
method action (line 2629) | action() {
method loader (line 2632) | loader() {
method loader (line 2685) | loader() {
method action (line 2704) | action() {
method loader (line 2707) | loader() {
method loader (line 2755) | loader() {
method action (line 2776) | action() {
method loader (line 2779) | loader() {
method loader (line 2824) | loader() {
method loader (line 2855) | loader() {
method loader (line 2887) | loader() {
function getOrderMiddleware (line 2909) | function getOrderMiddleware(name: string): MiddlewareFunction {
method loader (line 2946) | loader() {
method loader (line 2965) | loader() {
method loader (line 3007) | loader() {
method loader (line 3028) | loader() {
method loader (line 3062) | loader() {
method loader (line 3090) | loader() {
method loader (line 3122) | loader() {
method loader (line 3155) | loader() {
method loader (line 3189) | loader() {
method loader (line 3223) | loader() {
method loader (line 3247) | loader({ context }) {
method loader (line 3258) | loader({ context }) {
method loader (line 3299) | loader({ context }) {
method action (line 3310) | action({ context }) {
method loader (line 3317) | loader({ context }) {
method loader (line 3365) | loader() {
method loader (line 3377) | loader() {
method loader (line 3411) | loader() {
method loader (line 3443) | loader() {
method loader (line 3456) | loader() {
method loader (line 3493) | loader() {
method loader (line 3507) | loader() {
method loader (line 3550) | loader() {
method action (line 3578) | action() {
method loader (line 3581) | loader() {
method loader (line 3629) | loader() {
method action (line 3663) | action() {
method loader (line 3666) | loader() {
method loader (line 3717) | loader() {
method action (line 3745) | action() {
method loader (line 3748) | loader() {
method loader (line 3797) | loader() {
method action (line 3830) | action() {
method loader (line 3833) | loader() {
method loader (line 3873) | loader() {
method loader (line 3904) | loader() {
FILE: packages/react-router/__tests__/router/data-strategy-test.ts
function mockDataStrategy (line 14) | function mockDataStrategy(fn: DataStrategyFunction) {
function keyedResults (line 21) | function keyedResults(
function keyedResultsUsingShouldCallHandler (line 35) | function keyedResultsUsingShouldCallHandler(
method dataStrategy (line 188) | async dataStrategy({ matches }) {
method dataStrategy (line 221) | async dataStrategy({ matches }) {
method dataStrategy (line 253) | async dataStrategy({ matches }) {
method dataStrategy (line 297) | dataStrategy({ matches }) {
method dataStrategy (line 335) | dataStrategy({ matches }) {
method dataStrategy (line 375) | dataStrategy({ matches }) {
method dataStrategy (line 416) | dataStrategy({ matches, request }) {
method dataStrategy (line 1084) | async dataStrategy({ matches }) {
method dataStrategy (line 1143) | async dataStrategy({ matches }) {
method middleware (line 1206) | middleware(context) {
method middleware (line 1219) | middleware(context) {
method dataStrategy (line 1227) | async dataStrategy({ matches }) {
method middleware (line 1326) | middleware(context) {
method middleware (line 1339) | middleware(context) {
method dataStrategy (line 1347) | async dataStrategy({ matches }) {
method middleware (line 1439) | middleware(context) {
method middleware (line 1452) | middleware(context) {
method dataStrategy (line 1460) | async dataStrategy({ matches }) {
method dataStrategy (line 1552) | async dataStrategy({ request, matches }) {
method dataStrategy (line 1665) | async dataStrategy({ request, matches }) {
method dataStrategy (line 1765) | async dataStrategy({ request, matches, context }) {
FILE: packages/react-router/__tests__/router/fetchers-test.ts
function initializeTest (line 20) | function initializeTest(init?: {
method patchRoutesOnNavigation (line 133) | async patchRoutesOnNavigation({ path, patch }) {
method loader (line 2707) | async loader() {
method action (line 2716) | async action() {
FILE: packages/react-router/__tests__/router/instrumentation-test.ts
method route (line 48) | route(route) {
method route (line 92) | route(route) {
function loader (line 119) | function loader() {
method route (line 140) | route(route) {
method route (line 181) | route(route) {
method route (line 224) | route(route) {
method route (line 268) | route(route) {
method route (line 316) | route(route) {
method route (line 368) | route(route) {
method route (line 427) | route(route) {
method route (line 492) | route(route) {
method route (line 556) | route(route) {
method route (line 618) | route(route) {
method route (line 687) | route(route) {
method route (line 768) | route(route) {
method route (line 843) | route(route) {
method route (line 936) | route(route) {
method route (line 1014) | route(route) {
method route (line 1095) | route(route) {
method route (line 1174) | route(route) {
method route (line 1185) | route(route) {
method route (line 1233) | route(route) {
method route (line 1250) | route(route) {
method route (line 1300) | route(route) {
method route (line 1317) | route(route) {
method route (line 1370) | route(route) {
method route (line 1413) | route(route) {
method route (line 1456) | route(route) {
method route (line 1493) | route(route) {
method route (line 1535) | route(route) {
method route (line 1578) | route(route) {
method router (line 1629) | router(router) {
method router (line 1671) | router(router) {
method route (line 1724) | route(route) {
method route (line 1771) | route(route) {
method route (line 1816) | route(route) {
method generateMiddlewareResponse (line 1832) | async generateMiddlewareResponse(query) {
method route (line 1884) | route(route) {
method route (line 1927) | route(route) {
method handleDocumentRequest (line 1974) | handleDocumentRequest(request) {
method handler (line 1979) | handler(handler) {
method handleDocumentRequest (line 2050) | handleDocumentRequest(request) {
method route (line 2055) | route(route) {
method handleDocumentRequest (line 2126) | handleDocumentRequest(request) {
method route (line 2131) | route(route) {
method handleDocumentRequest (line 2197) | handleDocumentRequest(request) {
method route (line 2202) | route(route) {
FILE: packages/react-router/__tests__/router/interruptions-test.ts
function initializeTest (line 7) | function initializeTest(init?: {
FILE: packages/react-router/__tests__/router/lazy-discovery-test.ts
function last (line 11) | function last(array: any[]) {
method patchRoutesOnNavigation (line 39) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 95) | async patchRoutesOnNavigation({ patch, matches }) {
method lazyChildren (line 144) | async lazyChildren() {
method patchRoutesOnNavigation (line 166) | async patchRoutesOnNavigation({ patch, matches }) {
method patchRoutesOnNavigation (line 203) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 277) | async patchRoutesOnNavigation({ patch, matches }) {
method lazyChildren (line 338) | async lazyChildren() {
method patchRoutesOnNavigation (line 360) | async patchRoutesOnNavigation({ patch, matches }) {
method patchRoutesOnNavigation (line 396) | async patchRoutesOnNavigation({ path, matches, patch }) {
method patchRoutesOnNavigation (line 453) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 514) | async patchRoutesOnNavigation({ path, matches, patch }) {
method loader (line 554) | loader() {
method loader (line 561) | loader() {
method loadChildren (line 590) | async loadChildren() {
method patchRoutesOnNavigation (line 617) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 647) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 695) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 723) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 757) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 788) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 814) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 844) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 878) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 913) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 944) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 992) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1043) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1081) | async patchRoutesOnNavigation() {
method patchRoutesOnNavigation (line 1108) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1159) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1214) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1264) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1315) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1384) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1467) | async patchRoutesOnNavigation({ patch, path }) {
method patchRoutesOnNavigation (line 1562) | async patchRoutesOnNavigation({ patch, path }) {
method patchRoutesOnNavigation (line 1651) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1706) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 1763) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1816) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1869) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1921) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 1978) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 2035) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 2093) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2157) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2222) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2263) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2316) | async patchRoutesOnNavigation() {
method patchRoutesOnNavigation (line 2364) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2403) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 2451) | async patchRoutesOnNavigation({ patch }) {
method patchRoutesOnNavigation (line 2493) | async patchRoutesOnNavigation({ matches, patch }) {
method patchRoutesOnNavigation (line 2543) | async patchRoutesOnNavigation({ path, patch }) {
method patchRoutesOnNavigation (line 2585) | async patchRoutesOnNavigation({ path, patch }) {
FILE: packages/react-router/__tests__/router/lazy-test.ts
method loader (line 821) | async loader() {
method loader (line 867) | async loader() {
method loader (line 2917) | async loader() {
method loader (line 2988) | async loader() {
method loader (line 3137) | async loader() {
FILE: packages/react-router/__tests__/router/navigation-blocking-test.ts
constant LOADER_LATENCY_MS (line 5) | const LOADER_LATENCY_MS = 100;
function sleep (line 492) | function sleep(n: number = 500) {
FILE: packages/react-router/__tests__/router/navigation-test.ts
function initializeTest (line 7) | function initializeTest(init?: {
FILE: packages/react-router/__tests__/router/path-resolution-test.ts
function assertRoutingToSelf (line 13) | function assertRoutingToSelf(fooChildren, expectedPath, expectIndex) {
function assertRoutingToParent (line 149) | function assertRoutingToParent(fooChildren) {
function assertRoutingToSibling (line 241) | function assertRoutingToSibling(fooChildren) {
function assertRoutingToChild (line 338) | function assertRoutingToChild(fooChildren) {
FILE: packages/react-router/__tests__/router/revalidate-test.ts
method loader (line 928) | loader() {
method loader (line 1022) | loader() {
FILE: packages/react-router/__tests__/router/route-fallback-test.ts
type CustomMatchers (line 10) | interface CustomMatchers<R = jest.Expect> {
type Expect (line 22) | interface Expect extends CustomMatchers {}
type Matchers (line 23) | interface Matchers<R> extends CustomMatchers<R> {}
type InverseAsymmetricMatchers (line 24) | interface InverseAsymmetricMatchers extends CustomMatchers {}
FILE: packages/react-router/__tests__/router/router-test.ts
type CustomMatchers (line 20) | interface CustomMatchers<R = jest.Expect> {
type Expect (line 26) | interface Expect extends CustomMatchers {}
type Matchers (line 27) | interface Matchers<R> extends CustomMatchers<R> {}
type InverseAsymmetricMatchers (line 28) | interface InverseAsymmetricMatchers extends CustomMatchers {}
function initializeTest (line 36) | function initializeTest(init?: {
FILE: packages/react-router/__tests__/router/should-revalidate-test.ts
type CustomMatchers (line 9) | interface CustomMatchers {
type Expect (line 15) | interface Expect extends CustomMatchers {}
type Matchers (line 16) | interface Matchers extends CustomMatchers {}
type InverseAsymmetricMatchers (line 17) | interface InverseAsymmetricMatchers extends CustomMatchers {}
method dataStrategy (line 1200) | async dataStrategy({ request, matches }) {
FILE: packages/react-router/__tests__/router/ssr-test.ts
method lazy (line 278) | async lazy() {
method lazy (line 291) | async lazy() {
method lazy (line 304) | async lazy() {
function setupFlexRouteTest (line 1416) | function setupFlexRouteTest() {
FILE: packages/react-router/__tests__/router/submission-test.ts
function initializeTest (line 6) | function initializeTest(init?: {
function validateFormDataSubmission (line 926) | async function validateFormDataSubmission(
function validateJsonObjectSubmission (line 966) | async function validateJsonObjectSubmission(body: any) {
function validateJsonArraySubmission (line 999) | async function validateJsonArraySubmission(body: any) {
FILE: packages/react-router/__tests__/router/utils/custom-matchers.ts
type CustomMatchers (line 1) | interface CustomMatchers<R = jest.Expect> {
type Expect (line 13) | interface Expect extends CustomMatchers {}
type Matchers (line 14) | interface Matchers<R> extends CustomMatchers<R> {}
type InverseAsymmetricMatchers (line 15) | interface InverseAsymmetricMatchers extends CustomMatchers {}
function urlMatch (line 20) | function urlMatch(received, url) {
FILE: packages/react-router/__tests__/router/utils/data-router-setup.ts
type TestIndexRouteObject (line 34) | type TestIndexRouteObject = Pick<
type TestNonIndexRouteObject (line 49) | type TestNonIndexRouteObject = Pick<
type TestRouteObject (line 65) | type TestRouteObject = TestIndexRouteObject | TestNonIndexRouteObject;
type InternalHelpers (line 69) | type InternalHelpers = {
type Helpers (line 76) | type Helpers = InternalHelpers & {
type NavigationHelpers (line 96) | type NavigationHelpers = {
type FetcherHelpers (line 102) | type FetcherHelpers = NavigationHelpers & {
constant TASK_ROUTES (line 114) | const TASK_ROUTES: TestRouteObject[] = [
type SetupOpts (line 148) | type SetupOpts = Omit<RouterInit, "routes" | "history" | "window"> & {
function createDeferred (line 156) | function createDeferred<T = any>() {
function createAsyncStub (line 179) | function createAsyncStub(): [
function getFetcherData (line 189) | function getFetcherData(router: Router) {
function setup (line 210) | function setup({
function cleanup (line 746) | function cleanup(_router?: Router) {
FILE: packages/react-router/__tests__/router/utils/utils.ts
function sleep (line 3) | async function sleep(n: number) {
function tick (line 7) | async function tick() {
function invariant (line 16) | function invariant(value: any, message?: string) {
function createFormData (line 23) | function createFormData(obj: Record<string, string>): FormData {
function isRedirect (line 29) | function isRedirect(result: any) {
function createDeferred (line 35) | function createDeferred<T = unknown>() {
function findRouteById (line 61) | function findRouteById(
function createRequest (line 84) | function createRequest(path: string, opts?: RequestInit) {
function createSubmitRequest (line 88) | function createSubmitRequest(path: string, opts?: RequestInit) {
FILE: packages/react-router/__tests__/same-component-lifecycle-test.tsx
class Home (line 9) | class Home extends React.Component {
method componentDidMount (line 10) | componentDidMount() {
method render (line 13) | render() {
FILE: packages/react-router/__tests__/server-runtime/cookies-test.ts
function getCookieFromSetCookie (line 7) | function getCookieFromSetCookie(setCookie: string): string {
function spyConsole (line 201) | function spyConsole() {
FILE: packages/react-router/__tests__/server-runtime/handle-error-test.ts
function getHandler (line 6) | function getHandler(
method loader (line 38) | loader() {
method handleDocumentRequest (line 74) | handleDocumentRequest() {
method loader (line 89) | loader() {
method loader (line 106) | loader() {
method loader (line 144) | loader() {
method default (line 164) | default() {
method default (line 171) | default() {
method loader (line 174) | loader() {
method loader (line 199) | loader() {
method loader (line 238) | loader() {
FILE: packages/react-router/__tests__/server-runtime/server-test.ts
function spyConsole (line 11) | function spyConsole() {
method handleDocumentRequest (line 40) | handleDocumentRequest(request) {
method handleDocumentRequest (line 104) | handleDocumentRequest(request) {
method handleDocumentRequest (line 131) | handleDocumentRequest(request) {
method handleDocumentRequest (line 161) | handleDocumentRequest(request) {
method handleDocumentRequest (line 2105) | handleDocumentRequest(request, responseStatusCode, responseHeaders) {
FILE: packages/react-router/__tests__/server-runtime/sessions-test.ts
function getCookieFromSetCookie (line 9) | function getCookieFromSetCookie(setCookie: string): string {
function spyConsole (line 220) | function spyConsole() {
FILE: packages/react-router/__tests__/server-runtime/utils.ts
function mockServerBuild (line 20) | function mockServerBuild(
FILE: packages/react-router/__tests__/use-revalidator-test.tsx
function Layout (line 48) | function Layout() {
function Foo (line 61) | function Foo() {
method Component (line 245) | Component() {
method Component (line 262) | Component() {
method Component (line 268) | Component() {
method Component (line 297) | Component() {
FILE: packages/react-router/__tests__/useHref-basename-test.tsx
function ShowHref (line 5) | function ShowHref({ to }: { to: string }) {
FILE: packages/react-router/__tests__/useHref-test.tsx
function ShowHref (line 5) | function ShowHref({ to }: { to: string }) {
FILE: packages/react-router/__tests__/useLocation-test.tsx
function ShowLocation (line 5) | function ShowLocation() {
function App (line 40) | function App() {
FILE: packages/react-router/__tests__/useMatch-test.tsx
function ShowMatch (line 6) | function ShowMatch({ pattern }: { pattern: string }) {
function HomePage (line 104) | function HomePage() {
FILE: packages/react-router/__tests__/useNavigate-test.tsx
function Home (line 18) | function Home() {
function Home (line 58) | function Home() {
function Home (line 115) | function Home() {
function Home (line 172) | function Home() {
function Home (line 229) | function Home() {
method Component (line 308) | Component() {
function Home (line 330) | function Home() {
function Page (line 342) | function Page() {
function Home (line 500) | function Home() {
function Home (line 530) | function Home() {
function Parent (line 560) | function Parent() {
function Child (line 569) | function Child({ onChildRendered }) {
method Component (line 590) | Component() {
method Component (line 621) | Component() {
method Component (line 652) | Component() {
function Child (line 671) | function Child({ onChildRendered }) {
function Home (line 690) | function Home() {
function ShowLocationState (line 705) | function ShowLocationState() {
function Contacts (line 1220) | function Contacts() {
function NavBar (line 1275) | function NavBar() {
function Contacts (line 1894) | function Contacts() {
function NavBar (line 1962) | function NavBar() {
function Home (line 2078) | function Home() {
function Home (line 2122) | function Home() {
function Home (line 2160) | function Home() {
method Component (line 2194) | Component() {
function Home (line 2207) | function Home() {
function UseNavigateButton (line 2239) | function UseNavigateButton({
FILE: packages/react-router/__tests__/useOutlet-test.tsx
function Home (line 14) | function Home() {
function Home (line 33) | function Home() {
function Home (line 57) | function Home() {
function Users (line 83) | function Users() {
function Home (line 108) | function Home() {
function Home (line 134) | function Home() {
function Users (line 162) | function Users() {
function Profile (line 166) | function Profile() {
function Users (line 203) | function Users() {
function Profile (line 214) | function Profile() {
function Layout (line 274) | function Layout() {
function Layout (line 301) | function Layout() {
function Profile (line 305) | function Profile() {
FILE: packages/react-router/__tests__/useParams-test.tsx
function ShowParams (line 13) | function ShowParams() {
function UserDashboard (line 80) | function UserDashboard() {
function ShowParamsAndPath (line 250) | function ShowParamsAndPath({ path }: { path: string }) {
FILE: packages/react-router/__tests__/useResolvedPath-test.tsx
function ShowResolvedPath (line 13) | function ShowResolvedPath({ path }: { path: string | Path }) {
function LogResolvedPathInfo (line 234) | function LogResolvedPathInfo({ desc }) {
function App (line 254) | function App({ enableFlag }: { enableFlag: boolean }) {
function getHtml (line 403) | function getHtml(container: HTMLElement) {
FILE: packages/react-router/__tests__/useRoutes-test.tsx
function RoutesRenderer (line 176) | function RoutesRenderer({
FILE: packages/react-router/__tests__/utils/MemoryNavigate.tsx
function MemoryNavigate (line 6) | function MemoryNavigate({
FILE: packages/react-router/__tests__/utils/framework.ts
function mockFrameworkContext (line 6) | function mockFrameworkContext(
function mockEntryContext (line 46) | function mockEntryContext(
FILE: packages/react-router/__tests__/utils/getHtml.ts
function getHtml (line 3) | function getHtml(container: HTMLElement) {
FILE: packages/react-router/__tests__/utils/getWindow.ts
function getWindow (line 3) | function getWindow(initialUrl: string, isHash = false): Window {
FILE: packages/react-router/__tests__/utils/renderStrict.tsx
function renderStrict (line 12) | function renderStrict(
FILE: packages/react-router/__tests__/utils/tick.ts
function tick (line 1) | async function tick() {
FILE: packages/react-router/__tests__/utils/waitForRedirect.tsx
function waitForRedirect (line 1) | function waitForRedirect(fn: (...args: any[]) => void) {
FILE: packages/react-router/__tests__/vendor/turbo-stream-test.ts
function quickDecode (line 7) | async function quickDecode(stream: ReadableStream<Uint8Array>) {
method write (line 244) | write(chunk) {
class Custom (line 328) | class Custom {
method constructor (line 330) | constructor(public foo: string) {}
method constructor (line 369) | constructor(public foo: string) {}
class Custom (line 368) | class Custom {
method constructor (line 330) | constructor(public foo: string) {}
method constructor (line 369) | constructor(public foo: string) {}
class Class (line 442) | class Class {}
method write (line 511) | write(chunk) {
method write (line 542) | write(chunk) {
method write (line 573) | write(chunk) {
type Nested (line 583) | type Nested = { i: number; next: Promise<Nested> | null };
FILE: packages/react-router/lib/actions.ts
function throwIfPotentialCSRFAttack (line 1) | function throwIfPotentialCSRFAttack(
function matchWildcardDomain (line 41) | function matchWildcardDomain(domain: string, pattern: string) {
function isAllowedOrigin (line 93) | function isAllowedOrigin(
function parseHostHeader (line 105) | function parseHostHeader(headers: Headers) {
FILE: packages/react-router/lib/components.tsx
constant USE_OPTIMISTIC (line 91) | const USE_OPTIMISTIC = "useOptimistic";
function useOptimisticSafe (line 96) | function useOptimisticSafe<T>(
function mapRouteProperties (line 107) | function mapRouteProperties(route: RouteObject) {
type MemoryRouterOpts (line 176) | interface MemoryRouterOpts {
function createMemoryRouter (line 311) | function createMemoryRouter(
class Deferred (line 333) | class Deferred<T> {
method constructor (line 340) | constructor() {
type ClientOnErrorFunction (line 362) | interface ClientOnErrorFunction {
type RouterProviderProps (line 377) | interface RouterProviderProps {
function RouterProvider (line 464) | function RouterProvider({
function getOptimisticRouterState (line 763) | function getOptimisticRouterState(
function DataRoutes (line 793) | function DataRoutes({
type MemoryRouterProps (line 812) | interface MemoryRouterProps {
function MemoryRouter (line 861) | function MemoryRouter({
type NavigateProps (line 910) | interface NavigateProps {
function Navigate (line 951) | function Navigate({
type OutletProps (line 997) | interface OutletProps {
function Outlet (line 1033) | function Outlet(props: OutletProps): React.ReactElement | null {
type PathRouteProps (line 1040) | interface PathRouteProps {
type LayoutRouteProps (line 1128) | interface LayoutRouteProps extends PathRouteProps {}
type IndexRouteProps (line 1133) | interface IndexRouteProps {
type RouteProps (line 1218) | type RouteProps = PathRouteProps | LayoutRouteProps | IndexRouteProps;
function Route (line 1276) | function Route(props: RouteProps): React.ReactElement | null {
type RouterProps (line 1287) | interface RouterProps {
function Router (line 1354) | function Router({
type RoutesProps (line 1446) | interface RoutesProps {
function Routes (line 1479) | function Routes({
type AwaitResolveRenderFunction (line 1486) | interface AwaitResolveRenderFunction<Resolve = any> {
type AwaitProps (line 1493) | interface AwaitProps<Resolve> {
function Await (line 1645) | function Await<Resolve>({
type AwaitErrorBoundaryProps (line 1682) | type AwaitErrorBoundaryProps = React.PropsWithChildren<{
type AwaitErrorBoundaryState (line 1688) | type AwaitErrorBoundaryState = {
type AwaitRenderStatus (line 1692) | enum AwaitRenderStatus {
class AwaitErrorBoundary (line 1698) | class AwaitErrorBoundary extends React.Component<
method constructor (line 1702) | constructor(props: AwaitErrorBoundaryProps) {
method getDerivedStateFromError (line 1707) | static getDerivedStateFromError(error: any) {
method componentDidCatch (line 1711) | componentDidCatch(error: any, errorInfo: React.ErrorInfo) {
method render (line 1724) | render() {
function ResolveAwait (line 1788) | function ResolveAwait({
function createRoutesFromChildren (line 1813) | function createRoutesFromChildren(
function renderMatches (line 1923) | function renderMatches(
function useRouteComponentProps (line 1929) | function useRouteComponentProps() {
type RouteComponentProps (line 1938) | type RouteComponentProps = ReturnType<typeof useRouteComponentProps>;
type RouteComponentType (line 1939) | type RouteComponentType = React.ComponentType<RouteComponentProps>;
function WithComponentProps (line 1941) | function WithComponentProps({
function withComponentProps (line 1950) | function withComponentProps(Component: RouteComponentType) {
function useHydrateFallbackProps (line 1957) | function useHydrateFallbackProps() {
type HydrateFallbackProps (line 1965) | type HydrateFallbackProps = ReturnType<typeof useHydrateFallbackProps>;
type HydrateFallbackType (line 1966) | type HydrateFallbackType = React.ComponentType<HydrateFallbackProps>;
function WithHydrateFallbackProps (line 1968) | function WithHydrateFallbackProps({
function withHydrateFallbackProps (line 1977) | function withHydrateFallbackProps(HydrateFallback: HydrateFallbackType) {
function useErrorBoundaryProps (line 1984) | function useErrorBoundaryProps() {
type ErrorBoundaryProps (line 1993) | type ErrorBoundaryProps = ReturnType<typeof useErrorBoundaryProps>;
type ErrorBoundaryType (line 1994) | type ErrorBoundaryType = React.ComponentType<ErrorBoundaryProps>;
function WithErrorBoundaryProps (line 1996) | function WithErrorBoundaryProps({
function withErrorBoundaryProps (line 2005) | function withErrorBoundaryProps(ErrorBoundary: ErrorBoundaryType) {
FILE: packages/react-router/lib/context.ts
type IndexRouteObject (line 26) | interface IndexRouteObject {
type NonIndexRouteObject (line 47) | interface NonIndexRouteObject {
type RouteObject (line 68) | type RouteObject = IndexRouteObject | NonIndexRouteObject;
type DataRouteObject (line 70) | type DataRouteObject = RouteObject & {
type RouteMatch (line 75) | interface RouteMatch<
type DataRouteMatch (line 80) | interface DataRouteMatch extends RouteMatch<string, DataRouteObject> {}
type PatchRoutesOnNavigationFunctionArgs (line 82) | type PatchRoutesOnNavigationFunctionArgs =
type PatchRoutesOnNavigationFunction (line 85) | type PatchRoutesOnNavigationFunction =
type DataRouterContextObject (line 88) | interface DataRouterContextObject
function useIsRSCRouterContext (line 109) | function useIsRSCRouterContext(): boolean {
type ViewTransitionContextObject (line 113) | type ViewTransitionContextObject =
type FetchersContextObject (line 131) | type FetchersContextObject = Map<string, any>;
type NavigateOptions (line 145) | interface NavigateOptions {
type Navigator (line 173) | interface Navigator {
type NavigationContextObject (line 182) | interface NavigationContextObject {
type LocationContextObject (line 197) | interface LocationContextObject {
type RouteContextObject (line 207) | interface RouteContextObject {
constant ENABLE_DEV_WARNINGS (line 225) | const ENABLE_DEV_WARNINGS = __DEV__;
FILE: packages/react-router/lib/dom-export/dom-router-provider.tsx
type RouterProviderProps (line 7) | type RouterProviderProps = Omit<BaseRouterProviderProps, "flushSync">;
function RouterProvider (line 9) | function RouterProvider(props: Omit<RouterProviderProps, "flushSync">) {
FILE: packages/react-router/lib/dom-export/hydrated-router.tsx
type SSRInfo (line 32) | type SSRInfo = {
function initSsrInfo (line 49) | function initSsrInfo(): void {
function createHydratedRouter (line 80) | function createHydratedRouter({
type HydratedRouterProps (line 235) | interface HydratedRouterProps {
function HydratedRouter (line 347) | function HydratedRouter(props: HydratedRouterProps) {
FILE: packages/react-router/lib/dom/dom.ts
function isHtmlElement (line 9) | function isHtmlElement(object: any): object is HTMLElement {
function isButtonElement (line 13) | function isButtonElement(object: any): object is HTMLButtonElement {
function isFormElement (line 17) | function isFormElement(object: any): object is HTMLFormElement {
function isInputElement (line 21) | function isInputElement(object: any): object is HTMLInputElement {
type LimitedMouseEvent (line 25) | type LimitedMouseEvent = Pick<
function isModifiedEvent (line 30) | function isModifiedEvent(event: LimitedMouseEvent) {
function shouldProcessLinkClick (line 34) | function shouldProcessLinkClick(
type ParamKeyValuePair (line 45) | type ParamKeyValuePair = [string, string];
type URLSearchParamsInit (line 47) | type URLSearchParamsInit =
function createSearchParams (line 79) | function createSearchParams(
function getSearchParamsForLocation (line 96) | function getSearchParamsForLocation(
type JsonObject (line 121) | type JsonObject = { [Key in string]: JsonValue } & {
type JsonArray (line 124) | type JsonArray = JsonValue[] | readonly JsonValue[];
type JsonPrimitive (line 125) | type JsonPrimitive = string | number | boolean | null;
type JsonValue (line 126) | type JsonValue = JsonPrimitive | JsonObject | JsonArray;
type SubmitTarget (line 128) | type SubmitTarget =
function isFormDataSubmitterSupported (line 140) | function isFormDataSubmitterSupported() {
type SharedSubmitOptions (line 159) | interface SharedSubmitOptions {
type FetcherSubmitOptions (line 213) | interface FetcherSubmitOptions extends SharedSubmitOptions {}
type SubmitOptions (line 218) | interface SubmitOptions extends FetcherSubmitOptions {
function getFormEncType (line 253) | function getFormEncType(encType: string | null) {
function getFormSubmissionInfo (line 266) | function getFormSubmissionInfo(
FILE: packages/react-router/lib/dom/global.ts
type WindowReactRouterContext (line 6) | type WindowReactRouterContext = ServerHandoff & {
type ViewTransition (line 12) | interface ViewTransition {
type Document (line 24) | interface Document {
FILE: packages/react-router/lib/dom/lib.tsx
type DOMRouterOpts (line 139) | interface DOMRouterOpts {
function createBrowserRouter (line 645) | function createBrowserRouter(
function createHashRouter (line 684) | function createHashRouter(
function parseHydrationData (line 704) | function parseHydrationData(): HydrationState | undefined {
function deserializeErrors (line 715) | function deserializeErrors(
type BrowserRouterProps (line 772) | interface BrowserRouterProps {
function BrowserRouter (line 818) | function BrowserRouter({
type HashRouterProps (line 862) | interface HashRouterProps {
function HashRouter (line 909) | function HashRouter({
type HistoryRouterProps (line 953) | interface HistoryRouterProps {
function HistoryRouter (line 1002) | function HistoryRouter({
type LinkProps (line 1041) | interface LinkProps
constant ABSOLUTE_URL_REGEX (line 1274) | const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
function handleClick (line 1380) | function handleClick(
type NavLinkRenderProps (line 1454) | type NavLinkRenderProps = {
type NavLinkProps (line 1476) | interface NavLinkProps
type SharedFormProps (line 1729) | interface SharedFormProps extends React.FormHTMLAttributes<HTMLFormEleme...
type FetcherFormProps (line 1800) | interface FetcherFormProps extends SharedFormProps {}
type FormProps (line 1806) | interface FormProps extends SharedFormProps {
type HTMLSubmitEvent (line 1861) | type HTMLSubmitEvent = React.BaseSyntheticEvent<
type HTMLFormSubmitter (line 1867) | type HTMLFormSubmitter = HTMLButtonElement | HTMLInputElement;
type ScrollRestorationProps (line 1997) | type ScrollRestorationProps = ScriptsProps & {
function ScrollRestoration (line 2060) | function ScrollRestoration({
type DataRouterHook (line 2135) | enum DataRouterHook {
type DataRouterStateHook (line 2143) | enum DataRouterStateHook {
function getDataRouterConsoleError (line 2151) | function getDataRouterConsoleError(
function useDataRouterContext (line 2157) | function useDataRouterContext(hookName: DataRouterHook) {
function useDataRouterState (line 2163) | function useDataRouterState(hookName: DataRouterStateHook) {
function useLinkClickHandler (line 2202) | function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
function useSearchParams (line 2375) | function useSearchParams(
type SetURLSearchParams (line 2447) | type SetURLSearchParams = (
type SubmitFunction (line 2458) | interface SubmitFunction {
type FetcherSubmitFunction (line 2510) | interface FetcherSubmitFunction {
function useSubmit (line 2578) | function useSubmit(): SubmitFunction {
function useFormAction (line 2657) | function useFormAction(
type FetcherWithComponents (line 2718) | type FetcherWithComponents<TData> = Fetcher<TData> & {
function useFetcher (line 2894) | function useFetcher<T = any>({
function useFetchers (line 3005) | function useFetchers(): (Fetcher & { key: string })[] {
constant SCROLL_RESTORATION_STORAGE_KEY (line 3013) | const SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions";
function getScrollRestorationKey (line 3016) | function getScrollRestorationKey(
function useScrollRestoration (line 3065) | function useScrollRestoration({
function useBeforeUnload (line 3198) | function useBeforeUnload(
function usePageHide (line 3220) | function usePageHide(
function usePrompt (line 3282) | function usePrompt({
function useViewTransitionState (line 3331) | function useViewTransitionState(
FILE: packages/react-router/lib/dom/server.tsx
type StaticRouterProps (line 41) | interface StaticRouterProps {
function StaticRouter (line 69) | function StaticRouter({
type StaticRouterProviderProps (line 105) | interface StaticRouterProviderProps {
function StaticRouterProvider (line 157) | function StaticRouterProvider({
function serializeErrors (line 232) | function serializeErrors(
function getStatelessNavigator (line 263) | function getStatelessNavigator() {
type CreateStaticHandlerOptions (line 304) | type CreateStaticHandlerOptions = Omit<
function createStaticHandler (line 339) | function createStaticHandler(
function createStaticRouter (line 378) | function createStaticRouter(
function createHref (line 492) | function createHref(to: To) {
function encodeLocation (line 496) | function encodeLocation(to: To): Path {
constant ABSOLUTE_URL_REGEX (line 512) | const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
FILE: packages/react-router/lib/dom/ssr/components.tsx
function useDataRouterContext (line 40) | function useDataRouterContext() {
function useDataRouterStateContext (line 49) | function useDataRouterStateContext() {
function useFrameworkContext (line 66) | function useFrameworkContext(): FrameworkContextObject {
type DiscoverBehavior (line 85) | type DiscoverBehavior = "render" | "none";
type PrefetchBehavior (line 95) | type PrefetchBehavior = "intent" | "render" | "none" | "viewport";
type PrefetchHandlers (line 97) | interface PrefetchHandlers {
function usePrefetchBehavior (line 105) | function usePrefetchBehavior<T extends HTMLAnchorElement>(
function composeEventHandlers (line 180) | function composeEventHandlers<
function getActiveMatches (line 199) | function getActiveMatches(
constant CRITICAL_CSS_DATA_ATTRIBUTE (line 216) | const CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css";
type LinksProps (line 223) | interface LinksProps {
function Links (line 267) | function Links({ nonce, crossOrigin }: LinksProps): React.JSX.Element {
function PrefetchPageLinks (line 345) | function PrefetchPageLinks({ page, ...linkProps }: PageLinkDescriptor) {
function useKeyedPrefetchLinks (line 359) | function useKeyedPrefetchLinks(matches: AgnosticDataRouteMatch[]) {
function PrefetchPageLinksImpl (line 385) | function PrefetchPageLinksImpl({
function Meta (line 545) | function Meta(): React.JSX.Element {
function isValidMetaTag (line 676) | function isValidMetaTag(tagName: unknown): tagName is "meta" | "link" {
function setIsHydrated (line 685) | function setIsHydrated() {
type ScriptsProps (line 708) | type ScriptsProps = Omit<
function Scripts (line 760) | function Scripts(scriptProps: ScriptsProps): React.JSX.Element | null {
function dedupe (line 976) | function dedupe(array: any[]) {
function mergeRefs (line 980) | function mergeRefs<T = any>(
FILE: packages/react-router/lib/dom/ssr/data.ts
function createRequestInit (line 4) | async function createRequestInit(
FILE: packages/react-router/lib/dom/ssr/entry.ts
type SerializedError (line 8) | type SerializedError = {
type FrameworkContextObject (line 14) | interface FrameworkContextObject {
type EntryContext (line 41) | interface EntryContext extends FrameworkContextObject {
type FutureConfig (line 46) | interface FutureConfig {
type CriticalCss (line 52) | type CriticalCss = string | { rel: "stylesheet"; href: string };
type AssetsManifest (line 54) | interface AssetsManifest {
FILE: packages/react-router/lib/dom/ssr/errorBoundaries.tsx
type RemixErrorBoundaryProps (line 8) | type RemixErrorBoundaryProps = React.PropsWithChildren<{
type RemixErrorBoundaryState (line 14) | type RemixErrorBoundaryState = {
class RemixErrorBoundary (line 19) | class RemixErrorBoundary extends React.Component<
method constructor (line 23) | constructor(props: RemixErrorBoundaryProps) {
method getDerivedStateFromError (line 28) | static getDerivedStateFromError(error: Error) {
method getDerivedStateFromProps (line 32) | static getDerivedStateFromProps(
method render (line 56) | render() {
function RemixRootDefaultErrorBoundary (line 73) | function RemixRootDefaultErrorBoundary({
function BoundaryShell (line 139) | function BoundaryShell({
FILE: packages/react-router/lib/dom/ssr/errors.ts
function deserializeErrors (line 4) | function deserializeErrors(
FILE: packages/react-router/lib/dom/ssr/fallback.tsx
function RemixRootDefaultHydrateFallback (line 10) | function RemixRootDefaultHydrateFallback() {
FILE: packages/react-router/lib/dom/ssr/fog-of-war.ts
constant URL_LIMIT (line 23) | const URL_LIMIT = 7680;
function isFogOfWarEnabled (line 25) | function isFogOfWarEnabled(
function getPartialManifest (line 32) | function getPartialManifest(
function getPatchRoutesOnNavigationFunction (line 70) | function getPatchRoutesOnNavigationFunction(
function useFogOFWarDiscovery (line 107) | function useFogOFWarDiscovery(
function getManifestPath (line 200) | function getManifestPath(
constant MANIFEST_VERSION_STORAGE_KEY (line 213) | const MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
function fetchAndApplyManifestPatches (line 215) | async function fetchAndApplyManifestPatches(
function addToFifoQueue (line 346) | function addToFifoQueue(path: string, queue: Set<string>) {
function debounce (line 356) | function debounce(callback: (...args: unknown[]) => unknown, wait: numbe...
FILE: packages/react-router/lib/dom/ssr/hydration.tsx
function getHydrationData (line 8) | function getHydrationData({
FILE: packages/react-router/lib/dom/ssr/invariant.ts
function invariant (line 9) | function invariant(value: any, message?: string) {
FILE: packages/react-router/lib/dom/ssr/links.ts
function getKeyedLinksForMatches (line 18) | function getKeyedLinksForMatches(
function getRouteCssDescriptors (line 40) | function getRouteCssDescriptors(route: EntryRoute): HtmlLinkDescriptor[] {
function prefetchRouteCss (line 45) | async function prefetchRouteCss(route: EntryRoute): Promise<void> {
function prefetchStyleLinks (line 51) | async function prefetchStyleLinks(
function prefetchStyleLink (line 80) | async function prefetchStyleLink(
function isPageLinkDescriptor (line 122) | function isPageLinkDescriptor(
function isHtmlLinkDescriptor (line 128) | function isHtmlLinkDescriptor(object: any): object is HtmlLinkDescriptor {
type KeyedHtmlLinkDescriptor (line 147) | type KeyedHtmlLinkDescriptor = { key: string; link: HtmlLinkDescriptor };
function getKeyedPrefetchLinks (line 149) | async function getKeyedPrefetchLinks(
function getNewMatchesForLinks (line 179) | function getNewMatchesForLinks(
function getModuleLinkHrefs (line 246) | function getModuleLinkHrefs(
function dedupeHrefs (line 275) | function dedupeHrefs(hrefs: string[]): string[] {
function sortKeys (line 279) | function sortKeys<Obj extends { [Key in keyof Obj]: Obj[Key] }>(obj: Obj...
type KeyedLinkDescriptor (line 290) | type KeyedLinkDescriptor<Descriptor extends LinkDescriptor = LinkDescrip...
function dedupeLinkDescriptors (line 295) | function dedupeLinkDescriptors<Descriptor extends LinkDescriptor>(
function isPreloadSupported (line 328) | function isPreloadSupported(): boolean {
FILE: packages/react-router/lib/dom/ssr/markup.ts
constant ESCAPE_LOOKUP (line 7) | const ESCAPE_LOOKUP: { [match: string]: string } = {
constant ESCAPE_REGEX (line 15) | const ESCAPE_REGEX = /[&><\u2028\u2029]/g;
function escapeHtml (line 17) | function escapeHtml(html: string) {
FILE: packages/react-router/lib/dom/ssr/routeModules.ts
type RouteModules (line 19) | interface RouteModules {
type RouteModule (line 26) | interface RouteModule {
type ServerRouteModule (line 43) | interface ServerRouteModule extends RouteModule {
type ClientActionFunction (line 53) | type ClientActionFunction = (
type ClientActionFunctionArgs (line 60) | type ClientActionFunctionArgs = ActionFunctionArgs & {
type ClientLoaderFunction (line 67) | type ClientLoaderFunction = ((
type ClientLoaderFunctionArgs (line 76) | type ClientLoaderFunctionArgs = LoaderFunctionArgs & {
type ErrorBoundaryComponent (line 83) | type ErrorBoundaryComponent = ComponentType;
type HeadersArgs (line 85) | type HeadersArgs = {
type HeadersFunction (line 96) | interface HeadersFunction {
type HydrateFallbackComponent (line 104) | type HydrateFallbackComponent = ComponentType;
type LayoutComponent (line 111) | type LayoutComponent = ComponentType<{
type LinksFunction (line 124) | interface LinksFunction {
type MetaMatch (line 128) | interface MetaMatch<
type MetaMatches (line 147) | type MetaMatches<
type MetaArgs (line 161) | interface MetaArgs<
type MetaFunction (line 235) | interface MetaFunction<
type MetaDescriptor (line 245) | type MetaDescriptor =
type LdJsonObject (line 255) | type LdJsonObject = { [Key in string]: LdJsonValue } & {
type LdJsonArray (line 258) | type LdJsonArray = LdJsonValue[] | readonly LdJsonValue[];
type LdJsonPrimitive (line 259) | type LdJsonPrimitive = string | number | boolean | null;
type LdJsonValue (line 260) | type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray;
type RouteComponent (line 265) | type RouteComponent = ComponentType<{}>;
type RouteHandle (line 272) | type RouteHandle = unknown;
function loadRouteModule (line 274) | async function loadRouteModule(
FILE: packages/react-router/lib/dom/ssr/routes-test-stub.tsx
type StubRouteExtensions (line 42) | interface StubRouteExtensions {
type StubIndexRouteObject (line 53) | interface StubIndexRouteObject
type StubNonIndexRouteObject (line 67) | interface StubNonIndexRouteObject
type StubRouteObject (line 81) | type StubRouteObject = StubIndexRouteObject | StubNonIndexRouteObject;
type RoutesTestStubProps (line 83) | interface RoutesTestStubProps {
function createRoutesStub (line 119) | function createRoutesStub(
function processRoutes (line 182) | function processRoutes(
FILE: packages/react-router/lib/dom/ssr/routes.tsx
type Route (line 26) | interface Route {
type EntryRoute (line 34) | interface EntryRoute extends Route {
function groupRoutesByParentId (line 53) | function groupRoutesByParentId(manifest: RouteManifest<EntryRoute>) {
function getRouteComponents (line 69) | function getRouteComponents(
function createServerRoutes (line 123) | function createServerRoutes(
function createClientRoutesWithHMRRevalidationOptOut (line 177) | function createClientRoutesWithHMRRevalidationOptOut(
function preventInvalidServerHandlerCall (line 197) | function preventInvalidServerHandlerCall(
function noActionDefinedError (line 214) | function noActionDefinedError(
function createClientRoutes (line 226) | function createClientRoutes(
function getShouldRevalidateFunction (line 563) | function getShouldRevalidateFunction(
function wrapShouldRevalidateForHdr (line 612) | function wrapShouldRevalidateForHdr(
function loadRouteModuleWithBlockingLinks (line 630) | async function loadRouteModuleWithBlockingLinks(
function getRouteModuleComponent (line 664) | function getRouteModuleComponent(routeModule: RouteModule) {
function shouldHydrateRouteLoader (line 674) | function shouldHydrateRouteLoader(
FILE: packages/react-router/lib/dom/ssr/server.tsx
type ServerRouterProps (line 14) | interface ServerRouterProps {
function ServerRouter (line 45) | function ServerRouter({
FILE: packages/react-router/lib/dom/ssr/single-fetch.tsx
class SingleFetchNoResultError (line 27) | class SingleFetchNoResultError extends Error {}
type SingleFetchRedirectResult (line 29) | type SingleFetchRedirectResult = {
type DecodedSingleFetchResults (line 38) | type DecodedSingleFetchResults =
type SingleFetchResult (line 45) | type SingleFetchResult =
type SingleFetchResults (line 50) | type SingleFetchResults =
type StreamTransferProps (line 54) | interface StreamTransferProps {
constant SINGLE_FETCH_REDIRECT_STATUS (line 67) | const SINGLE_FETCH_REDIRECT_STATUS = 202;
constant NO_BODY_STATUS_CODES (line 77) | const NO_BODY_STATUS_CODES = new Set([100, 101, 204, 205]);
function StreamTransfer (line 81) | function StreamTransfer({
type GetRouteInfoFunction (line 162) | type GetRouteInfoFunction = (match: DataRouteMatch) => {
type ShouldAllowOptOutFunction (line 168) | type ShouldAllowOptOutFunction = (match: DataRouteMatch) => boolean;
type FetchAndDecodeFunction (line 170) | type FetchAndDecodeFunction = (
function getTurboStreamSingleFetchDataStrategy (line 178) | function getTurboStreamSingleFetchDataStrategy(
function getSingleFetchDataStrategyImpl (line 206) | function getSingleFetchDataStrategyImpl(
function singleFetchActionStrategy (line 301) | async function singleFetchActionStrategy(
function nonSsrStrategy (line 343) | async function nonSsrStrategy(
function singleFetchLoaderNavigationStrategy (line 384) | async function singleFetchLoaderNavigationStrategy(
function bubbleMiddlewareErrors (line 532) | async function bubbleMiddlewareErrors(
function singleFetchLoaderFetcherStrategy (line 576) | async function singleFetchLoaderFetcherStrategy(
function stripIndexParam (line 596) | function stripIndexParam(url: URL) {
function singleFetchUrl (line 612) | function singleFetchUrl(
function fetchAndDecodeViaTurboStream (line 651) | async function fetchAndDecodeViaTurboStream(
function decodeViaTurboStream (line 743) | function decodeViaTurboStream(
function unwrapSingleFetchResult (line 796) | function unwrapSingleFetchResult(
function createDeferred (line 833) | function createDeferred<T = unknown>() {
FILE: packages/react-router/lib/errors.ts
constant ERROR_DIGEST_BASE (line 5) | const ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR";
constant ERROR_DIGEST_REDIRECT (line 6) | const ERROR_DIGEST_REDIRECT = "REDIRECT";
constant ERROR_DIGEST_ROUTE_ERROR_RESPONSE (line 7) | const ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE";
function createRedirectErrorDigest (line 9) | function createRedirectErrorDigest(response: Response) {
function decodeRedirectErrorDigest (line 19) | function decodeRedirectErrorDigest(digest: string):
function createRouteErrorResponseDigest (line 46) | function createRouteErrorResponseDigest(
function decodeRouteErrorResponseDigest (line 72) | function decodeRouteErrorResponseDigest(
FILE: packages/react-router/lib/hooks.tsx
function useHref (line 89) | function useHref(
function useInRouterContext (line 127) | function useInRouterContext(): boolean {
function useLocation (line 156) | function useLocation(): Location {
function useNavigationType (line 176) | function useNavigationType(): NavigationType {
function useMatch (line 190) | function useMatch<
type NavigateFunction (line 211) | interface NavigateFunction {
function useIsomorphicLayoutEffect (line 221) | function useIsomorphicLayoutEffect(
function useNavigate (line 379) | function useNavigate(): NavigateFunction {
function useNavigateUnstable (line 386) | function useNavigateUnstable(): NavigateFunction {
function useOutletContext (line 535) | function useOutletContext<Context = unknown>(): Context {
function useOutlet (line 549) | function useOutlet(context?: unknown): React.ReactElement | null {
function useParams (line 666) | function useParams<
function useResolvedPath (line 700) | function useResolvedPath(
function useRoutes (line 755) | function useRoutes(
function useRoutesImpl (line 763) | function useRoutesImpl(
function DefaultErrorComponent (line 953) | function DefaultErrorComponent() {
type RenderErrorBoundaryProps (line 996) | type RenderErrorBoundaryProps = React.PropsWithChildren<{
type RenderErrorBoundaryState (line 1005) | type RenderErrorBoundaryState = {
class RenderErrorBoundary (line 1011) | class RenderErrorBoundary extends React.Component<
method constructor (line 1015) | constructor(props: RenderErrorBoundaryProps) {
method getDerivedStateFromError (line 1026) | static getDerivedStateFromError(error: any) {
method getDerivedStateFromProps (line 1030) | static getDerivedStateFromProps(
method componentDidCatch (line 1064) | componentDidCatch(error: any, errorInfo: React.ErrorInfo) {
method render (line 1075) | render() {
function RSCErrorHandler (line 1110) | function RSCErrorHandler({
type RenderedRouteProps (line 1157) | interface RenderedRouteProps {
function RenderedRoute (line 1163) | function RenderedRoute({ routeContext, match, children }: RenderedRouteP...
function _renderMatches (line 1184) | function _renderMatches(
type DataRouterHook (line 1376) | enum DataRouterHook {
type DataRouterStateHook (line 1382) | enum DataRouterStateHook {
function getDataRouterConsoleError (line 1396) | function getDataRouterConsoleError(
function useDataRouterContext (line 1402) | function useDataRouterContext(hookName: DataRouterHook) {
function useDataRouterState (line 1408) | function useDataRouterState(hookName: DataRouterStateHook) {
function useRouteContext (line 1414) | function useRouteContext(hookName: DataRouterStateHook) {
function useCurrentRouteId (line 1421) | function useCurrentRouteId(hookName: DataRouterStateHook) {
function useRouteId (line 1437) | function useRouteId() {
function useNavigation (line 1463) | function useNavigation(): Navigation {
function useRevalidator (line 1503) | function useRevalidator(): {
function useMatches (line 1530) | function useMatches(): UIMatch[] {
function useLoaderData (line 1563) | function useLoaderData<T = any>(): SerializeFrom<T> {
function useRouteLoaderData (line 1601) | function useRouteLoaderData<T = any>(
function useActionData (line 1640) | function useActionData<T = any>(): SerializeFrom<T> | undefined {
function useRouteError (line 1668) | function useRouteError(): unknown {
function useAsyncValue (line 1703) | function useAsyncValue(): unknown {
function useAsyncError (line 1733) | function useAsyncError(): unknown {
function useBlocker (line 1849) | function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
function useNavigateStable (line 1913) | function useNavigateStable(): NavigateFunction {
function warningOnce (line 1944) | function warningOnce(key: string, cond: boolean, message: string) {
type UseRouteArgs (line 1951) | type UseRouteArgs = [] | [routeId: keyof RouteModules];
type UseRouteResult (line 1954) | type UseRouteResult<Args extends UseRouteArgs> =
type UseRoute (line 1961) | type UseRoute<RouteId extends keyof RouteModules | unknown> = {
function useRoute (line 1976) | function useRoute<Args extends UseRouteArgs>(
FILE: packages/react-router/lib/href.ts
type Args (line 4) | type Args = { [K in keyof Pages]: ToArgs<Pages[K]["params"]> };
type ToArgs (line 7) | type ToArgs<Params extends Record<string, string | undefined>> =
function href (line 25) | function href<Path extends keyof Args>(
function trimTrailingSplat (line 62) | function trimTrailingSplat(path: string): string {
FILE: packages/react-router/lib/router/history.ts
type Action (line 8) | enum Action {
type Path (line 35) | interface Path {
type Location (line 59) | interface Location<State = any> extends Path {
type Update (line 83) | interface Update {
type Listener (line 103) | interface Listener {
type To (line 111) | type To = string | Partial<Path>;
type History (line 121) | interface History {
type HistoryState (line 194) | type HistoryState = {
function isLocation (line 203) | function isLocation(obj: unknown): obj is Location {
type InitialEntry (line 225) | type InitialEntry = string | Partial<Location>;
type MemoryHistoryOptions (line 227) | type MemoryHistoryOptions = {
type MemoryHistory (line 238) | interface MemoryHistory extends History {
function createMemoryHistory (line 249) | function createMemoryHistory(
type BrowserHistory (line 371) | interface BrowserHistory extends UrlHistory {}
type BrowserHistoryOptions (line 373) | type BrowserHistoryOptions = UrlHistoryOptions;
function createBrowserHistory (line 382) | function createBrowserHistory(
type HashHistory (line 435) | interface HashHistory extends UrlHistory {}
type HashHistoryOptions (line 437) | type HashHistoryOptions = UrlHistoryOptions;
function createHashHistory (line 447) | function createHashHistory(
function invariant (line 522) | function invariant(value: any, message?: string) {
function warning (line 528) | function warning(cond: any, message: string) {
function createKey (line 543) | function createKey() {
function getHistoryState (line 550) | function getHistoryState(location: Location, index: number): HistoryState {
function createLocation (line 568) | function createLocation(
function createPath (line 596) | function createPath({
function parsePath (line 613) | function parsePath(path: string): Partial<Path> {
type UrlHistory (line 637) | interface UrlHistory extends History {}
type UrlHistoryOptions (line 639) | type UrlHistoryOptions = {
function getUrlBasedHistory (line 644) | function getUrlBasedHistory(
function createBrowserURLImpl (line 774) | function createBrowserURLImpl(to: To, isAbsolute = false): URL {
FILE: packages/react-router/lib/router/instrumentation.ts
type unstable_ServerInstrumentation (line 21) | type unstable_ServerInstrumentation = {
type unstable_ClientInstrumentation (line 26) | type unstable_ClientInstrumentation = {
type unstable_InstrumentRequestHandlerFunction (line 31) | type unstable_InstrumentRequestHandlerFunction = (
type unstable_InstrumentRouterFunction (line 35) | type unstable_InstrumentRouterFunction = (
type unstable_InstrumentRouteFunction (line 39) | type unstable_InstrumentRouteFunction = (
type unstable_InstrumentationHandlerResult (line 43) | type unstable_InstrumentationHandlerResult =
type InstrumentFunction (line 48) | type InstrumentFunction<T> = (
type InstrumentationInfo (line 53) | type InstrumentationInfo =
type ReadonlyRequest (line 60) | type ReadonlyRequest = {
type ReadonlyContext (line 66) | type ReadonlyContext = MiddlewareEnabled extends true
type InstrumentableRoute (line 71) | type InstrumentableRoute = {
type RouteInstrumentations (line 78) | type RouteInstrumentations = {
type RouteLazyInstrumentationInfo (line 88) | type RouteLazyInstrumentationInfo = undefined;
type RouteHandlerInstrumentationInfo (line 90) | type RouteHandlerInstrumentationInfo = Readonly<{
type InstrumentableRouter (line 98) | type InstrumentableRouter = {
type RouterInstrumentations (line 102) | type RouterInstrumentations = {
type RouterNavigationInstrumentationInfo (line 107) | type RouterNavigationInstrumentationInfo = Readonly<{
type RouterFetchInstrumentationInfo (line 116) | type RouterFetchInstrumentationInfo = Readonly<{
type InstrumentableRequestHandler (line 127) | type InstrumentableRequestHandler = {
type RequestHandlerInstrumentations (line 131) | type RequestHandlerInstrumentations = {
type RequestHandlerInstrumentationInfo (line 135) | type RequestHandlerInstrumentationInfo = Readonly<{
function getRouteInstrumentationUpdates (line 142) | function getRouteInstrumentationUpdates(
function instrumentClientSideRouter (line 256) | function instrumentClientSideRouter(
function instrumentHandler (line 328) | function instrumentHandler(
function wrapImpl (line 366) | function wrapImpl<T extends InstrumentationInfo>(
type RecurseResult (line 388) | type RecurseResult = { type: "success" | "error"; value: unknown };
function recurseRight (line 390) | async function recurseRight<T extends InstrumentationInfo>(
function getHandlerInfo (line 448) | function getHandlerInfo(
function getRouterInfo (line 463) | function getRouterInfo(
function getReadonlyRequest (line 479) | function getReadonlyRequest(request: Request): {
function getReadonlyContext (line 493) | function getReadonlyContext(
function isPlainObject (line 517) | function isPlainObject(
FILE: packages/react-router/lib/router/links.ts
type Primitive (line 1) | type Primitive = null | undefined | string | number | boolean | symbol |...
type LiteralUnion (line 3) | type LiteralUnion<LiteralType, BaseType extends Primitive> =
type HtmlLinkProps (line 7) | interface HtmlLinkProps {
type HtmlLinkPreloadImage (line 132) | interface HtmlLinkPreloadImage extends HtmlLinkProps {
type HtmlLinkDescriptor (line 165) | type HtmlLinkDescriptor =
type PageLinkDescriptor (line 173) | interface PageLinkDescriptor
type LinkDescriptor (line 198) | type LinkDescriptor = HtmlLinkDescriptor | PageLinkDescriptor;
FILE: packages/react-router/lib/router/router.ts
type Router (line 81) | interface Router {
type RouterState (line 324) | interface RouterState {
type HydrationState (line 405) | type HydrationState = Partial<
type FutureConfig (line 412) | interface FutureConfig {}
type RouterInit (line 417) | interface RouterInit {
type StaticHandlerContext (line 435) | interface StaticHandlerContext {
type StaticHandler (line 451) | interface StaticHandler {
type ViewTransitionOpts (line 484) | type ViewTransitionOpts = {
type RouterSubscriber (line 492) | interface RouterSubscriber {
type GetScrollRestorationKeyFunction (line 508) | interface GetScrollRestorationKeyFunction {
type GetScrollPositionFunction (line 515) | interface GetScrollPositionFunction {
type RelativeRoutingType (line 527) | type RelativeRoutingType = "route" | "path";
type BaseNavigateOrFetchOptions (line 530) | type BaseNavigateOrFetchOptions = {
type BaseNavigateOptions (line 538) | type BaseNavigateOptions = BaseNavigateOrFetchOptions & {
type BaseSubmissionOptions (line 547) | type BaseSubmissionOptions = {
type LinkNavigateOptions (line 558) | type LinkNavigateOptions = BaseNavigateOptions;
type SubmissionNavigateOptions (line 563) | type SubmissionNavigateOptions = BaseNavigateOptions & BaseSubmissionOpt...
type RouterNavigateOptions (line 568) | type RouterNavigateOptions =
type LoadFetchOptions (line 575) | type LoadFetchOptions = BaseNavigateOrFetchOptions;
type SubmitFetchOptions (line 580) | type SubmitFetchOptions = BaseNavigateOrFetchOptions & BaseSubmissionOpt...
type RouterFetchOptions (line 585) | type RouterFetchOptions = LoadFetchOptions | SubmitFetchOptions;
type NavigationStates (line 590) | type NavigationStates = {
type Navigation (line 623) | type Navigation = NavigationStates[keyof NavigationStates];
type RevalidationState (line 625) | type RevalidationState = "idle" | "loading";
type FetcherStates (line 630) | type FetcherStates<TData = any> = {
type Fetcher (line 705) | type Fetcher<TData = any> =
type BlockerBlocked (line 708) | interface BlockerBlocked {
type BlockerUnblocked (line 715) | interface BlockerUnblocked {
type BlockerProceeding (line 722) | interface BlockerProceeding {
type Blocker (line 729) | type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding;
type BlockerFunction (line 731) | type BlockerFunction = (args: {
type ShortCircuitable (line 737) | interface ShortCircuitable {
type PendingActionResult (line 751) | type PendingActionResult =
type HandleActionResult (line 755) | interface HandleActionResult extends ShortCircuitable {
type HandleLoadersResult (line 767) | interface HandleLoadersResult extends ShortCircuitable {
type FetchLoadMatch (line 786) | interface FetchLoadMatch {
type RevalidatingFetcher (line 794) | interface RevalidatingFetcher extends FetchLoadMatch {
constant IDLE_NAVIGATION (line 821) | const IDLE_NAVIGATION: NavigationStates["Idle"] = {
constant IDLE_FETCHER (line 832) | const IDLE_FETCHER: FetcherStates["Idle"] = {
constant IDLE_BLOCKER (line 843) | const IDLE_BLOCKER: BlockerUnblocked = {
constant TRANSITIONS_STORAGE_KEY (line 854) | const TRANSITIONS_STORAGE_KEY = "remix-router-transitions";
function createRouter (line 869) | function createRouter(init: RouterInit): Router {
type CreateStaticHandlerOptions (line 3726) | interface CreateStaticHandlerOptions {
function createStaticHandler (line 3733) | function createStaticHandler(
function getStaticContextFromError (line 4666) | function getStaticContextFromError(
function throwStaticHandlerAbortedError (line 4683) | function throwStaticHandlerAbortedError(
function isSubmissionNavigation (line 4697) | function isSubmissionNavigation(
function normalizeTo (line 4707) | function normalizeTo(
function normalizeNavigateOptions (line 4778) | function normalizeNavigateOptions(
function getMatchesToLoad (line 4922) | function getMatchesToLoad(
function routeHasLoaderOrMiddleware (line 5218) | function routeHasLoaderOrMiddleware(route: RouteObject) {
function getRouteHydrationStatus (line 5229) | function getRouteHydrationStatus(
function isNewLoader (line 5263) | function isNewLoader(
function isNewRouteInstance (line 5282) | function isNewRouteInstance(
function shouldRevalidateLoader (line 5298) | function shouldRevalidateLoader(
function patchRoutesImpl (line 5312) | function patchRoutesImpl(
function isSameRoute (line 5394) | function isSameRoute(
function loadLazyRoute (line 5529) | function loadLazyRoute(
function isNonNullable (line 5682) | function isNonNullable<T>(value: T): value is NonNullable<T> {
function loadLazyMiddlewareForMatches (line 5686) | function loadLazyMiddlewareForMatches(
function defaultDataStrategy (line 5710) | async function defaultDataStrategy(
function defaultDataStrategyWithMiddleware (line 5724) | async function defaultDataStrategyWithMiddleware(
function runServerMiddlewarePipeline (line 5735) | function runServerMiddlewarePipeline(
function runClientMiddlewarePipeline (line 5767) | function runClientMiddlewarePipeline(
function runMiddlewarePipeline (line 5829) | async function runMiddlewarePipeline<Result>(
function callRouteMiddleware (line 5876) | async function callRouteMiddleware<Result>(
function getDataStrategyMatchLazyPromises (line 5955) | function getDataStrategyMatchLazyPromises(
function getDataStrategyMatch (line 5984) | function getDataStrategyMatch(
function getTargetedDataStrategyMatches (line 6071) | function getTargetedDataStrategyMatches(
function callDataStrategyImpl (line 6115) | async function callDataStrategyImpl(
function callLoaderOrAction (line 6189) | async function callLoaderOrAction({
function parseResponseBody (line 6326) | async function parseResponseBody(response: Response) {
function convertDataStrategyResultToDataResult (line 6338) | async function convertDataStrategyResultToDataResult(
function normalizeRelativeRoutingRedirectResponse (line 6415) | function normalizeRelativeRoutingRedirectResponse(
function normalizeRedirectLocation (line 6445) | function normalizeRedirectLocation(
function createClientSideRequest (line 6495) | function createClientSideRequest(
function convertFormDataToSearchParams (line 6532) | function convertFormDataToSearchParams(formData: FormData): URLSearchPar...
function convertSearchParamsToFormData (line 6543) | function convertSearchParamsToFormData(
function processRouteLoaderData (line 6553) | function processRouteLoaderData(
function processLoaderData (line 6658) | function processLoaderData(
function mergeLoaderData (line 6713) | function mergeLoaderData(
function getActionDataForCommit (line 6747) | function getActionDataForCommit(
function findNearestBoundary (line 6768) | function findNearestBoundary(
function getShortCircuitMatches (line 6781) | function getShortCircuitMatches(routes: AgnosticDataRouteObject[]): {
function getInternalRouterError (line 6806) | function getInternalRouterError(
function findRedirect (line 6862) | function findRedirect(
function stripHashFromPath (line 6874) | function stripHashFromPath(path: To) {
function isHashChangeOnly (line 6879) | function isHashChangeOnly(a: Location, b: Location): boolean {
function dataWithResponseInitToResponse (line 6900) | function dataWithResponseInitToResponse<D>(
function dataWithResponseInitToErrorResponse (line 6906) | function dataWithResponseInitToErrorResponse<D>(
function isDataStrategyResults (line 6916) | function isDataStrategyResults(
function isDataStrategyResult (line 6928) | function isDataStrategyResult(result: unknown): result is DataStrategyRe...
function isRedirectDataStrategyResult (line 6938) | function isRedirectDataStrategyResult(result: DataStrategyResult) {
function isErrorResult (line 6943) | function isErrorResult(result: DataResult): result is ErrorResult {
function isRedirectResult (line 6947) | function isRedirectResult(result?: DataResult): result is RedirectResult {
function isDataWithResponseInit (line 6951) | function isDataWithResponseInit(
function isResponse (line 6964) | function isResponse(value: any): value is Response {
function isRedirectStatusCode (line 6974) | function isRedirectStatusCode(statusCode: number): boolean {
function isRedirectResponse (line 6978) | function isRedirectResponse(result: any): result is Response {
function isValidMethod (line 6986) | function isValidMethod(method: string): method is FormMethod {
function isMutationMethod (line 6990) | function isMutationMethod(method: string): method is MutationFormMethod {
function hasNakedIndexQuery (line 6997) | function hasNakedIndexQuery(search: string): boolean {
function getTargetMatch (line 7001) | function getTargetMatch(
function getSubmissionFromNavigation (line 7020) | function getSubmissionFromNavigation(
function getLoadingNavigation (line 7059) | function getLoadingNavigation(
function getSubmittingNavigation (line 7090) | function getSubmittingNavigation(
function getLoadingFetcher (line 7107) | function getLoadingFetcher(
function getSubmittingFetcher (line 7138) | function getSubmittingFetcher(
function getDoneFetcher (line 7155) | function getDoneFetcher(data: Fetcher["data"]): FetcherStates["Idle"] {
function restoreAppliedTransitions (line 7169) | function restoreAppliedTransitions(
function persistAppliedTransitions (line 7190) | function persistAppliedTransitions(
function createDeferred (line 7213) | function createDeferred<T = unknown>() {
FILE: packages/react-router/lib/router/utils.ts
type MaybePromise (line 6) | type MaybePromise<T> = T | Promise<T>;
type RouteData (line 11) | interface RouteData {
type ResultType (line 15) | enum ResultType {
type SuccessResult (line 24) | interface SuccessResult {
type RedirectResult (line 34) | interface RedirectResult {
type ErrorResult (line 43) | interface ErrorResult {
type DataResult (line 53) | type DataResult = SuccessResult | RedirectResult | ErrorResult;
type LowerCaseFormMethod (line 55) | type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete";
type UpperCaseFormMethod (line 56) | type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>;
type HTMLFormMethod (line 62) | type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;
type FormMethod (line 68) | type FormMethod = UpperCaseFormMethod;
type MutationFormMethod (line 69) | type MutationFormMethod = Exclude<FormMethod, "GET">;
type FormEncType (line 71) | type FormEncType =
type JsonObject (line 78) | type JsonObject = { [Key in string]: JsonValue } & {
type JsonArray (line 81) | type JsonArray = JsonValue[] | readonly JsonValue[];
type JsonPrimitive (line 82) | type JsonPrimitive = string | number | boolean | null;
type JsonValue (line 83) | type JsonValue = JsonPrimitive | JsonObject | JsonArray;
type Submission (line 90) | type Submission =
type RouterContext (line 121) | interface RouterContext<T = unknown> {
function createContext (line 183) | function createContext<T>(defaultValue?: T): RouterContext<T> {
class RouterContextProvider (line 209) | class RouterContextProvider {
method constructor (line 216) | constructor(init?: Map<RouterContext, unknown>) {
method get (line 232) | get<T>(context: RouterContext<T>): T {
method set (line 252) | set<C extends RouterContext>(
type DefaultContext (line 260) | type DefaultContext = MiddlewareEnabled extends true
type DataFunctionArgs (line 269) | interface DataFunctionArgs<Context> {
type MiddlewareNextFunction (line 304) | interface MiddlewareNextFunction<Result = unknown> {
type MiddlewareFunction (line 314) | type MiddlewareFunction<Result = unknown> = (
type LoaderFunctionArgs (line 322) | interface LoaderFunctionArgs<Context = DefaultContext>
type ActionFunctionArgs (line 328) | interface ActionFunctionArgs<Context = DefaultContext>
type DataFunctionValue (line 334) | type DataFunctionValue = unknown;
type DataFunctionReturnValue (line 336) | type DataFunctionReturnValue = MaybePromise<DataFunctionValue>;
type LoaderFunction (line 341) | type LoaderFunction<Context = DefaultContext> = {
type ActionFunction (line 351) | interface ActionFunction<Context = DefaultContext> {
type ShouldRevalidateFunctionArgs (line 361) | interface ShouldRevalidateFunctionArgs {
type ShouldRevalidateFunction (line 422) | interface ShouldRevalidateFunction {
type DataStrategyMatch (line 426) | interface DataStrategyMatch
type DataStrategyFunctionArgs (line 500) | interface DataStrategyFunctionArgs<Context = DefaultContext>
type DataStrategyResult (line 519) | interface DataStrategyResult {
type DataStrategyFunction (line 524) | interface DataStrategyFunction<Context = DefaultContext> {
type AgnosticPatchRoutesOnNavigationFunctionArgs (line 530) | type AgnosticPatchRoutesOnNavigationFunctionArgs<
type AgnosticPatchRoutesOnNavigationFunction (line 541) | type AgnosticPatchRoutesOnNavigationFunction<
type MapRoutePropertiesFunction (line 552) | interface MapRoutePropertiesFunction {
type UnsupportedLazyRouteObjectKey (line 563) | type UnsupportedLazyRouteObjectKey =
function isUnsupportedLazyRouteObjectKey (line 578) | function isUnsupportedLazyRouteObjectKey(
type UnsupportedLazyRouteFunctionKey (line 591) | type UnsupportedLazyRouteFunctionKey =
function isUnsupportedLazyRouteFunctionKey (line 604) | function isUnsupportedLazyRouteFunctionKey(
type LazyRouteObject (line 616) | type LazyRouteObject<R extends AgnosticRouteObject> = {
type LazyRouteFunction (line 626) | interface LazyRouteFunction<R extends AgnosticRouteObject> {
type LazyRouteDefinition (line 633) | type LazyRouteDefinition<R extends AgnosticRouteObject> =
type AgnosticBaseRouteObject (line 640) | type AgnosticBaseRouteObject = {
type AgnosticIndexRouteObject (line 656) | type AgnosticIndexRouteObject = AgnosticBaseRouteObject & {
type AgnosticNonIndexRouteObject (line 664) | type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & {
type AgnosticRouteObject (line 673) | type AgnosticRouteObject =
type AgnosticDataIndexRouteObject (line 677) | type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & {
type AgnosticDataNonIndexRouteObject (line 681) | type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & {
type AgnosticDataRouteObject (line 689) | type AgnosticDataRouteObject =
type RouteManifest (line 693) | type RouteManifest<R = AgnosticDataRouteObject> = Record<
type Regex_az (line 699) | type Regex_az = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j...
type Regez_AZ (line 701) | type Regez_AZ = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J...
type Regex_09 (line 702) | type Regex_09 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
type Regex_w (line 703) | type Regex_w = Regex_az | Regez_AZ | Regex_09 | "_";
type ParamChar (line 704) | type ParamChar = Regex_w | "-";
type RegexMatchPlus (line 707) | type RegexMatchPlus<
type _PathParam (line 719) | type _PathParam<Path extends string> =
type PathParam (line 731) | type PathParam<Path extends string> =
type _tests (line 742) | type _tests = [
type ParamParseKey (line 756) | type ParamParseKey<Segment extends string> =
type Params (line 763) | type Params<Key extends string = string> = {
type AgnosticRouteMatch (line 770) | interface AgnosticRouteMatch<
type AgnosticDataRouteMatch (line 792) | interface AgnosticDataRouteMatch
function isIndexRoute (line 795) | function isIndexRoute(
function convertRoutesToDataRoutes (line 803) | function convertRoutesToDataRoutes(
function mergeRouteUpdates (line 859) | function mergeRouteUpdates<T extends AgnosticDataRouteObject>(
function matchRoutes (line 902) | function matchRoutes<
function matchRoutesImpl (line 912) | function matchRoutesImpl<
type UIMatch (line 951) | interface UIMatch<Data = unknown, Handle = unknown> {
function convertRouteMatchToUiMatch (line 979) | function convertRouteMatchToUiMatch(
type RouteMeta (line 994) | interface RouteMeta<
type RouteBranch (line 1003) | interface RouteBranch<
function flattenRoutes (line 1011) | function flattenRoutes<
function explodeOptionalSegments (line 1119) | function explodeOptionalSegments(path: string): string[] {
function rankRouteBranches (line 1164) | function rankRouteBranches(branches: RouteBranch[]): void {
function computeScore (line 1183) | function computeScore(path: string, index: boolean | undefined): number {
function compareIndexes (line 1208) | function compareIndexes(a: number[], b: number[]): number {
function matchRouteBranch (line 1223) | function matchRouteBranch<
function generatePath (line 1304) | function generatePath<Path extends string>(
type PathPattern (line 1360) | interface PathPattern<Path extends string = string> {
type PathMatch (line 1381) | interface PathMatch<ParamKey extends string = string> {
type Mutable (line 1400) | type Mutable<T> = {
function matchPath (line 1418) | function matchPath<
type CompiledPathParam (line 1471) | type CompiledPathParam = { paramName: string; isOptional?: boolean };
function compilePath (line 1473) | function compilePath(
function decodePath (line 1545) | function decodePath(value: string) {
function stripBasename (line 1563) | function stripBasename(
function prependBasename (line 1587) | function prependBasename({
constant ABSOLUTE_URL_REGEX (line 1600) | const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
function resolvePath (line 1613) | function resolvePath(to: To, fromPathname = "/"): Path {
function resolvePathname (line 1639) | function resolvePathname(relativePath: string, fromPathname: string): st...
function getInvalidPathError (line 1655) | function getInvalidPathError(
function getPathContributingMatches (line 1690) | function getPathContributingMatches<
function getResolveToMatches (line 1701) | function getResolveToMatches<
function resolveTo (line 1713) | function resolveTo(
class DataWithResponseInit (line 1816) | class DataWithResponseInit<D> {
method constructor (line 1821) | constructor(data: D, init?: ResponseInit) {
function data (line 1853) | function data<D>(data: D, init?: number | ResponseInit) {
type TrackedPromise (line 1862) | interface TrackedPromise extends Promise<any> {
type RedirectFunction (line 1868) | type RedirectFunction = (
type ErrorResponse (line 1981) | type ErrorResponse = {
class ErrorResponseImpl (line 1994) | class ErrorResponseImpl implements ErrorResponse {
method constructor (line 2001) | constructor(
function isRouteErrorResponse (line 2050) | function isRouteErrorResponse(error: any): error is ErrorResponse {
function getRoutePattern (line 2066) | function getRoutePattern(matches: AgnosticRouteMatch[]) {
type ParsedLocationInfo (line 2081) | type ParsedLocationInfo<T extends To> =
function parseToInfo (line 2092) | function parseToInfo<T extends To | string>(
FILE: packages/react-router/lib/rsc/browser.tsx
type BrowserCreateFromReadableStreamFunction (line 46) | type BrowserCreateFromReadableStreamFunction = (
type EncodeReplyFunction (line 55) | type EncodeReplyFunction = (
type WindowWithRouterGlobals (line 60) | type WindowWithRouterGlobals = Window &
function createCallServer (line 103) | function createCallServer({
function createRouterFromPayload (line 226) | function createRouterFromPayload({
function getRSCSingleFetchDataStrategy (line 424) | function getRSCSingleFetchDataStrategy(
function getFetchAndDecodeViaRSC (line 518) | function getFetchAndDecodeViaRSC(
type RSCHydratedRouterProps (line 615) | interface RSCHydratedRouterProps {
function RSCHydratedRouter (line 684) | function RSCHydratedRouter({
type DataRouteObjectWithManifestInfo (line 858) | type DataRouteObjectWithManifestInfo = DataRouteObject & {
function createRouteFromServerManifest (line 867) | function createRouteFromServerManifest(
function callSingleFetch (line 966) | function callSingleFetch(singleFetch: unknown) {
function preventInvalidServerHandlerCall (line 971) | function preventInvalidServerHandlerCall(
constant URL_LIMIT (line 996) | const URL_LIMIT = 7680;
function getManifestUrl (line 998) | function getManifestUrl(paths: string[]): URL | null {
function fetchAndApplyManifestPatches (line 1018) | async function fetchAndApplyManifestPatches(
function addToFifoQueue (line 1064) | function addToFifoQueue(path: string, queue: Set<string>) {
function debounce (line 1074) | function debounce(callback: (...args: unknown[]) => unknown, wait: numbe...
function isExternalLocation (line 1082) | function isExternalLocation(location: string) {
function cloneRoutes (line 1087) | function cloneRoutes(
function diffRoutes (line 1097) | function diffRoutes(
FILE: packages/react-router/lib/rsc/errorBoundaries.tsx
type RSCRouterGlobalErrorBoundaryProps (line 7) | type RSCRouterGlobalErrorBoundaryProps = React.PropsWithChildren<{
type RSCRouterGlobalErrorBoundaryState (line 11) | type RSCRouterGlobalErrorBoundaryState = {
class RSCRouterG
Condensed preview — 1375 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,993K chars).
[
{
"path": ".browserslistrc",
"chars": 107,
"preview": "# Browsers we support\nChrome >= 73\nChromeAndroid >= 75\nFirefox >= 67\nEdge >= 17\nSafari >= 12.1\niOS >= 11.3\n"
},
{
"path": ".changeset/README.md",
"chars": 510,
"preview": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that wo"
},
{
"path": ".changeset/config.json",
"chars": 890,
"preview": "{\n \"$schema\": \"https://unpkg.com/@changesets/config@2.0.0/schema.json\",\n \"changelog\": [\n \"@remix-run/changelog-gith"
},
{
"path": ".eslintignore",
"chars": 419,
"preview": "/fixtures/\nnode_modules/\npnpm-lock.yaml\n/docs/api\nexamples/**/dist/\nworker-configuration.d.ts\n/playground/\n/playground-l"
},
{
"path": ".eslintrc",
"chars": 2915,
"preview": "{\n \"extends\": [\"react-app\"],\n \"rules\": {\n \"import/first\": \"off\",\n \"@typescript-eslint/consistent-type-imports\": "
},
{
"path": ".github/FUNDING.yml",
"chars": 675,
"preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2923,
"preview": "name: 🐛 Bug Report\ndescription: Something is wrong with React Router\nlabels:\n - bug\nbody:\n - type: markdown\n attrib"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 597,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: 💡 Feature Request\n url: https://github.com/remix-run/react-route"
},
{
"path": ".github/ISSUE_TEMPLATE/documentation_isse.yml",
"chars": 655,
"preview": "name: 📚 Documentation Issue\ndescription: Something is wrong with the React Router docs\ntitle: \"[Docs]: \"\nlabels:\n - doc"
},
{
"path": ".github/dependabot.yml",
"chars": 111,
"preview": "version: 2\nupdates:\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: daily\n"
},
{
"path": ".github/workflows/close-feature-pr.yml",
"chars": 909,
"preview": "# Close a singular pull request that implements a feature that has not\n# gone through the Proposal process\n# Triggered b"
},
{
"path": ".github/workflows/close-no-repro-issue.yml",
"chars": 823,
"preview": "# Close a singular issue without a reproduction\n# Triggered by adding the `no-reproduction` label to an issue\n\nname: 🚪 C"
},
{
"path": ".github/workflows/close-no-repro-issues.yml",
"chars": 1407,
"preview": "# This is a bulk-close script that was used initially to find and close issues\n# without a repro, but moving forward we'"
},
{
"path": ".github/workflows/deduplicate-lock-file.yml",
"chars": 1226,
"preview": "name: ⚙️ Deduplicate lock file\n\non:\n push:\n branches:\n - dev\n paths:\n - pnpm-lock.yaml\n\nconcurrency:\n "
},
{
"path": ".github/workflows/docs.yml",
"chars": 1613,
"preview": "name: 📚 Docs\n\non:\n push:\n branches:\n - main\n - dev\n paths:\n - \"packages/**/*.ts\"\n - \"packages"
},
{
"path": ".github/workflows/format.yml",
"chars": 1301,
"preview": "name: 👔 Format\n\non:\n push:\n branches:\n - main\n - dev\n\nconcurrency:\n group: ${{ github.workflow }}-${{ git"
},
{
"path": ".github/workflows/integration-full.yml",
"chars": 1310,
"preview": "name: Branch\n\n# main/dev branches will get the full run across\n# all OS/browsers for multiple node versions\n\non:\n push:"
},
{
"path": ".github/workflows/integration-pr-ubuntu.yml",
"chars": 797,
"preview": "name: PR (Base)\n\n# All PRs touching code will run tests on ubuntu/node/chromium\n\non:\n pull_request:\n paths-ignore:\n "
},
{
"path": ".github/workflows/integration-pr-windows-macos.yml",
"chars": 1435,
"preview": "name: PR (Full)\n\n# PRs touching @react-router/dev will also run on Ubuntu/Firefox, Windows/Edge and\n# OSX/WebKit as well"
},
{
"path": ".github/workflows/no-response.yml",
"chars": 1220,
"preview": "name: 🥺 No Response\n\non:\n schedule:\n # Schedule for five minutes after the hour, every hour\n - cron: \"5 * * * *\"\n"
},
{
"path": ".github/workflows/release-comment-manual.yml",
"chars": 1210,
"preview": "# Used to manually trigger the release comments workflow\n\nname: 💬 Release Comment\non:\n workflow_dispatch:\n inputs:\n "
},
{
"path": ".github/workflows/release.yml",
"chars": 9305,
"preview": "# We use this singular file for all of our releases because we can only specify\n# a singular GitHub workflow file in npm"
},
{
"path": ".github/workflows/shared-build.yml",
"chars": 888,
"preview": "name: 🛠️ Build\n\non:\n workflow_call:\n\nenv:\n CI: true\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - name"
},
{
"path": ".github/workflows/shared-integration.yml",
"chars": 2161,
"preview": "name: 🧪 Test (Integration)\n\non:\n workflow_call:\n inputs:\n os:\n required: true\n type: string\n "
},
{
"path": ".github/workflows/support.yml",
"chars": 909,
"preview": "name: \"Support Requests\"\n\non:\n issues:\n types: [labeled, unlabeled, reopened]\n\npermissions:\n issues: write\n\njobs:\n "
},
{
"path": ".github/workflows/test.yml",
"chars": 1475,
"preview": "name: 🧪 Test\n\non:\n push:\n branches:\n - main\n - dev\n tags-ignore:\n - v*\n paths-ignore:\n - \""
},
{
"path": ".gitignore",
"chars": 522,
"preview": ".DS_Store\nnpm-debug.log\n\n/website/build/\nnode_modules/\n\n/examples/*/yarn.lock\n/examples/*/pnpm-lock.yaml\n/examples/*/dis"
},
{
"path": ".npmrc",
"chars": 58,
"preview": "ignore-workspace-cycles=true\nenable-pre-post-scripts=true\n"
},
{
"path": ".nvmrc",
"chars": 2,
"preview": "22"
},
{
"path": ".vscode/settings.json",
"chars": 106,
"preview": "{\n \"typescript.tsdk\": \"node_modules/typescript/lib\",\n \"typescript.enablePromptUseWorkspaceTsdk\": true\n}\n"
},
{
"path": "AGENTS.md",
"chars": 7288,
"preview": "# React Router Development Guide\n\n## Commands\n\n- **Build**: `pnpm build` (all packages) or `pnpm run --filter <package> "
},
{
"path": "CHANGELOG.md",
"chars": 283993,
"preview": "<!-- markdownlint-disable no-duplicate-header no-emphasis-as-heading no-inline-html -->\n\n# React Router Releases\n\nThis p"
},
{
"path": "CLA.md",
"chars": 5184,
"preview": "Remix Software, Inc. Individual Contributor License Agreement (\"Agreement\"), v2.0\n\nYou accept and agree to the following"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3584,
"preview": "## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as members, contributors, and leaders "
},
{
"path": "CONTRIBUTING.md",
"chars": 72,
"preview": "Please see [our guide to contributing](docs/community/contributing.md).\n"
},
{
"path": "DEVELOPMENT.md",
"chars": 8430,
"preview": "# React Router Development\n\n## Releases\n\nNew 7.x releases should be created from release branches originating from the `"
},
{
"path": "GOVERNANCE.md",
"chars": 37428,
"preview": "# React Router Open Governance Model <!-- omit in toc -->\n\n- [Overview](#overview)\n- [Design Goals](#design-goals)\n- [St"
},
{
"path": "LICENSE.md",
"chars": 1161,
"preview": "MIT License\n\nCopyright (c) React Training LLC 2015-2019\nCopyright (c) Remix Software Inc. 2020-2021\nCopyright (c) Shopif"
},
{
"path": "README.md",
"chars": 1400,
"preview": "[![npm package][npm-badge]][npm] [![build][build-badge]][build]\n\n[npm-badge]: https://img.shields.io/npm/v/react-router-"
},
{
"path": "SECURITY.md",
"chars": 2034,
"preview": "# Security Policy\n\n## Supported Versions\n\nThe following versions are currently being supported with security updates:\n\n|"
},
{
"path": "build.utils.ts",
"chars": 312,
"preview": "export function createBanner(packageName: string, version: string) {\n return `/**\n * ${packageName} v${version}\n *\n * C"
},
{
"path": "contributors.yml",
"chars": 5926,
"preview": "- 0xEddie\n- 3fuyang\n- 43081j\n- aarbi\n- abdallah-nour\n- abeadam\n- abhi-kr-2100\n- abhijeetpandit7\n- AchThomas\n- acusti\n- a"
},
{
"path": "decisions/0001-use-blocker.md",
"chars": 17298,
"preview": "# useBlocker\n\nDate: 2023-01-17\n\nStatus: accepted\n\n## Context\n\nReact Router v5 had a [`<Prompt>`](https://v5.reactrouter."
},
{
"path": "decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md",
"chars": 4572,
"preview": "# Use `npm` to manage NPM dependencies for Deno projects\n\nDate: 2022-05-10\n\nStatus: accepted\n\n## Context\n\nDeno has three"
},
{
"path": "decisions/0002-do-not-clone-request.md",
"chars": 1204,
"preview": "# Do not clone request\n\nDate: 2022-05-13\n\nStatus: accepted\n\n## Context\n\nTo allow multiple loaders / actions to read the "
},
{
"path": "decisions/0002-lazy-route-modules.md",
"chars": 13313,
"preview": "# Lazy Route Modules\n\nDate: 2023-02-21\n\nStatus: accepted\n\n## Context\n\nIn a data-aware React Router application (`<Router"
},
{
"path": "decisions/0003-data-strategy.md",
"chars": 18324,
"preview": "# Data Strategy\n\nDate: 2024-01-31\n\nStatus: accepted\n\n## Context\n\nIn order to implement \"Single Fetch\" in Remix ([Issue]["
},
{
"path": "decisions/0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md",
"chars": 8612,
"preview": "# Infer types for `useLoaderData` and `useActionData` from `loader` and `action` via generics\n\nDate: 2022-07-11\n\nStatus:"
},
{
"path": "decisions/0004-streaming-apis.md",
"chars": 10029,
"preview": "---\ntitle: Remix (and React Router) Streaming APIs\n---\n\n# Title\n\nDate: 2022-07-27\n\nStatus: accepted\n\n## Context\n\nRemix a"
},
{
"path": "decisions/0005-remixing-react-router.md",
"chars": 20775,
"preview": "# Remixing React Router\n\nDate: 2022-07-29\n\nStatus: accepted\n\n- [Remixing React Router](#remixing-react-router)\n - [Cont"
},
{
"path": "decisions/0006-linear-workflow.md",
"chars": 5462,
"preview": "# Linear Workflow\n\nDate: 2022-09-06\n\nStatus: accepted\n\n## Context\n\nThe Remix development team uses Linear internally to "
},
{
"path": "decisions/0007-remix-on-react-router-6-4-0.md",
"chars": 9585,
"preview": "# Layering Remix on top of React Router 6.4\n\nDate: 2022-08-16\n\nStatus: accepted\n\n## Context\n\nNow that we're almost done "
},
{
"path": "decisions/0008-only-support-js-conversion-for-app-code.md",
"chars": 4021,
"preview": "# Only support JS conversion for app code\n\nDate: 2023-01-20\n\nStatus: accepted\n\n## Context\n\nRemix defaults to Typescript,"
},
{
"path": "decisions/0009-do-not-rely-on-treeshaking-for-correctness.md",
"chars": 5608,
"preview": "# Do not rely on treeshaking for correctness\n\nDate: 2024-01-02\n\nStatus: accepted\n\n## Context\n\nRemix lets you write code "
},
{
"path": "decisions/0010-splitting-up-client-and-server-code-in-vite.md",
"chars": 4954,
"preview": "# Splitting up client and server code in Vite\n\nDate: 2024-02-01\n\nStatus: accepted\n\n## Context\n\nBefore adopting Vite, Rem"
},
{
"path": "decisions/0011-routes-ts.md",
"chars": 7065,
"preview": "# routes.ts\n\nDate: 2024-09-18\n\nStatus: accepted\n\n## Context\n\nNow that Remix is being merged upstream into React Router, "
},
{
"path": "decisions/0012-type-inference.md",
"chars": 14364,
"preview": "# Type inference\n\nDate: 2024-09-20\n\nStatus: accepted\n\nSupersedes [#0003](./0003-infer-types-for-useloaderdata-and-useact"
},
{
"path": "decisions/0013-react-router-config-ts.md",
"chars": 3811,
"preview": "# `react-router.config.ts`\n\nDate: 2024-11-21\n\nStatus: accepted\n\n## Context\n\nPreviously in Remix and earlier pre-releases"
},
{
"path": "decisions/0014-context-middleware.md",
"chars": 14355,
"preview": "# Middleware + Context\n\nDate: 2025-01-22\n\nStatus: accepted\n\n## Context\n\n_Lol \"context\", get it 😉_\n\nThe [Middleware RFC]["
},
{
"path": "decisions/0015-observability.md",
"chars": 12711,
"preview": "# Title\n\nDate: 2025-09-22\n\nStatus: proposed\n\n## Context\n\nWe want it to be easy to add observability to production React "
},
{
"path": "decisions/template.md",
"chars": 165,
"preview": "# Title\n\nDate: YYYY-MM-DD\n\nStatus: proposed | rejected | accepted | deprecated | … | superseded by [0005](0005-example.m"
},
{
"path": "docs/api/components/Await.md",
"chars": 3855,
"preview": "---\ntitle: Await\n---\n\n# Await\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file "
},
{
"path": "docs/api/components/Form.md",
"chars": 5434,
"preview": "---\ntitle: Form\n---\n\n# Form\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file is"
},
{
"path": "docs/api/components/Link.md",
"chars": 7228,
"preview": "---\ntitle: Link\n---\n\n# Link\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file is"
},
{
"path": "docs/api/components/Links.md",
"chars": 1581,
"preview": "---\ntitle: Links\n---\n\n# Links\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file "
},
{
"path": "docs/api/components/Meta.md",
"chars": 1070,
"preview": "---\ntitle: Meta\n---\n\n# Meta\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file is"
},
{
"path": "docs/api/components/NavLink.md",
"chars": 8439,
"preview": "---\ntitle: NavLink\n---\n\n# NavLink\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis f"
},
{
"path": "docs/api/components/Navigate.md",
"chars": 1641,
"preview": "---\ntitle: Navigate\n---\n\n# Navigate\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis"
},
{
"path": "docs/api/components/Outlet.md",
"chars": 1180,
"preview": "---\ntitle: Outlet\n---\n\n# Outlet\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis fil"
},
{
"path": "docs/api/components/PrefetchPageLinks.md",
"chars": 1751,
"preview": "---\ntitle: PrefetchPageLinks\n---\n\n# PrefetchPageLinks\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our do"
},
{
"path": "docs/api/components/Route.md",
"chars": 3306,
"preview": "---\ntitle: Route\n---\n\n# Route\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file "
},
{
"path": "docs/api/components/Routes.md",
"chars": 1445,
"preview": "---\ntitle: Routes\n---\n\n# Routes\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis fil"
},
{
"path": "docs/api/components/Scripts.md",
"chars": 1508,
"preview": "---\ntitle: Scripts\n---\n\n# Scripts\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis f"
},
{
"path": "docs/api/components/ScrollRestoration.md",
"chars": 2314,
"preview": "---\ntitle: ScrollRestoration\n---\n\n# ScrollRestoration\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our do"
},
{
"path": "docs/api/components/index.md",
"chars": 35,
"preview": "---\ntitle: Components\norder: 1\n---\n"
},
{
"path": "docs/api/data-routers/RouterProvider.md",
"chars": 3850,
"preview": "---\ntitle: RouterProvider\n---\n\n# RouterProvider\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our document"
},
{
"path": "docs/api/data-routers/StaticRouterProvider.md",
"chars": 2121,
"preview": "---\ntitle: StaticRouterProvider\n---\n\n# StaticRouterProvider\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve "
},
{
"path": "docs/api/data-routers/createBrowserRouter.md",
"chars": 16611,
"preview": "---\ntitle: createBrowserRouter\n---\n\n# createBrowserRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve ou"
},
{
"path": "docs/api/data-routers/createHashRouter.md",
"chars": 16485,
"preview": "---\ntitle: createHashRouter\n---\n\n# createHashRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docu"
},
{
"path": "docs/api/data-routers/createMemoryRouter.md",
"chars": 4228,
"preview": "---\ntitle: createMemoryRouter\n---\n\n# createMemoryRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our "
},
{
"path": "docs/api/data-routers/createStaticHandler.md",
"chars": 1525,
"preview": "---\ntitle: createStaticHandler\n---\n\n# createStaticHandler\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve ou"
},
{
"path": "docs/api/data-routers/createStaticRouter.md",
"chars": 1985,
"preview": "---\ntitle: createStaticRouter\n---\n\n# createStaticRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our "
},
{
"path": "docs/api/data-routers/index.md",
"chars": 37,
"preview": "---\ntitle: Data Routers\norder: 5\n---\n"
},
{
"path": "docs/api/declarative-routers/BrowserRouter.md",
"chars": 1809,
"preview": "---\ntitle: BrowserRouter\n---\n\n# BrowserRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/declarative-routers/HashRouter.md",
"chars": 1829,
"preview": "---\ntitle: HashRouter\n---\n\n# HashRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\n"
},
{
"path": "docs/api/declarative-routers/HistoryRouter.md",
"chars": 2165,
"preview": "---\ntitle: HistoryRouter\nunstable: true\n---\n\n# unstable_HistoryRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helpin"
},
{
"path": "docs/api/declarative-routers/MemoryRouter.md",
"chars": 1794,
"preview": "---\ntitle: MemoryRouter\n---\n\n# MemoryRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentatio"
},
{
"path": "docs/api/declarative-routers/Router.md",
"chars": 2687,
"preview": "---\ntitle: Router\n---\n\n# Router\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis fil"
},
{
"path": "docs/api/declarative-routers/StaticRouter.md",
"chars": 1195,
"preview": "---\ntitle: StaticRouter\n---\n\n# StaticRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentatio"
},
{
"path": "docs/api/declarative-routers/index.md",
"chars": 44,
"preview": "---\ntitle: Declarative Routers\norder: 6\n---\n"
},
{
"path": "docs/api/framework-conventions/client-modules.md",
"chars": 2833,
"preview": "---\ntitle: .client modules\n---\n\n# `.client` modules\n\n[MODES: framework]\n\n## Summary\n\nYou may have a file or dependency t"
},
{
"path": "docs/api/framework-conventions/entry.client.tsx.md",
"chars": 1058,
"preview": "---\ntitle: entry.client.tsx\norder: 4\n---\n\n# entry.client.tsx\n\n[MODES: framework]\n\n## Summary\n\n<docs-info>\nThis file is o"
},
{
"path": "docs/api/framework-conventions/entry.server.tsx.md",
"chars": 6760,
"preview": "---\ntitle: entry.server.tsx\norder: 5\n---\n\n# entry.server.tsx\n\n[MODES: framework]\n\n## Summary\n\nThis file is the server-si"
},
{
"path": "docs/api/framework-conventions/index.md",
"chars": 46,
"preview": "---\ntitle: Framework Conventions\norder: 3\n---\n"
},
{
"path": "docs/api/framework-conventions/react-router.config.ts.md",
"chars": 6368,
"preview": "---\ntitle: react-router.config.ts\norder: 3\n---\n\n# react-router.config.ts\n\n[MODES: framework]\n\n## Summary\n\n<docs-info>\nTh"
},
{
"path": "docs/api/framework-conventions/root.tsx.md",
"chars": 6472,
"preview": "---\ntitle: root.tsx\norder: 1\n---\n\n# root.tsx\n\n[MODES: framework]\n\n## Summary\n\n<docs-info>\nThis file is required\n</docs-i"
},
{
"path": "docs/api/framework-conventions/routes.ts.md",
"chars": 2334,
"preview": "---\ntitle: routes.ts\norder: 2\n---\n\n# routes.ts\n\n[MODES: framework]\n\n## Summary\n\n<docs-info>\nThis file is required\n</docs"
},
{
"path": "docs/api/framework-conventions/server-modules.md",
"chars": 3599,
"preview": "---\ntitle: .server modules\n---\n\n# `.server` modules\n\n[MODES: framework]\n\n## Summary\n\nServer-only modules that are exclud"
},
{
"path": "docs/api/framework-routers/HydratedRouter.md",
"chars": 1840,
"preview": "---\ntitle: HydratedRouter\n---\n\n# HydratedRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our document"
},
{
"path": "docs/api/framework-routers/ServerRouter.md",
"chars": 1229,
"preview": "---\ntitle: ServerRouter\n---\n\n# ServerRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentatio"
},
{
"path": "docs/api/framework-routers/index.md",
"chars": 42,
"preview": "---\ntitle: Framework Routers\norder: 4\n---\n"
},
{
"path": "docs/api/hooks/index.md",
"chars": 30,
"preview": "---\ntitle: Hooks\norder: 2\n---\n"
},
{
"path": "docs/api/hooks/useActionData.md",
"chars": 1461,
"preview": "---\ntitle: useActionData\n---\n\n# useActionData\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useAsyncError.md",
"chars": 1087,
"preview": "---\ntitle: useAsyncError\n---\n\n# useAsyncError\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useAsyncValue.md",
"chars": 959,
"preview": "---\ntitle: useAsyncValue\n---\n\n# useAsyncValue\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useBeforeUnload.md",
"chars": 1171,
"preview": "---\ntitle: useBeforeUnload\n---\n\n# useBeforeUnload\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docume"
},
{
"path": "docs/api/hooks/useBlocker.md",
"chars": 3945,
"preview": "---\ntitle: useBlocker\n---\n\n# useBlocker\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\n"
},
{
"path": "docs/api/hooks/useFetcher.md",
"chars": 2393,
"preview": "---\ntitle: useFetcher\n---\n\n# useFetcher\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\n"
},
{
"path": "docs/api/hooks/useFetchers.md",
"chars": 1237,
"preview": "---\ntitle: useFetchers\n---\n\n# useFetchers\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!"
},
{
"path": "docs/api/hooks/useFormAction.md",
"chars": 1426,
"preview": "---\ntitle: useFormAction\n---\n\n# useFormAction\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useHref.md",
"chars": 1185,
"preview": "---\ntitle: useHref\n---\n\n# useHref\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis f"
},
{
"path": "docs/api/hooks/useInRouterContext.md",
"chars": 915,
"preview": "---\ntitle: useInRouterContext\n---\n\n# useInRouterContext\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our "
},
{
"path": "docs/api/hooks/useLinkClickHandler.md",
"chars": 3333,
"preview": "---\ntitle: useLinkClickHandler\n---\n\n# useLinkClickHandler\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve ou"
},
{
"path": "docs/api/hooks/useLoaderData.md",
"chars": 1208,
"preview": "---\ntitle: useLoaderData\n---\n\n# useLoaderData\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useLocation.md",
"chars": 1190,
"preview": "---\ntitle: useLocation\n---\n\n# useLocation\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!"
},
{
"path": "docs/api/hooks/useMatch.md",
"chars": 1201,
"preview": "---\ntitle: useMatch\n---\n\n# useMatch\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis"
},
{
"path": "docs/api/hooks/useMatches.md",
"chars": 909,
"preview": "---\ntitle: useMatches\n---\n\n# useMatches\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\n"
},
{
"path": "docs/api/hooks/useNavigate.md",
"chars": 5878,
"preview": "---\ntitle: useNavigate\n---\n\n# useNavigate\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!"
},
{
"path": "docs/api/hooks/useNavigation.md",
"chars": 1245,
"preview": "---\ntitle: useNavigation\n---\n\n# useNavigation\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useNavigationType.md",
"chars": 1161,
"preview": "---\ntitle: useNavigationType\n---\n\n# useNavigationType\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our do"
},
{
"path": "docs/api/hooks/useOutlet.md",
"chars": 931,
"preview": "---\ntitle: useOutlet\n---\n\n# useOutlet\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nTh"
},
{
"path": "docs/api/hooks/useOutletContext.md",
"chars": 2582,
"preview": "---\ntitle: useOutletContext\n---\n\n# useOutletContext\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docu"
},
{
"path": "docs/api/hooks/useParams.md",
"chars": 2599,
"preview": "---\ntitle: useParams\n---\n\n# useParams\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nTh"
},
{
"path": "docs/api/hooks/usePrompt.md",
"chars": 2398,
"preview": "---\ntitle: usePrompt\nunstable: true\n---\n\n# unstable_usePrompt\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improv"
},
{
"path": "docs/api/hooks/useResolvedPath.md",
"chars": 1643,
"preview": "---\ntitle: useResolvedPath\n---\n\n# useResolvedPath\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docume"
},
{
"path": "docs/api/hooks/useRevalidator.md",
"chars": 1647,
"preview": "---\ntitle: useRevalidator\n---\n\n# useRevalidator\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our document"
},
{
"path": "docs/api/hooks/useRouteError.md",
"chars": 1178,
"preview": "---\ntitle: useRouteError\n---\n\n# useRouteError\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/hooks/useRouteLoaderData.md",
"chars": 1721,
"preview": "---\ntitle: useRouteLoaderData\n---\n\n# useRouteLoaderData\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our "
},
{
"path": "docs/api/hooks/useRoutes.md",
"chars": 1885,
"preview": "---\ntitle: useRoutes\n---\n\n# useRoutes\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nTh"
},
{
"path": "docs/api/hooks/useSearchParams.md",
"chars": 3459,
"preview": "---\ntitle: useSearchParams\n---\n\n# useSearchParams\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docume"
},
{
"path": "docs/api/hooks/useSubmit.md",
"chars": 1022,
"preview": "---\ntitle: useSubmit\n---\n\n# useSubmit\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nTh"
},
{
"path": "docs/api/hooks/useViewTransitionState.md",
"chars": 1932,
"preview": "---\ntitle: useViewTransitionState\n---\n\n# useViewTransitionState\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping impr"
},
{
"path": "docs/api/index.md",
"chars": 28,
"preview": "---\ntitle: API\norder: 3\n---\n"
},
{
"path": "docs/api/other-api/adapter.md",
"chars": 5531,
"preview": "---\ntitle: \"@react-router/{adapter}\"\n---\n\n# Server Adapters\n\n## Official Adapters\n\nIdiomatic React Router apps can gener"
},
{
"path": "docs/api/other-api/dev.md",
"chars": 7556,
"preview": "---\ntitle: \"@react-router/dev (CLI)\"\n---\n\n# React Router CLI\n\nThe React Router CLI comes from the `@react-router/dev` pa"
},
{
"path": "docs/api/other-api/index.md",
"chars": 34,
"preview": "---\ntitle: Other API\norder: 9\n---\n"
},
{
"path": "docs/api/other-api/serve.md",
"chars": 4333,
"preview": "---\ntitle: \"@react-router/serve\"\n---\n\n# React Router App Server\n\nReact Router is designed for you to own your server, bu"
},
{
"path": "docs/api/rsc/RSCHydratedRouter.md",
"chars": 2658,
"preview": "---\ntitle: RSCHydratedRouter\nunstable: true\n---\n\n# unstable_RSCHydratedRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you fo"
},
{
"path": "docs/api/rsc/RSCStaticRouter.md",
"chars": 2037,
"preview": "---\ntitle: RSCStaticRouter\nunstable: true\n---\n\n# unstable_RSCStaticRouter\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for he"
},
{
"path": "docs/api/rsc/createCallServer.md",
"chars": 2194,
"preview": "---\ntitle: createCallServer\nunstable: true\n---\n\n# unstable_createCallServer\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for "
},
{
"path": "docs/api/rsc/getRSCStream.md",
"chars": 1767,
"preview": "---\ntitle: getRSCStream\nunstable: true\n---\n\n# unstable_getRSCStream\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping "
},
{
"path": "docs/api/rsc/index.md",
"chars": 39,
"preview": "---\ntitle: RSC (Unstable)\norder: 7\n---\n"
},
{
"path": "docs/api/rsc/matchRSCServerRequest.md",
"chars": 5020,
"preview": "---\ntitle: matchRSCServerRequest\nunstable: true\n---\n\n# unstable_matchRSCServerRequest\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThan"
},
{
"path": "docs/api/rsc/routeRSCServerRequest.md",
"chars": 3324,
"preview": "---\ntitle: routeRSCServerRequest\nunstable: true\n---\n\n# unstable_routeRSCServerRequest\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThan"
},
{
"path": "docs/api/utils/IsCookieFunction.md",
"chars": 196,
"preview": "---\ntitle: IsCookieFunction\n---\n\n# IsCookieFunction\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗](h"
},
{
"path": "docs/api/utils/IsSessionFunction.md",
"chars": 199,
"preview": "---\ntitle: IsSessionFunction\n---\n\n# IsSessionFunction\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗]"
},
{
"path": "docs/api/utils/RouterContextProvider.md",
"chars": 1074,
"preview": "---\ntitle: RouterContextProvider\n---\n\n# RouterContextProvider\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improv"
},
{
"path": "docs/api/utils/createContext.md",
"chars": 2579,
"preview": "---\ntitle: createContext\n---\n\n# createContext\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/utils/createCookie.md",
"chars": 260,
"preview": "---\ntitle: createCookie\n---\n\n# createCookie\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗](https://a"
},
{
"path": "docs/api/utils/createCookieSessionStorage.md",
"chars": 600,
"preview": "---\ntitle: createCookieSessionStorage\n---\n\n# createCookieSessionStorage\n\n[MODES: framework, data]\n\n## Summary\n\n[Referenc"
},
{
"path": "docs/api/utils/createMemorySessionStorage.md",
"chars": 463,
"preview": "---\ntitle: createMemorySessionStorage\n---\n\n# createMemorySessionStorage\n\n[MODES: framework, data]\n\n## Summary\n\n[Referenc"
},
{
"path": "docs/api/utils/createPath.md",
"chars": 431,
"preview": "---\ntitle: createPath\n---\n\n# createPath\n\n[MODES: framework, data, declarative]\n\n## Summary\n\n[Reference Documentation ↗]("
},
{
"path": "docs/api/utils/createRequestHandler.md",
"chars": 234,
"preview": "---\ntitle: createRequestHandler\nhidden: true\n---\n\n# createRequestHandler\n\n[MODES: framework, data, declarative]\n\n## Summ"
},
{
"path": "docs/api/utils/createRoutesFromElements.md",
"chars": 1496,
"preview": "---\ntitle: createRoutesFromElements\n---\n\n# createRoutesFromElements\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping "
},
{
"path": "docs/api/utils/createRoutesStub.md",
"chars": 395,
"preview": "---\ntitle: createRoutesStub\n---\n\n# createRoutesStub\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗](h"
},
{
"path": "docs/api/utils/createSearchParams.md",
"chars": 906,
"preview": "---\ntitle: createSearchParams\n---\n\n# createSearchParams\n\n[MODES: framework, data, declarative]\n\n## Summary\n\n[Reference D"
},
{
"path": "docs/api/utils/createSession.md",
"chars": 382,
"preview": "---\ntitle: createSession\nhidden: true\n---\n\n# createSession\n\n[MODES: framework, data, declarative]\n\n## Summary\n\n[Referenc"
},
{
"path": "docs/api/utils/createSessionStorage.md",
"chars": 429,
"preview": "---\ntitle: createSessionStorage\nhidden: true\n---\n\n# createSessionStorage\n\n[MODES: framework, data, declarative]\n\n## Summ"
},
{
"path": "docs/api/utils/data.md",
"chars": 1303,
"preview": "---\ntitle: data\n---\n\n# data\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis file is"
},
{
"path": "docs/api/utils/generatePath.md",
"chars": 1084,
"preview": "---\ntitle: generatePath\n---\n\n# generatePath\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentatio"
},
{
"path": "docs/api/utils/href.md",
"chars": 341,
"preview": "---\ntitle: href\n---\n\n# href\n\n[MODES: framework]\n\n## Summary\n\n[Reference Documentation ↗](https://api.reactrouter.com/v7/"
},
{
"path": "docs/api/utils/index.md",
"chars": 30,
"preview": "---\ntitle: Utils\norder: 8\n---\n"
},
{
"path": "docs/api/utils/isCookie.md",
"chars": 228,
"preview": "---\ntitle: isCookie\n---\n\n# isCookie\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗](https://api.react"
},
{
"path": "docs/api/utils/isRouteErrorResponse.md",
"chars": 1613,
"preview": "---\ntitle: isRouteErrorResponse\n---\n\n# isRouteErrorResponse\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve "
},
{
"path": "docs/api/utils/isSession.md",
"chars": 229,
"preview": "---\ntitle: isSession\n---\n\n# isSession\n\n[MODES: framework, data]\n\n## Summary\n\n[Reference Documentation ↗](https://api.rea"
},
{
"path": "docs/api/utils/matchPath.md",
"chars": 1313,
"preview": "---\ntitle: matchPath\n---\n\n# matchPath\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nTh"
},
{
"path": "docs/api/utils/matchRoutes.md",
"chars": 1557,
"preview": "---\ntitle: matchRoutes\n---\n\n# matchRoutes\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!"
},
{
"path": "docs/api/utils/parsePath.md",
"chars": 402,
"preview": "---\ntitle: parsePath\n---\n\n# parsePath\n\n[MODES: framework, data, declarative]\n\n## Summary\n\n[Reference Documentation ↗](ht"
},
{
"path": "docs/api/utils/redirect.md",
"chars": 1367,
"preview": "---\ntitle: redirect\n---\n\n# redirect\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis"
},
{
"path": "docs/api/utils/redirectDocument.md",
"chars": 1627,
"preview": "---\ntitle: redirectDocument\n---\n\n# redirectDocument\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our docu"
},
{
"path": "docs/api/utils/renderMatches.md",
"chars": 984,
"preview": "---\ntitle: renderMatches\n---\n\n# renderMatches\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentat"
},
{
"path": "docs/api/utils/replace.md",
"chars": 1553,
"preview": "---\ntitle: replace\n---\n\n# replace\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!\n\nThis f"
},
{
"path": "docs/api/utils/resolvePath.md",
"chars": 1150,
"preview": "---\ntitle: resolvePath\n---\n\n# resolvePath\n\n<!--\n⚠️ ⚠️ IMPORTANT ⚠️ ⚠️ \n\nThank you for helping improve our documentation!"
},
{
"path": "docs/community/api-development-strategy.md",
"chars": 2271,
"preview": "---\ntitle: API Development Strategy\n---\n\n# API Development Strategy\n\nReact Router is foundational to your application. W"
},
{
"path": "docs/community/contributing.md",
"chars": 6505,
"preview": "---\ntitle: Contributing\n---\n\n# Contributing to React Router\n\nThanks for contributing, you rock!\n\nWhen it comes to open s"
},
{
"path": "docs/community/index.md",
"chars": 34,
"preview": "---\ntitle: Community\norder: 6\n---\n"
},
{
"path": "docs/elements.md",
"chars": 5547,
"preview": "---\ntitle: Markdown Elements\nhidden: true\n---\n\n# Markdown Elements\n\nThis is for testing all the different kinds of markd"
},
{
"path": "docs/explanation/README",
"chars": 93,
"preview": "Explanations:\n\n- Theoretical Knowledge\n- Understanding Oriented\n- Useful when we're studying\n"
},
{
"path": "docs/explanation/backend-for-frontend.md",
"chars": 2336,
"preview": "---\ntitle: Backend For Frontend\n---\n\n# Backend For Frontend\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nWhile React Router can ser"
},
{
"path": "docs/explanation/code-splitting.md",
"chars": 1770,
"preview": "---\ntitle: Automatic Code Splitting\n---\n\n# Automatic Code Splitting\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nWhen using React R"
},
{
"path": "docs/explanation/concurrency.md",
"chars": 7559,
"preview": "---\ntitle: Network Concurrency Management\n---\n\n# Network Concurrency Management\n\n[MODES: framework, data]\n\n<br/>\n<br/>\n\n"
},
{
"path": "docs/explanation/form-vs-fetcher.md",
"chars": 11630,
"preview": "---\ntitle: Form vs. fetcher\n---\n\n# Form vs. fetcher\n\n[MODES: framework, data]\n\n## Overview\n\nDeveloping in React Router o"
},
{
"path": "docs/explanation/hot-module-replacement.md",
"chars": 4878,
"preview": "---\ntitle: Hot Module Replacement\n---\n\n# Hot Module Replacement\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nHot Module Replacement"
},
{
"path": "docs/explanation/hydration.md",
"chars": 1216,
"preview": "---\ntitle: Hydration\nhidden: true\n---\n\nThere are a few nuances worth noting around the behavior of `HydrateFallback`:\n\n-"
},
{
"path": "docs/explanation/index-query-param.md",
"chars": 2642,
"preview": "---\ntitle: Index Query Param\n---\n\n# Index Query Param\n\n[MODES: framework, data]\n\n## Overview\n\nYou may find a wild `?inde"
},
{
"path": "docs/explanation/index.md",
"chars": 37,
"preview": "---\ntitle: Explanations\norder: 5\n---\n"
},
{
"path": "docs/explanation/lazy-route-discovery.md",
"chars": 3323,
"preview": "---\ntitle: Lazy Route Discovery\n---\n\n# Lazy Route Discovery\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nLazy Route Discovery is a "
},
{
"path": "docs/explanation/location.md",
"chars": 194,
"preview": "---\ntitle: Location Object\nhidden: true\n---\n\n<!-- put some stuff about what it is and how it can be used, probably good "
},
{
"path": "docs/explanation/progressive-enhancement.md",
"chars": 6292,
"preview": "---\ntitle: Progressive Enhancement\n---\n\n# Progressive Enhancement\n\n[MODES: framework]\n\n<br/>\n<br/>\n\n> Progressive enhanc"
},
{
"path": "docs/explanation/race-conditions.md",
"chars": 3797,
"preview": "---\ntitle: Race Conditions\n---\n\n# Race Conditions\n\n[MODES: framework, data]\n\n<br/>\n<br/>\n\nWhile impossible to eliminate "
},
{
"path": "docs/explanation/react-transitions.md",
"chars": 9071,
"preview": "---\ntitle: React Transitions\nunstable: true\n---\n\n# React Transitions\n\n[MODES: framework, data, declarative]\n\n<br/>\n<br/>"
},
{
"path": "docs/explanation/route-matching.md",
"chars": 139,
"preview": "---\ntitle: Route Matching\nhidden: true\n# want to explain how the matching algorithm works with any potential gotchas\n---"
},
{
"path": "docs/explanation/server-client-execution.md",
"chars": 61,
"preview": "---\ntitle: Server vs. Client Code Execution\nhidden: true\n---\n"
},
{
"path": "docs/explanation/sessions-and-cookies.md",
"chars": 16100,
"preview": "---\ntitle: Sessions and Cookies\n---\n\n# Sessions and Cookies\n\n[MODES: framework, data]\n\n## Sessions\n\nSessions are an impo"
},
{
"path": "docs/explanation/special-files.md",
"chars": 939,
"preview": "---\ntitle: Special Files\nhidden: true\n---\n\n# Special Files\n\nThe content of this page has been moved to the following:\n\n-"
},
{
"path": "docs/explanation/state-management.md",
"chars": 18464,
"preview": "---\ntitle: State Management\n---\n\n# State Management\n\n[MODES: framework, data]\n\n<br/>\n<br/>\n\nState management in React ty"
},
{
"path": "docs/explanation/type-safety.md",
"chars": 2404,
"preview": "---\ntitle: Type Safety\n---\n\n# Type Safety\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nIf you haven't done so already, check out ou"
},
{
"path": "docs/how-to/README",
"chars": 73,
"preview": "How-To:\n\n- Practical Steps\n- Problem Oriented\n- Useful when we're coding\n"
},
{
"path": "docs/how-to/accessibility.md",
"chars": 2522,
"preview": "---\ntitle: Accessibility\n---\n\n# Accessibility\n\nAccessibility in a React Router app looks a lot like accessibility on the"
},
{
"path": "docs/how-to/client-data.md",
"chars": 5809,
"preview": "---\ntitle: Client Data\n---\n\n# Client Data\n\n[MODES: framework]\n\n<br/>\n<br/>\n\nYou can fetch and mutate data directly in th"
}
]
// ... and 1175 more files (download for full content)
About this extraction
This page contains the full source code of the remix-run/react-router GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1375 files (7.2 MB), approximately 2.0M tokens, and a symbol index with 3037 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.