diff --git a/packages/react-router/src/Scripts.tsx b/packages/react-router/src/Scripts.tsx index 28c05bf2749..96f700eff78 100644 --- a/packages/react-router/src/Scripts.tsx +++ b/packages/react-router/src/Scripts.tsx @@ -3,6 +3,10 @@ import { useRouterState } from './useRouterState' import { useRouter } from './useRouter' import type { RouterManagedTag } from '@tanstack/router-core' +/** + * Render body script tags collected from route matches and SSR manifests. + * Should be placed near the end of the document body. + */ export const Scripts = () => { const router = useRouter() const nonce = router.options.ssr?.nonce diff --git a/packages/react-router/src/ScrollRestoration.tsx b/packages/react-router/src/ScrollRestoration.tsx index 71d472723de..55591c92cee 100644 --- a/packages/react-router/src/ScrollRestoration.tsx +++ b/packages/react-router/src/ScrollRestoration.tsx @@ -17,7 +17,7 @@ function useScrollRestoration() { } /** - * @deprecated use createRouter's `scrollRestoration` option instead + * @deprecated Use the `scrollRestoration` router option instead. */ export function ScrollRestoration(_props: ScrollRestorationOptions) { useScrollRestoration() diff --git a/packages/react-router/src/awaited.tsx b/packages/react-router/src/awaited.tsx index f695b33e8c5..d177288781d 100644 --- a/packages/react-router/src/awaited.tsx +++ b/packages/react-router/src/awaited.tsx @@ -7,6 +7,7 @@ export type AwaitOptions = { promise: Promise } +/** Suspend until a deferred promise resolves/rejects and return its data. */ export function useAwaited({ promise: _promise, }: AwaitOptions): [T, DeferredPromise] { @@ -23,6 +24,10 @@ export function useAwaited({ return [promise[TSR_DEFERRED_PROMISE].data, promise] } +/** + * Component that suspends on a deferred promise and renders its child with + * the resolved value. Optionally provides a Suspense fallback. + */ export function Await( props: AwaitOptions & { fallback?: React.ReactNode diff --git a/packages/react-router/src/route.tsx b/packages/react-router/src/route.tsx index 0aefd3673eb..3fb7716e7a5 100644 --- a/packages/react-router/src/route.tsx +++ b/packages/react-router/src/route.tsx @@ -78,24 +78,6 @@ declare module '@tanstack/router-core' { } } -/** - * Returns a route-specific API that exposes type-safe hooks pre-bound - * to a single route ID. Useful for consuming a route's APIs from files - * where the route object isn't directly imported (e.g. code-split files). - * - * @param id Route ID string literal for the target route. - * @returns A `RouteApi` instance bound to the given route ID. - * @link https://tanstack.com/router/latest/docs/framework/react/api/router/getRouteApiFunction - */ -/** - * Returns a route-specific API that exposes type-safe hooks pre-bound - * to a single route ID. Useful for consuming a route's APIs from files - * where the route object isn't directly imported (e.g. code-split files). - * - * @param id Route ID string literal for the target route. - * @returns A `RouteApi` instance bound to the given route ID. - * @link https://tanstack.com/router/latest/docs/framework/react/api/router/getRouteApiFunction - */ /** * Returns a route-specific API that exposes type-safe hooks pre-bound * to a single route ID. Useful for consuming a route's APIs from files diff --git a/packages/react-router/src/useRouter.tsx b/packages/react-router/src/useRouter.tsx index 1eadfb68b5a..abfefecaa3e 100644 --- a/packages/react-router/src/useRouter.tsx +++ b/packages/react-router/src/useRouter.tsx @@ -3,16 +3,6 @@ import warning from 'tiny-warning' import { getRouterContext } from './routerContext' import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core' -/** - * Access the current TanStack Router instance from React context. - * Must be used within a `RouterProvider`. - * - * Options: - * - `warn`: Log a warning if no router context is found (default: true). - * - * @returns The registered router instance. - * @link https://tanstack.com/router/latest/docs/framework/react/api/router/useRouterHook - */ /** * Access the current TanStack Router instance from React context. * Must be used within a `RouterProvider`. diff --git a/packages/router-core/src/path.ts b/packages/router-core/src/path.ts index 1c3b6341cf3..edb5a8d22cb 100644 --- a/packages/router-core/src/path.ts +++ b/packages/router-core/src/path.ts @@ -22,6 +22,7 @@ export interface Segment { readonly hasStaticAfter?: boolean } +/** Join path segments, cleaning duplicate slashes between parts. */ export function joinPaths(paths: Array) { return cleanPath( paths @@ -32,23 +33,28 @@ export function joinPaths(paths: Array) { ) } +/** Remove repeated slashes from a path string. */ export function cleanPath(path: string) { // remove double slashes return path.replace(/\/{2,}/g, '/') } +/** Trim leading slashes (except preserving root '/'). */ export function trimPathLeft(path: string) { return path === '/' ? path : path.replace(/^\/{1,}/, '') } +/** Trim trailing slashes (except preserving root '/'). */ export function trimPathRight(path: string) { return path === '/' ? path : path.replace(/\/{1,}$/, '') } +/** Trim both leading and trailing slashes. */ export function trimPath(path: string) { return trimPathRight(trimPathLeft(path)) } +/** Remove a trailing slash from value when appropriate for comparisons. */ export function removeTrailingSlash(value: string, basepath: string): string { if (value?.endsWith('/') && value !== '/' && value !== `${basepath}/`) { return value.slice(0, -1) @@ -149,6 +155,10 @@ function segmentToString(segment: Segment): string { return value } +/** + * Resolve a destination path against a base, honoring trailing-slash policy + * and supporting relative segments (`.`/`..`) and absolute `to` values. + */ export function resolvePath({ base, to, @@ -384,6 +394,13 @@ type InterPolatePathResult = { usedParams: Record isMissingParams: boolean // true if any params were not available when being looked up in the params object } +/** + * Interpolate params and wildcards into a route path template. + * + * - Encodes params safely (configurable allowed characters) + * - Supports `{-$optional}` segments, `{prefix{$id}suffix}` and `{$}` wildcards + * - Optionally leaves placeholders or wildcards in place + */ export function interpolatePath({ path, params, @@ -510,6 +527,10 @@ function encodePathParam(value: string, decodeCharMap?: Map) { return encoded } +/** + * Match a pathname against a route destination and return extracted params + * or `undefined`. Uses the same parsing as the router for consistency. + */ export function matchPathname( currentPathname: string, matchLocation: Pick, @@ -525,6 +546,7 @@ export function matchPathname( return pathParams ?? {} } +/** Low-level matcher that compares two path strings and extracts params. */ export function matchByPath( from: string, { diff --git a/packages/router-core/src/qss.ts b/packages/router-core/src/qss.ts index 550a5b0cea5..15b7728dd35 100644 --- a/packages/router-core/src/qss.ts +++ b/packages/router-core/src/qss.ts @@ -22,6 +22,7 @@ * // Expected output: "token=foo&key=value" * ``` */ +/** Encode a plain object into a URL query string using URLSearchParams. */ export function encode( obj: Record, stringify: (value: any) => string = String, @@ -62,6 +63,7 @@ function toValue(str: unknown) { * // Example input: decode("token=foo&key=value") * // Expected output: { "token": "foo", "key": "value" } */ +/** Decode a URL query string into an object with basic type coercion. */ export function decode(str: any): any { const searchParams = new URLSearchParams(str) diff --git a/packages/router-core/src/redirect.ts b/packages/router-core/src/redirect.ts index 277d184b4b2..4672bf3febf 100644 --- a/packages/router-core/src/redirect.ts +++ b/packages/router-core/src/redirect.ts @@ -114,12 +114,14 @@ export function isRedirect(obj: any): obj is AnyRedirect { return obj instanceof Response && !!(obj as any).options } +/** True if value is a redirect with a resolved `href` location. */ export function isResolvedRedirect( obj: any, ): obj is AnyRedirect & { options: { href: string } } { return isRedirect(obj) && !!obj.options.href } +/** Parse a serialized redirect object back into a redirect Response. */ export function parseRedirect(obj: any) { if (obj !== null && typeof obj === 'object' && obj.isSerializedRedirect) { return redirect(obj) diff --git a/packages/router-core/src/rewrite.ts b/packages/router-core/src/rewrite.ts index 7ffb49b8e15..452bf98b13d 100644 --- a/packages/router-core/src/rewrite.ts +++ b/packages/router-core/src/rewrite.ts @@ -1,6 +1,7 @@ import { joinPaths, trimPath } from './path' import type { LocationRewrite } from './router' +/** Compose multiple rewrite pairs into a single in/out rewrite. */ export function composeRewrites(rewrites: Array) { return { input: ({ url }) => { @@ -18,6 +19,7 @@ export function composeRewrites(rewrites: Array) { } satisfies LocationRewrite } +/** Create a rewrite pair that strips/adds a basepath on input/output. */ export function rewriteBasepath(opts: { basepath: string caseSensitive?: boolean @@ -54,6 +56,7 @@ export function rewriteBasepath(opts: { } satisfies LocationRewrite } +/** Execute a location input rewrite if provided. */ export function executeRewriteInput( rewrite: LocationRewrite | undefined, url: URL, @@ -69,6 +72,7 @@ export function executeRewriteInput( return url } +/** Execute a location output rewrite if provided. */ export function executeRewriteOutput( rewrite: LocationRewrite | undefined, url: URL, diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index df01f7a8356..9ff9eb3dca6 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -842,6 +842,15 @@ export type CreateRouterFn = < TDehydrated > +/** + * Core, framework-agnostic router engine that powers TanStack Router. + * + * Provides navigation, matching, loading, preloading, caching and event APIs + * used by framework adapters (React/Solid). Prefer framework helpers like + * `createRouter` in app code. + * + * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType + */ export class RouterCore< in out TRouteTree extends AnyRoute, in out TTrailingSlashOption extends TrailingSlashOption, @@ -1096,6 +1105,12 @@ export class RouterCore< } } + /** + * Subscribe to router lifecycle events like `onBeforeNavigate`, `onLoad`, + * `onResolved`, etc. Returns an unsubscribe function. + * + * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterEventsType + */ subscribe: SubscribeFn = (eventType, fn) => { const listener: RouterListener = { eventType, @@ -1117,6 +1132,10 @@ export class RouterCore< }) } + /** + * Parse a HistoryLocation into a strongly-typed ParsedLocation using the + * current router options, rewrite rules and search parser/stringifier. + */ parseLocation: ParseLocationFn = ( locationToParse, previousLocation, @@ -1172,6 +1191,7 @@ export class RouterCore< return location } + /** Resolve a path against the router basepath and trailing-slash policy. */ resolvePathWithBase = (from: string, path: string) => { const resolvedPath = resolvePath({ base: from, @@ -1538,6 +1558,13 @@ export class RouterCore< }) } + /** + * Build the next ParsedLocation from navigation options without committing. + * Resolves `to`/`from`, params/search/hash/state, applies search validation + * and middlewares, and returns a stable, stringified location object. + * + * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType#buildlocation-method + */ buildLocation: BuildLocationFn = (opts) => { const build = ( dest: BuildNextOptions & { @@ -1785,6 +1812,10 @@ export class RouterCore< commitLocationPromise: undefined | ControlledPromise + /** + * Commit a previously built location to history (push/replace), optionally + * using view transitions and scroll restoration options. + */ commitLocation: CommitLocationFn = ({ viewTransition, ignoreBlocker, @@ -1875,6 +1906,7 @@ export class RouterCore< return this.commitLocationPromise } + /** Convenience helper: build a location from options, then commit it. */ buildAndCommitLocation = ({ replace, resetScroll, @@ -1911,6 +1943,13 @@ export class RouterCore< }) } + /** + * Imperatively navigate using standard `NavigateOptions`. When `reloadDocument` + * or an absolute `href` is provided, performs a full document navigation. + * Otherwise, builds and commits a client-side location. + * + * @link https://tanstack.com/router/latest/docs/framework/react/api/router/NavigateOptionsType + */ navigate: NavigateFn = ({ to, reloadDocument, href, ...rest }) => { if (!reloadDocument && href) { try { diff --git a/packages/router-core/src/scroll-restoration.ts b/packages/router-core/src/scroll-restoration.ts index d662a654b80..cc6432221ce 100644 --- a/packages/router-core/src/scroll-restoration.ts +++ b/packages/router-core/src/scroll-restoration.ts @@ -33,6 +33,7 @@ function getSafeSessionStorage() { return undefined } +/** SessionStorage key used to persist scroll restoration state. */ export const storageKey = 'tsr-scroll-restoration-v1_3' const throttle = (fn: (...args: Array) => void, wait: number) => { @@ -70,6 +71,7 @@ function createScrollRestorationCache(): ScrollRestorationCache | null { } } +/** In-memory handle to the persisted scroll restoration cache. */ export const scrollRestorationCache = createScrollRestorationCache() /** @@ -79,10 +81,14 @@ export const scrollRestorationCache = createScrollRestorationCache() * The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render. */ +/** + * Default scroll restoration cache key: location state key or full href. + */ export const defaultGetScrollRestorationKey = (location: ParsedLocation) => { return location.state.__TSR_key! || location.href } +/** Best-effort nth-child CSS selector for a given element. */ export function getCssSelector(el: any): string { const path = [] let parent: HTMLElement @@ -101,6 +107,9 @@ let ignoreScroll = false // unless they are passed in as arguments. Why? Because we need to be able to // toString() it into a script tag to execute as early as possible in the browser // during SSR. Additionally, we also call it from within the router lifecycle +/** + * Restore scroll positions for window/elements based on cached entries. + */ export function restoreScroll({ storageKey, key, @@ -200,6 +209,7 @@ export function restoreScroll({ ignoreScroll = false } +/** Setup global listeners and hooks to support scroll restoration. */ export function setupScrollRestoration(router: AnyRouter, force?: boolean) { if (!scrollRestorationCache && !router.isServer) { return @@ -357,6 +367,14 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) { }) } +/** + * @private + * Handles hash-based scrolling after navigation completes. + * To be used in framework-specific components during the onResolved event. + * + * Provides hash scrolling for programmatic navigation when default browser handling is prevented. + * @param router The router instance containing current location and state + */ /** * @private * Handles hash-based scrolling after navigation completes. diff --git a/packages/router-core/src/searchMiddleware.ts b/packages/router-core/src/searchMiddleware.ts index e90d453350f..32d672348ea 100644 --- a/packages/router-core/src/searchMiddleware.ts +++ b/packages/router-core/src/searchMiddleware.ts @@ -13,6 +13,9 @@ import type { IsRequiredParams } from './link' * @returns A search middleware suitable for route `search.middlewares`. * @link https://tanstack.com/router/latest/docs/framework/react/api/router/retainSearchParamsFunction */ +/** + * Retain specified search params across navigations by merging prior values. + */ export function retainSearchParams( keys: Array | true, ): SearchMiddleware { @@ -41,6 +44,9 @@ export function retainSearchParams( * @returns A search middleware suitable for route `search.middlewares`. * @link https://tanstack.com/router/latest/docs/framework/react/api/router/stripSearchParamsFunction */ +/** + * Remove optional/default-valued search params from navigations. + */ export function stripSearchParams< TSearchSchema, TOptionalProps = PickOptional>, diff --git a/packages/router-core/src/searchParams.ts b/packages/router-core/src/searchParams.ts index f36d8e490a6..f8b9205bebf 100644 --- a/packages/router-core/src/searchParams.ts +++ b/packages/router-core/src/searchParams.ts @@ -1,6 +1,7 @@ import { decode, encode } from './qss' import type { AnySchema } from './validators' +/** Default `parseSearch` that strips leading '?' and JSON-parses values. */ export const defaultParseSearch = parseSearchWith(JSON.parse) export const defaultStringifySearch = stringifySearchWith( JSON.stringify, @@ -17,6 +18,7 @@ export const defaultStringifySearch = stringifySearchWith( * @returns A `parseSearch` function compatible with `Router` options. * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization */ +/** Build a parseSearch function using a provided JSON-like parser. */ export function parseSearchWith(parser: (str: string) => any) { return (searchStr: string): AnySchema => { if (searchStr[0] === '?') { @@ -53,6 +55,7 @@ export function parseSearchWith(parser: (str: string) => any) { * @returns A `stringifySearch` function compatible with `Router` options. * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization */ +/** Build a stringifySearch function using a provided serializer/parser. */ export function stringifySearchWith( stringify: (search: any) => string, parser?: (str: string) => any,