UNPKG

react-router

Version:
1,337 lines (1,322 loc) • 65.3 kB
import { R as Router, D as DataStrategyFunction, T as To, q as NavigateOptions, B as BlockerFunction, r as Blocker, a as RelativeRoutingType, c as Location, s as ParamParseKey, t as Path, v as PathPattern, w as PathMatch, U as UIMatch, x as Navigation, A as Action, h as Params, f as RouteObject, I as InitialEntry, H as HydrationState, b as IndexRouteObject, l as LoaderFunction, k as ActionFunction, N as NonIndexRouteObject, o as unstable_RouterContextProvider, M as MiddlewareEnabled, S as ShouldRevalidateFunction, e as RouterInit, y as RouterState, P as PatchRoutesOnNavigationFunction, z as DataRouteObject } from './context-DohQKLID.mjs'; export { i as ActionFunctionArgs, m as DataRouteMatch, Y as DataStrategyFunctionArgs, Z as DataStrategyMatch, _ as DataStrategyResult, $ as ErrorResponse, K as Fetcher, a0 as FormEncType, a1 as FormMethod, an as Future, G as GetScrollPositionFunction, E as GetScrollRestorationKeyFunction, a2 as HTMLFormMethod, ac as IDLE_BLOCKER, ab as IDLE_FETCHER, aa as IDLE_NAVIGATION, L as LazyRouteFunction, j as LoaderFunctionArgs, O as NavigationStates, d as Navigator, am as PatchRoutesOnNavigationFunctionArgs, a3 as PathParam, a4 as RedirectFunction, X as RevalidationState, g as RouteMatch, W as RouterFetchOptions, V as RouterNavigateOptions, Q as RouterSubscriber, a6 as ShouldRevalidateFunctionArgs, C as StaticHandler, J as StaticHandlerContext, as as UNSAFE_DataRouterContext, at as UNSAFE_DataRouterStateContext, p as UNSAFE_DataWithResponseInit, ar as UNSAFE_ErrorResponseImpl, au as UNSAFE_FetchersContext, av as UNSAFE_LocationContext, aw as UNSAFE_NavigationContext, ax as UNSAFE_RouteContext, ay as UNSAFE_ViewTransitionContext, ao as UNSAFE_createBrowserHistory, aq as UNSAFE_createRouter, ap as UNSAFE_invariant, a8 as createPath, ad as data, ae as generatePath, af as isRouteErrorResponse, ag as matchPath, ah as matchRoutes, a9 as parsePath, ai as redirect, aj as redirectDocument, ak as replace, al as resolvePath, n as unstable_MiddlewareFunction, a5 as unstable_RouterContext, a7 as unstable_createContext } from './context-DohQKLID.mjs'; import { a as RouteComponentType, H as HydrateFallbackType, E as ErrorBoundaryType } from './components-CuPfnyiZ.mjs'; export { f as Await, A as AwaitProps, I as IndexRouteProps, L as LayoutRouteProps, g as MemoryRouter, M as MemoryRouterOpts, b as MemoryRouterProps, h as Navigate, N as NavigateProps, i as Outlet, O as OutletProps, P as PathRouteProps, j as Route, c as RouteProps, k as Router, d as RouterProps, l as RouterProvider, R as RouterProviderProps, m as Routes, e as RoutesProps, W as UNSAFE_WithComponentProps, v as UNSAFE_WithErrorBoundaryProps, t as UNSAFE_WithHydrateFallbackProps, q as UNSAFE_hydrationRouteProperties, s as UNSAFE_mapRouteProperties, w as UNSAFE_withComponentProps, x as UNSAFE_withErrorBoundaryProps, u as UNSAFE_withHydrateFallbackProps, n as createMemoryRouter, o as createRoutesFromChildren, p as createRoutesFromElements, r as renderMatches } from './components-CuPfnyiZ.mjs'; import * as React from 'react'; import React__default, { ReactElement } from 'react'; import { c as RouteModules, d as SerializeFrom, e as MetaFunction, f as LinksFunction, A as AppLoadContext, E as Equal, g as ClientActionFunction, h as ClientLoaderFunction, H as HeadersFunction } from './route-data-CpB5xtMm.mjs'; export { i as ClientActionFunctionArgs, j as ClientLoaderFunctionArgs, k as HeadersArgs, n as HtmlLinkDescriptor, L as LinkDescriptor, l as MetaArgs, M as MetaDescriptor, m as PageLinkDescriptor, u as unstable_SerializesTo } from './route-data-CpB5xtMm.mjs'; import { A as AssetsManifest, E as EntryContext, F as FutureConfig, S as ServerBuild } from './index-react-server-client-DXb0OgpJ.mjs'; export { l as BrowserRouter, B as BrowserRouterProps, D as DOMRouterOpts, a1 as DiscoverBehavior, c as FetcherFormProps, h as FetcherSubmitFunction, G as FetcherSubmitOptions, i as FetcherWithComponents, q as Form, d as FormProps, a2 as HandleDataRequestFunction, a3 as HandleDocumentRequestFunction, a4 as HandleErrorFunction, m as HashRouter, H as HashRouterProps, a as HistoryRouterProps, n as Link, L as LinkProps, X as Links, _ as LinksProps, W as Meta, p as NavLink, N as NavLinkProps, b as NavLinkRenderProps, P as ParamKeyValuePair, a0 as PrefetchBehavior, Z as PrefetchPageLinks, Y as Scripts, $ as ScriptsProps, r as ScrollRestoration, e as ScrollRestorationProps, a5 as ServerEntryModule, f as SetURLSearchParams, T as StaticRouter, M as StaticRouterProps, V as StaticRouterProvider, O as StaticRouterProviderProps, g as SubmitFunction, I as SubmitOptions, J as SubmitTarget, a6 as UNSAFE_FrameworkContext, a7 as UNSAFE_createClientRoutes, a8 as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, a9 as UNSAFE_shouldHydrateRouteLoader, aa as UNSAFE_useScrollRestoration, U as URLSearchParamsInit, j as createBrowserRouter, k as createHashRouter, K as createSearchParams, Q as createStaticHandler, R as createStaticRouter, o as unstable_HistoryRouter, z as unstable_usePrompt, y as useBeforeUnload, w as useFetcher, x as useFetchers, v as useFormAction, u as useLinkClickHandler, s as useSearchParams, t as useSubmit, C as useViewTransitionState } from './index-react-server-client-DXb0OgpJ.mjs'; import { ParseOptions, SerializeOptions } from 'cookie'; export { ParseOptions as CookieParseOptions, SerializeOptions as CookieSerializeOptions } from 'cookie'; import { P as Pages } from './register-DiOIlEq5.mjs'; export { a as Register } from './register-DiOIlEq5.mjs'; export { g as unstable_getRSCStream } from './browser-z32v5KVN.mjs'; declare const SingleFetchRedirectSymbol: unique symbol; declare function getTurboStreamSingleFetchDataStrategy(getRouter: () => Router, manifest: AssetsManifest, routeModules: RouteModules, ssr: boolean, basename: string | undefined): DataStrategyFunction; declare function decodeViaTurboStream(body: ReadableStream<Uint8Array>, global: Window | typeof globalThis): Promise<{ done: Promise<undefined>; value: unknown; }>; /** * The mode to use when running the server. */ declare enum ServerMode { Development = "development", Production = "production", Test = "test" } /** * Resolves a URL against the current {@link Location}. * * @example * import { useHref } from "react-router"; * * function SomeComponent() { * let href = useHref("some/where"); * // "/resolved/some/where" * } * * @public * @category Hooks * @param to The path to resolve * @param options Options * @param options.relative Defaults to `"route"` so routing is relative to the * route tree. * Set to `"path"` to make relative routing operate against path segments. * @returns The resolved href string */ declare function useHref(to: To, { relative }?: { relative?: RelativeRoutingType; }): string; /** * Returns `true` if this component is a descendant of a {@link Router}, useful * to ensure a component is used within a {@link Router}. * * @public * @category Hooks * @mode framework * @mode data * @returns Whether the component is within a {@link Router} context */ declare function useInRouterContext(): boolean; /** * Returns the current {@link Location}. This can be useful if you'd like to * perform some side effect whenever it changes. * * @example * import * as React from 'react' * import { useLocation } from 'react-router' * * function SomeComponent() { * let location = useLocation() * * React.useEffect(() => { * // Google Analytics * ga('send', 'pageview') * }, [location]); * * return ( * // ... * ); * } * * @public * @category Hooks * @returns The current {@link Location} object */ declare function useLocation(): Location; /** * Returns the current {@link Navigation} action which describes how the router * came to the current {@link Location}, either by a pop, push, or replace on * the [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History) stack. * * @public * @category Hooks * @returns The current {@link NavigationType} (`"POP"`, `"PUSH"`, or `"REPLACE"`) */ declare function useNavigationType(): Action; /** * Returns a {@link PathMatch} object if the given pattern matches the current URL. * This is useful for components that need to know "active" state, e.g. * {@link NavLink | `<NavLink>`}. * * @public * @category Hooks * @param pattern The pattern to match against the current {@link Location} * @returns The path match object if the pattern matches, `null` otherwise */ declare function useMatch<ParamKey extends ParamParseKey<Path>, Path extends string>(pattern: PathPattern<Path> | Path): PathMatch<ParamKey> | null; /** * The interface for the `navigate` function returned from {@link useNavigate}. */ interface NavigateFunction { (to: To, options?: NavigateOptions): void | Promise<void>; (delta: number): void | Promise<void>; } /** * Returns a function that lets you navigate programmatically in the browser in * response to user interactions or effects. * * It's often better to use {@link redirect} in [`action`](../../start/framework/route-module#action)/[`loader`](../../start/framework/route-module#loader) * functions than this hook. * * The returned function signature is `navigate(to, options?)`/`navigate(delta)` where: * * * `to` can be a string path, a {@link To} object, or a number (delta) * * `options` contains options for modifying the navigation * * `flushSync`: Wrap the DOM updates in [`ReactDom.flushSync`](https://react.dev/reference/react-dom/flushSync) * * `preventScrollReset`: Do not scroll back to the top of the page after navigation * * `relative`: `"route"` or `"path"` to control relative routing logic * * `replace`: Replace the current entry in the [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History) stack * * `state`: Optional [`history.state`](https://developer.mozilla.org/en-US/docs/Web/API/History/state) to include with the new {@link Location} * * `viewTransition`: Enable [`document.startViewTransition`](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) for this navigation * * @example * import { useNavigate } from "react-router"; * * function SomeComponent() { * let navigate = useNavigate(); * return ( * <button onClick={() => navigate(-1)}> * Go Back * </button> * ); * } * * @additionalExamples * ### Navigate to another path * * ```tsx * navigate("/some/route"); * navigate("/some/route?search=param"); * ``` * * ### Navigate with a {@link To} object * * All properties are optional. * * ```tsx * navigate({ * pathname: "/some/route", * search: "?search=param", * hash: "#hash", * state: { some: "state" }, * }); * ``` * * If you use `state`, that will be available on the {@link Location} object on * the next page. Access it with `useLocation().state` (see {@link useLocation}). * * ### Navigate back or forward in the history stack * * ```tsx * // back * // often used to close modals * navigate(-1); * * // forward * // often used in a multistep wizard workflows * navigate(1); * ``` * * Be cautious with `navigate(number)`. If your application can load up to a * route that has a button that tries to navigate forward/back, there may not be * a `[`History`](https://developer.mozilla.org/en-US/docs/Web/API/History) * entry to go back or forward to, or it can go somewhere you don't expect * (like a different domain). * * Only use this if you're sure they will have an entry in the [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History) * stack to navigate to. * * ### Replace the current entry in the history stack * * This will remove the current entry in the [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History) * stack, replacing it with a new one, similar to a server side redirect. * * ```tsx * navigate("/some/route", { replace: true }); * ``` * * ### Prevent Scroll Reset * * [MODES: framework, data] * * <br/> * <br/> * * To prevent {@link ScrollRestoration | `<ScrollRestoration>`} from resetting * the scroll position, use the `preventScrollReset` option. * * ```tsx * navigate("?some-tab=1", { preventScrollReset: true }); * ``` * * For example, if you have a tab interface connected to search params in the * middle of a page, and you don't want it to scroll to the top when a tab is * clicked. * * @public * @category Hooks * @returns A navigate function for programmatic navigation */ declare function useNavigate(): NavigateFunction; /** * Returns the parent route {@link Outlet | `<Outlet context>`}. * * Often parent routes manage state or other values you want shared with child * routes. You can create your own [context provider](https://react.dev/learn/passing-data-deeply-with-context) * if you like, but this is such a common situation that it's built-into * {@link Outlet | `<Outlet>`}. * * ```tsx * // Parent route * function Parent() { * const [count, setCount] = React.useState(0); * return <Outlet context={[count, setCount]} />; * } * ``` * * ```tsx * // Child route * import { useOutletContext } from "react-router"; * * function Child() { * const [count, setCount] = useOutletContext(); * const increment = () => setCount((c) => c + 1); * return <button onClick={increment}>{count}</button>; * } * ``` * * If you're using TypeScript, we recommend the parent component provide a * custom hook for accessing the context value. This makes it easier for * consumers to get nice typings, control consumers, and know who's consuming * the context value. * * Here's a more realistic example: * * ```tsx filename=src/routes/dashboard.tsx lines=[14,20] * import { useState } from "react"; * import { Outlet, useOutletContext } from "react-router"; * * import type { User } from "./types"; * * type ContextType = { user: User | null }; * * export default function Dashboard() { * const [user, setUser] = useState<User | null>(null); * * return ( * <div> * <h1>Dashboard</h1> * <Outlet context={{ user } satisfies ContextType} /> * </div> * ); * } * * export function useUser() { * return useOutletContext<ContextType>(); * } * ``` * * ```tsx filename=src/routes/dashboard/messages.tsx lines=[1,4] * import { useUser } from "../dashboard"; * * export default function DashboardMessages() { * const { user } = useUser(); * return ( * <div> * <h2>Messages</h2> * <p>Hello, {user.name}!</p> * </div> * ); * } * ``` * * @public * @category Hooks * @returns The context value passed to the parent {@link Outlet} component */ declare function useOutletContext<Context = unknown>(): Context; /** * Returns the element for the child route at this level of the route * hierarchy. Used internally by {@link Outlet | `<Outlet>`} to render child * routes. * * @public * @category Hooks * @param context The context to pass to the outlet * @returns The child route element or `null` if no child routes match */ declare function useOutlet(context?: unknown): React.ReactElement | null; /** * Returns an object of key/value-pairs of the dynamic params from the current * URL that were matched by the routes. Child routes inherit all params from * their parent routes. * * Assuming a route pattern like `/posts/:postId` is matched by `/posts/123` * then `params.postId` will be `"123"`. * * @example * import { useParams } from "react-router"; * * function SomeComponent() { * let params = useParams(); * params.postId; * } * * @additionalExamples * ### Basic Usage * * ```tsx * import { useParams } from "react-router"; * * // given a route like: * <Route path="/posts/:postId" element={<Post />} />; * * // or a data route like: * createBrowserRouter([ * { * path: "/posts/:postId", * component: Post, * }, * ]); * * // or in routes.ts * route("/posts/:postId", "routes/post.tsx"); * ``` * * Access the params in a component: * * ```tsx * import { useParams } from "react-router"; * * export default function Post() { * let params = useParams(); * return <h1>Post: {params.postId}</h1>; * } * ``` * * ### Multiple Params * * Patterns can have multiple params: * * ```tsx * "/posts/:postId/comments/:commentId"; * ``` * * All will be available in the params object: * * ```tsx * import { useParams } from "react-router"; * * export default function Post() { * let params = useParams(); * return ( * <h1> * Post: {params.postId}, Comment: {params.commentId} * </h1> * ); * } * ``` * * ### Catchall Params * * Catchall params are defined with `*`: * * ```tsx * "/files/*"; * ``` * * The matched value will be available in the params object as follows: * * ```tsx * import { useParams } from "react-router"; * * export default function File() { * let params = useParams(); * let catchall = params["*"]; * // ... * } * ``` * * You can destructure the catchall param: * * ```tsx * export default function File() { * let { "*": catchall } = useParams(); * console.log(catchall); * } * ``` * * @public * @category Hooks * @returns An object containing the dynamic route parameters */ declare function useParams<ParamsOrKey extends string | Record<string, string | undefined> = string>(): Readonly<[ ParamsOrKey ] extends [string] ? Params<ParamsOrKey> : Partial<ParamsOrKey>>; /** * Resolves the pathname of the given `to` value against the current * {@link Location}. Similar to {@link useHref}, but returns a * {@link Path} instead of a string. * * @example * import { useResolvedPath } from "react-router"; * * function SomeComponent() { * // if the user is at /dashboard/profile * let path = useResolvedPath("../accounts"); * path.pathname; // "/dashboard/accounts" * path.search; // "" * path.hash; // "" * } * * @public * @category Hooks * @param to The path to resolve * @param options Options * @param options.relative Defaults to `"route"` so routing is relative to the route tree. * Set to `"path"` to make relative routing operate against path segments. * @returns The resolved {@link Path} object with `pathname`, `search`, and `hash` */ declare function useResolvedPath(to: To, { relative }?: { relative?: RelativeRoutingType; }): Path; /** * Hook version of {@link Routes | `<Routes>`} that uses objects instead of * components. These objects have the same properties as the component props. * The return value of `useRoutes` is either a valid React element you can use * to render the route tree, or `null` if nothing matched. * * @example * import { useRoutes } from "react-router"; * * function App() { * let element = useRoutes([ * { * path: "/", * element: <Dashboard />, * children: [ * { * path: "messages", * element: <DashboardMessages />, * }, * { path: "tasks", element: <DashboardTasks /> }, * ], * }, * { path: "team", element: <AboutPage /> }, * ]); * * return element; * } * * @public * @category Hooks * @param routes An array of {@link RouteObject}s that define the route hierarchy * @param locationArg An optional {@link Location} object or pathname string to * use instead of the current {@link Location} * @returns A React element to render the matched route, or `null` if no routes matched */ declare function useRoutes(routes: RouteObject[], locationArg?: Partial<Location> | string): React.ReactElement | null; /** * Returns the current {@link Navigation}, defaulting to an "idle" navigation * when no navigation is in progress. You can use this to render pending UI * (like a global spinner) or read [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) * from a form navigation. * * @example * import { useNavigation } from "react-router"; * * function SomeComponent() { * let navigation = useNavigation(); * navigation.state; * navigation.formData; * // etc. * } * * @public * @category Hooks * @mode framework * @mode data * @returns The current {@link Navigation} object */ declare function useNavigation(): Navigation; /** * Revalidate the data on the page for reasons outside of normal data mutations * like [`Window` focus](https://developer.mozilla.org/en-US/docs/Web/API/Window/focus_event) * or polling on an interval. * * Note that page data is already revalidated automatically after actions. * If you find yourself using this for normal CRUD operations on your data in * response to user interactions, you're probably not taking advantage of the * other APIs like {@link useFetcher}, {@link Form}, {@link useSubmit} that do * this automatically. * * @example * import { useRevalidator } from "react-router"; * * function WindowFocusRevalidator() { * const revalidator = useRevalidator(); * * useFakeWindowFocus(() => { * revalidator.revalidate(); * }); * * return ( * <div hidden={revalidator.state === "idle"}> * Revalidating... * </div> * ); * } * * @public * @category Hooks * @mode framework * @mode data * @returns An object with a `revalidate` function and the current revalidation * `state` */ declare function useRevalidator(): { revalidate: () => Promise<void>; state: Router["state"]["revalidation"]; }; /** * Returns the active route matches, useful for accessing `loaderData` for * parent/child routes or the route [`handle`](../../start/framework/route-module#handle) * property * * @public * @category Hooks * @mode framework * @mode data * @returns An array of {@link UIMatch | UI matches} for the current route hierarchy */ declare function useMatches(): UIMatch[]; /** * Returns the data from the closest route * [`loader`](../../start/framework/route-module#loader) or * [`clientLoader`](../../start/framework/route-module#clientloader). * * @example * import { useLoaderData } from "react-router"; * * export async function loader() { * return await fakeDb.invoices.findAll(); * } * * export default function Invoices() { * let invoices = useLoaderData<typeof loader>(); * // ... * } * * @public * @category Hooks * @mode framework * @mode data * @returns The data returned from the route's [`loader`](../../start/framework/route-module#loader) or [`clientLoader`](../../start/framework/route-module#clientloader) function */ declare function useLoaderData<T = any>(): SerializeFrom<T>; /** * Returns the [`loader`](../../start/framework/route-module#loader) data for a * given route by route ID. * * Route IDs are created automatically. They are simply the path of the route file * relative to the app folder without the extension. * * | Route Filename | Route ID | * | ---------------------------- | ---------------------- | * | `app/root.tsx` | `"root"` | * | `app/routes/teams.tsx` | `"routes/teams"` | * | `app/whatever/teams.$id.tsx` | `"whatever/teams.$id"` | * * @example * import { useRouteLoaderData } from "react-router"; * * function SomeComponent() { * const { user } = useRouteLoaderData("root"); * } * * // You can also specify your own route ID's manually in your routes.ts file: * route("/", "containers/app.tsx", { id: "app" }) * useRouteLoaderData("app"); * * @public * @category Hooks * @mode framework * @mode data * @param routeId The ID of the route to return loader data from * @returns The data returned from the specified route's [`loader`](../../start/framework/route-module#loader) * function, or `undefined` if not found */ declare function useRouteLoaderData<T = any>(routeId: string): SerializeFrom<T> | undefined; /** * Returns the [`action`](../../start/framework/route-module#action) data from * the most recent `POST` navigation form submission or `undefined` if there * hasn't been one. * * @example * import { Form, useActionData } from "react-router"; * * export async function action({ request }) { * const body = await request.formData(); * const name = body.get("visitorsName"); * return { message: `Hello, ${name}` }; * } * * export default function Invoices() { * const data = useActionData(); * return ( * <Form method="post"> * <input type="text" name="visitorsName" /> * {data ? data.message : "Waiting..."} * </Form> * ); * } * * @public * @category Hooks * @mode framework * @mode data * @returns The data returned from the route's [`action`](../../start/framework/route-module#action) * function, or `undefined` if no [`action`](../../start/framework/route-module#action) * has been called */ declare function useActionData<T = any>(): SerializeFrom<T> | undefined; /** * Accesses the error thrown during an * [`action`](../../start/framework/route-module#action), * [`loader`](../../start/framework/route-module#loader), * or component render to be used in a route module * [`ErrorBoundary`](../../start/framework/route-module#errorboundary). * * @example * export function ErrorBoundary() { * const error = useRouteError(); * return <div>{error.message}</div>; * } * * @public * @category Hooks * @mode framework * @mode data * @returns The error that was thrown during route [loading](../../start/framework/route-module#loader), * [`action`](../../start/framework/route-module#action) execution, or rendering */ declare function useRouteError(): unknown; /** * Returns the resolved promise value from the closest {@link Await | `<Await>`}. * * @example * function SomeDescendant() { * const value = useAsyncValue(); * // ... * } * * // somewhere in your app * <Await resolve={somePromise}> * <SomeDescendant /> * </Await>; * * @public * @category Hooks * @mode framework * @mode data * @returns The resolved value from the nearest {@link Await} component */ declare function useAsyncValue(): unknown; /** * Returns the rejection value from the closest {@link Await | `<Await>`}. * * @example * import { Await, useAsyncError } from "react-router"; * * function ErrorElement() { * const error = useAsyncError(); * return ( * <p>Uh Oh, something went wrong! {error.message}</p> * ); * } * * // somewhere in your app * <Await * resolve={promiseThatRejects} * errorElement={<ErrorElement />} * />; * * @public * @category Hooks * @mode framework * @mode data * @returns The error that was thrown in the nearest {@link Await} component */ declare function useAsyncError(): unknown; /** * Allow the application to block navigations within the SPA and present the * user a confirmation dialog to confirm the navigation. Mostly used to avoid * using half-filled form data. This does not handle hard-reloads or * cross-origin navigations. * * The {@link Blocker} object returned by the hook has the following properties: * * - **`state`** * - `unblocked` - the blocker is idle and has not prevented any navigation * - `blocked` - the blocker has prevented a navigation * - `proceeding` - the blocker is proceeding through from a blocked navigation * - **`location`** * - When in a `blocked` state, this represents the {@link Location} to which * we blocked a navigation. When in a `proceeding` state, this is the * location being navigated to after a `blocker.proceed()` call. * - **`proceed()`** * - When in a `blocked` state, you may call `blocker.proceed()` to proceed to * the blocked location. * - **`reset()`** * - When in a `blocked` state, you may call `blocker.reset()` to return the * blocker to an `unblocked` state and leave the user at the current * location. * * @example * // Boolean version * let blocker = useBlocker(value !== ""); * * // Function version * let blocker = useBlocker( * ({ currentLocation, nextLocation, historyAction }) => * value !== "" && * currentLocation.pathname !== nextLocation.pathname * ); * * @additionalExamples * ```tsx * import { useCallback, useState } from "react"; * import { BlockerFunction, useBlocker } from "react-router"; * * export function ImportantForm() { * const [value, setValue] = useState(""); * * const shouldBlock = useCallback<BlockerFunction>( * () => value !== "", * [value] * ); * const blocker = useBlocker(shouldBlock); * * return ( * <form * onSubmit={(e) => { * e.preventDefault(); * setValue(""); * if (blocker.state === "blocked") { * blocker.proceed(); * } * }} * > * <input * name="data" * value={value} * onChange={(e) => setValue(e.target.value)} * /> * * <button type="submit">Save</button> * * {blocker.state === "blocked" ? ( * <> * <p style={{ color: "red" }}> * Blocked the last navigation to * </p> * <button * type="button" * onClick={() => blocker.proceed()} * > * Let me through * </button> * <button * type="button" * onClick={() => blocker.reset()} * > * Keep me here * </button> * </> * ) : blocker.state === "proceeding" ? ( * <p style={{ color: "orange" }}> * Proceeding through blocked navigation * </p> * ) : ( * <p style={{ color: "green" }}> * Blocker is currently unblocked * </p> * )} * </form> * ); * } * ``` * * @public * @category Hooks * @mode framework * @mode data * @param shouldBlock Either a boolean or a function returning a boolean which * indicates whether the navigation should be blocked. The function format * receives a single object parameter containing the `currentLocation`, * `nextLocation`, and `historyAction` of the potential navigation. * @returns A {@link Blocker} object with state and reset functionality */ declare function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker; /** * @category Types */ interface ServerRouterProps { /** * The entry context containing the manifest, route modules, and other data * needed for rendering. */ context: EntryContext; /** * The URL of the request being handled. */ url: string | URL; /** * An optional `nonce` for [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) * compliance, used to allow inline scripts to run safely. */ nonce?: string; } /** * The server entry point for a React Router app in Framework Mode. This * component is used to generate the HTML in the response from the server. See * [`entry.server.tsx`](../framework-conventions/entry.server.tsx). * * @public * @category Framework Routers * @mode framework * @param props Props * @param {ServerRouterProps.context} props.context n/a * @param {ServerRouterProps.nonce} props.nonce n/a * @param {ServerRouterProps.url} props.url n/a * @returns A React element that represents the server-rendered application. */ declare function ServerRouter({ context, url, nonce, }: ServerRouterProps): ReactElement; interface StubRouteExtensions { Component?: RouteComponentType; HydrateFallback?: HydrateFallbackType; ErrorBoundary?: ErrorBoundaryType; loader?: LoaderFunction; action?: ActionFunction; children?: StubRouteObject[]; meta?: MetaFunction; links?: LinksFunction; } interface StubIndexRouteObject extends Omit<IndexRouteObject, "Component" | "HydrateFallback" | "ErrorBoundary" | "loader" | "action" | "element" | "errorElement" | "children">, StubRouteExtensions { } interface StubNonIndexRouteObject extends Omit<NonIndexRouteObject, "Component" | "HydrateFallback" | "ErrorBoundary" | "loader" | "action" | "element" | "errorElement" | "children">, StubRouteExtensions { } type StubRouteObject = StubIndexRouteObject | StubNonIndexRouteObject; interface RoutesTestStubProps { /** * The initial entries in the history stack. This allows you to start a test with * multiple locations already in the history stack (for testing a back navigation, etc.) * The test will default to the last entry in initialEntries if no initialIndex is provided. * e.g. initialEntries={["/home", "/about", "/contact"]} */ initialEntries?: InitialEntry[]; /** * The initial index in the history stack to render. This allows you to start a test at a specific entry. * It defaults to the last entry in initialEntries. * e.g. * initialEntries: ["/", "/events/123"] * initialIndex: 1 // start at "/events/123" */ initialIndex?: number; /** * Used to set the route's initial loader and action data. * e.g. hydrationData={{ * loaderData: { "/contact": { locale: "en-US" } }, * actionData: { "/login": { errors: { email: "invalid email" } }} * }} */ hydrationData?: HydrationState; /** * Future flags mimicking the settings in react-router.config.ts */ future?: Partial<FutureConfig>; } /** * @category Utils */ declare function createRoutesStub(routes: StubRouteObject[], _context?: AppLoadContext | unstable_RouterContextProvider): ({ initialEntries, initialIndex, hydrationData, future, }: RoutesTestStubProps) => React.JSX.Element; interface CookieSignatureOptions { /** * An array of secrets that may be used to sign/unsign the value of a cookie. * * The array makes it easy to rotate secrets. New secrets should be added to * the beginning of the array. `cookie.serialize()` will always use the first * value in the array, but `cookie.parse()` may use any of them so that * cookies that were signed with older secrets still work. */ secrets?: string[]; } type CookieOptions = ParseOptions & SerializeOptions & CookieSignatureOptions; /** * A HTTP cookie. * * A Cookie is a logical container for metadata about a HTTP cookie; its name * and options. But it doesn't contain a value. Instead, it has `parse()` and * `serialize()` methods that allow a single instance to be reused for * parsing/encoding multiple different values. * * @see https://remix.run/utils/cookies#cookie-api */ interface Cookie { /** * The name of the cookie, used in the `Cookie` and `Set-Cookie` headers. */ readonly name: string; /** * True if this cookie uses one or more secrets for verification. */ readonly isSigned: boolean; /** * The Date this cookie expires. * * Note: This is calculated at access time using `maxAge` when no `expires` * option is provided to `createCookie()`. */ readonly expires?: Date; /** * Parses a raw `Cookie` header and returns the value of this cookie or * `null` if it's not present. */ parse(cookieHeader: string | null, options?: ParseOptions): Promise<any>; /** * Serializes the given value to a string and returns the `Set-Cookie` * header. */ serialize(value: any, options?: SerializeOptions): Promise<string>; } /** * Creates a logical container for managing a browser cookie from the server. */ declare const createCookie: (name: string, cookieOptions?: CookieOptions) => Cookie; type IsCookieFunction = (object: any) => object is Cookie; /** * Returns true if an object is a Remix cookie container. * * @see https://remix.run/utils/cookies#iscookie */ declare const isCookie: IsCookieFunction; type RequestHandler = (request: Request, loadContext?: MiddlewareEnabled extends true ? unstable_RouterContextProvider : AppLoadContext) => Promise<Response>; type CreateRequestHandlerFunction = (build: ServerBuild | (() => ServerBuild | Promise<ServerBuild>), mode?: string) => RequestHandler; declare const createRequestHandler: CreateRequestHandlerFunction; /** * An object of name/value pairs to be used in the session. */ interface SessionData { [name: string]: any; } /** * Session persists data across HTTP requests. * * @see https://reactrouter.com/explanation/sessions-and-cookies#sessions */ interface Session<Data = SessionData, FlashData = Data> { /** * A unique identifier for this session. * * Note: This will be the empty string for newly created sessions and * sessions that are not backed by a database (i.e. cookie-based sessions). */ readonly id: string; /** * The raw data contained in this session. * * This is useful mostly for SessionStorage internally to access the raw * session data to persist. */ readonly data: FlashSessionData<Data, FlashData>; /** * Returns `true` if the session has a value for the given `name`, `false` * otherwise. */ has(name: (keyof Data | keyof FlashData) & string): boolean; /** * Returns the value for the given `name` in this session. */ get<Key extends (keyof Data | keyof FlashData) & string>(name: Key): (Key extends keyof Data ? Data[Key] : undefined) | (Key extends keyof FlashData ? FlashData[Key] : undefined) | undefined; /** * Sets a value in the session for the given `name`. */ set<Key extends keyof Data & string>(name: Key, value: Data[Key]): void; /** * Sets a value in the session that is only valid until the next `get()`. * This can be useful for temporary values, like error messages. */ flash<Key extends keyof FlashData & string>(name: Key, value: FlashData[Key]): void; /** * Removes a value from the session. */ unset(name: keyof Data & string): void; } type FlashSessionData<Data, FlashData> = Partial<Data & { [Key in keyof FlashData as FlashDataKey<Key & string>]: FlashData[Key]; }>; type FlashDataKey<Key extends string> = `__flash_${Key}__`; type CreateSessionFunction = <Data = SessionData, FlashData = Data>(initialData?: Data, id?: string) => Session<Data, FlashData>; /** * Creates a new Session object. * * Note: This function is typically not invoked directly by application code. * Instead, use a `SessionStorage` object's `getSession` method. */ declare const createSession: CreateSessionFunction; type IsSessionFunction = (object: any) => object is Session; /** * Returns true if an object is a React Router session. * * @see https://reactrouter.com/api/utils/isSession */ declare const isSession: IsSessionFunction; /** * SessionStorage stores session data between HTTP requests and knows how to * parse and create cookies. * * A SessionStorage creates Session objects using a `Cookie` header as input. * Then, later it generates the `Set-Cookie` header to be used in the response. */ interface SessionStorage<Data = SessionData, FlashData = Data> { /** * Parses a Cookie header from a HTTP request and returns the associated * Session. If there is no session associated with the cookie, this will * return a new Session with no data. */ getSession: (cookieHeader?: string | null, options?: ParseOptions) => Promise<Session<Data, FlashData>>; /** * Stores all data in the Session and returns the Set-Cookie header to be * used in the HTTP response. */ commitSession: (session: Session<Data, FlashData>, options?: SerializeOptions) => Promise<string>; /** * Deletes all data associated with the Session and returns the Set-Cookie * header to be used in the HTTP response. */ destroySession: (session: Session<Data, FlashData>, options?: SerializeOptions) => Promise<string>; } /** * SessionIdStorageStrategy is designed to allow anyone to easily build their * own SessionStorage using `createSessionStorage(strategy)`. * * This strategy describes a common scenario where the session id is stored in * a cookie but the actual session data is stored elsewhere, usually in a * database or on disk. A set of create, read, update, and delete operations * are provided for managing the session data. */ interface SessionIdStorageStrategy<Data = SessionData, FlashData = Data> { /** * The Cookie used to store the session id, or options used to automatically * create one. */ cookie?: Cookie | (CookieOptions & { name?: string; }); /** * Creates a new record with the given data and returns the session id. */ createData: (data: FlashSessionData<Data, FlashData>, expires?: Date) => Promise<string>; /** * Returns data for a given session id, or `null` if there isn't any. */ readData: (id: string) => Promise<FlashSessionData<Data, FlashData> | null>; /** * Updates data for the given session id. */ updateData: (id: string, data: FlashSessionData<Data, FlashData>, expires?: Date) => Promise<void>; /** * Deletes data for a given session id from the data store. */ deleteData: (id: string) => Promise<void>; } /** * Creates a SessionStorage object using a SessionIdStorageStrategy. * * Note: This is a low-level API that should only be used if none of the * existing session storage options meet your requirements. */ declare function createSessionStorage<Data = SessionData, FlashData = Data>({ cookie: cookieArg, createData, readData, updateData, deleteData, }: SessionIdStorageStrategy<Data, FlashData>): SessionStorage<Data, FlashData>; interface CookieSessionStorageOptions { /** * The Cookie used to store the session data on the client, or options used * to automatically create one. */ cookie?: SessionIdStorageStrategy["cookie"]; } /** * Creates and returns a SessionStorage object that stores all session data * directly in the session cookie itself. * * This has the advantage that no database or other backend services are * needed, and can help to simplify some load-balanced scenarios. However, it * also has the limitation that serialized session data may not exceed the * browser's maximum cookie size. Trade-offs! */ declare function createCookieSessionStorage<Data = SessionData, FlashData = Data>({ cookie: cookieArg }?: CookieSessionStorageOptions): SessionStorage<Data, FlashData>; interface MemorySessionStorageOptions { /** * The Cookie used to store the session id on the client, or options used * to automatically create one. */ cookie?: SessionIdStorageStrategy["cookie"]; } /** * Creates and returns a simple in-memory SessionStorage object, mostly useful * for testing and as a reference implementation. * * Note: This storage does not scale beyond a single process, so it is not * suitable for most production scenarios. */ declare function createMemorySessionStorage<Data = SessionData, FlashData = Data>({ cookie }?: MemorySessionStorageOptions): SessionStorage<Data, FlashData>; type DevServerHooks = { getCriticalCss?: (pathname: string) => Promise<string | undefined>; processRequestError?: (error: unknown) => void; }; declare function setDevServerHooks(devServerHooks: DevServerHooks): void; type Args = { [K in keyof Pages]: ToArgs<Pages[K]["params"]>; }; type ToArgs<Params extends Record<string, string | undefined>> = Equal<Params, {}> extends true ? [] : Partial<Params> extends Params ? [Params] | [] : [ Params ]; /** Returns a resolved URL path for the specified route. ```tsx const h = href("/:lang?/about", { lang: "en" }) // -> `/en/about` <Link to={href("/products/:id", { id: "abc123" })} /> ``` */ declare function href<Path extends keyof Args>(path: Path, ...args: Args[Path]): string; type RSCRouteConfigEntryBase = { action?: ActionFunction; clientAction?: ClientActionFunction; clientLoader?: ClientLoaderFunction; ErrorBoundary?: React.ComponentType<any>; handle?: any; headers?: HeadersFunction; HydrateFallback?: React.ComponentType<any>; Layout?: React.ComponentType<any>; links?: LinksFunction; loader?: LoaderFunction; meta?: MetaFunction; shouldRevalidate?: ShouldRevalidateFunction; }; type RSCRouteConfigEntry = RSCRouteConfigEntryBase & { id: string; path?: string; Component?: React.ComponentType<any>; lazy?: () => Promise<RSCRouteConfigEntryBase & ({ default?: React.ComponentType<any>; Component?: never; } | { default?: never; Component?: React.ComponentType<any>; })>; } & ({ index: true; } | { children?: RSCRouteConfigEntry[]; }); type RSCRouteConfig = Array<RSCRouteConfigEntry>; type RSCRouteManifest = { clientAction?: ClientActionFunction; clientLoader?: ClientLoaderFunction; element?: React.ReactElement | false; errorElement?: React.ReactElement; handle?: any; hasAction: boolean; hasComponent: boolean; hasErrorBoundary: boolean; hasLoader: boolean; hydrateFallbackElement?: React.ReactElement; id: string; index?: boolean; links?: LinksFunction; meta?: MetaFunction; parentId?: string; path?: string; shouldRevalidate?: ShouldRevalidateFunction; }; type RSCRouteMatch = RSCRouteManifest & { params: Params; pathname: string; pathnameBase: string; }; type RSCRenderPayload = { type: "render"; actionData: Record<string, any> | null; basename: string | undefined; errors: Record<string, any> | null; loaderData: Record<string, any>; location: Location; matches: RSCRouteMatch[]; patches?: RSCRouteManifest[]; nonce?: string; formState?: unknown; }; type RSCManifestPayload = { type: "manifest"; patches: RSCRouteManifest[]; }; type RSCActionPayload = { type: "action"; actionResult: Promise<unknown>; rerender?: Promise<RSCRenderPayload | RSCRedirectPayload>; }; type RSCRedirectPayload = { type: "redirect"; status: number; location: string; replace: boolean; reload: boolean; actionResult?: Promise<unknown>; }; type RSCPayload = RSCRenderPayload | RSCManifestPayload | RSCActionPayload | RSCRedirectPayload; type RSCMatch = { statusCode: number; headers: Headers; payload: RSCPayload; }; type DecodeActionFunction = (formData: FormData) => Promise<() => Promise<unknown>>; type DecodeFormStateFunction = (result: unknown, formData: FormData) => unknown; type DecodeReplyFunction = (reply: FormData | string, { temporaryReferences }: { temporaryReferences: unknown; }) => Promise<unknown[]>; type LoadServerActionFunction = (id: string) => Promise<Function>; /** * Matches the given routes to a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) * and returns an [RSC](https://react.dev/reference/rsc/server-components) * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) * encoding an {@link unstable_RSCPayload} for consumption by an [RSC](https://react.dev/reference/rsc/server-components) * enabled client router. * * @example * import { * createTemporaryReferenceSet, * decodeAction, * decodeReply, * loadServerAction, * renderToReadableStream, * } from "@vitejs/plugin-rsc/rsc"; * import { unstable_matchRSCServerRequest as matchRSCServerRequest } from "react-router"; * * matchRSCServerRequest({ * createTemporaryReferenceSet, * decodeAction, * decodeFormState, * decodeReply, * loadServerAction, * request, * routes: routes(), * generateResponse(match) { * return new Response( * renderToReadableStream(match.payload), * { * status: match.statusCode, * headers: match.headers, * } * ); * }, * }); * * @name unstable_matchRSCServerRequest * @public * @category RSC * @mode data * @param opts Options * @param opts.basename The basename to use when matching the request. * @param opts.createTemporaryReferenceSet A function that returns a temporary * reference set for the request, used to track temporary references in the [RSC](https://react.dev/reference/rsc/server-components) * stream. * @param opts.decodeAction Your `react-server-dom-xyz/server`'s `decodeAction` * function, responsible for loading a server action. * @param opts.decodeFormState A function responsible for decoding form state for * progressively enhanceable forms with React's [`useActionState`](https://react.dev/reference/react/useActionState) * using your `react-server-dom-xyz/server`'s `decodeFormState`. * @param opts.decodeReply Your `react-server-dom-xyz/server`'s `decodeReply` * function, used to decode the server function's arguments and bind them to the * implementation for invocation by the router. * @param opts.generateResponse A function responsible for using your * `renderToReadableStream` to generate a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) * encoding the {@link unstable_RSCPayload}. * @param opts.loadServerAction Your `react-server-dom-xyz/server`'s * `loadServerAction` function, used to load a server action by ID. * @param opts.onError An optional error handler that will be called with any * errors that occur during the request processing. * @param opts.request The [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) * to match against. * @param opts.requestContext An instance of {@link unstable_RouterContextProvider} * that should be created per request, to be passed to [`action`](../../start/data/route-object#action)s, * [`loader`](../../start/data/route-object#loader)s and [middleware](../../how-to/middleware). * @param opts.routes Your {@link unstable_RSCRouteConfigEntry | route definitions}. * @returns A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) * that contains the [RSC](https://react.dev/reference/rsc/server-components) * data for hydration. */ declare function matchRSCServerRequest({ createTempor