Repository: TanStack/router
Pull request #3082 (2024-12-27 11:37:28)

fix(start): fixed route scripts filtering
The filtering before is like:

```ts
// ...
select: (state) => {
  // Assume here:
  // `[[undefined], undefined]`
  const scriptsOfEachMatch = state.matches.map((match) => match.scripts)
  // Filtered:
  // `[[undefined]]`
  const truthyScriptsOfEachMatch = scriptsOfEachMatch.filter(Boolean)
  // Turns out to be:
  // `[undefined]`
  // which will cause `TypeError` when `undefined` gets destructured below
  const truthyScripts = truthyScriptsOfEachMatch.flat(1)

  return {
    scripts: truthyScripts.map(({ children, ...script }) => ({ // <- TypeError: Cannot destructure property 'children' of 'undefined' as it is undefined.
      // ...
    })),
  }
},
// ...
```

Which will cause error when specifying `scripts` like:

```ts
export const Route = createRootRoute({
  head: () => ({
    // ...
    scripts: [undefined], // Passes type check but will panic at runtime
  }),
  // ...
})
```

This PR moves the `filter(Boolean)` after flattening. But I'm not sure if the following patterns are equivalent:

```js
arr.filter(Boolean).flat(1).filter(Boolean) // Semantically correct

arr.flat(1).filter(Boolean) // Less code
```


schiller-manuel: we need an e2e test for this
3fuyang: Hi @schiller-manuel, it seems the existing e2e are all related to examples, so I'm not sure where to put the e2e case for this. But I found the `start` package already includes unit tests for `scripts`, so I added it there instead. PTAL

Patch:
diff --git a/docs/config.json b/docs/config.json
index 4fff93b1a..0daed8d5b 100644
--- a/docs/config.json
+++ b/docs/config.json
@@ -199,6 +199,18 @@
               "label": "Getting Started",
               "to": "framework/react/start/getting-started"
             },
+            {
+              "label": "Quick Start",
+              "to": "framework/react/start/quick-start"
+            },
+            {
+              "label": "Build from Scratch",
+              "to": "framework/react/start/build-from-scratch"
+            },
+            {
+              "label": "Learn the Basics",
+              "to": "framework/react/start/learn-the-basics"
+            },
             {
               "label": "Server Functions",
               "to": "framework/react/start/server-functions"
diff --git a/docs/framework/react/start/build-from-scratch.md b/docs/framework/react/start/build-from-scratch.md
new file mode 100644
index 000000000..931fd5e45
--- /dev/null
+++ b/docs/framework/react/start/build-from-scratch.md
@@ -0,0 +1,305 @@
+---
+id: build-from-scratch
+title: Build a Project from Scratch
+---
+
+> [!NOTE]
+> If you chose to quick start with an example or cloned project, you can skip this guide and move on to the [Learn the Basics](../learn-the-basics) guide.
+
+_So you want to build a TanStack Start project from scratch?_
+
+This guide will help you build a **very** basic TanStack Start web application. Together, we will use TanStack Start to:
+
+- Serve an index page...
+- Which displays a counter...
+- With a button to increment the counter persistently.
+
+[Here is what that will look like](https://stackblitz.com/github/tanstack/router/tree/main/examples/react/start-counter)
+
+Let's create a new project directory and initialize it.
+
+```shell
+mkdir myApp
+cd myApp
+npm init -y
+```
+
+## TypeScript Configuration
+
+We highly recommend using TypeScript with TanStack Start. Create a `tsconfig.json` file with at least the following settings:
+
+```jsonc
+{
+  "compilerOptions": {
+    "jsx": "react-jsx",
+    "moduleResolution": "Bundler",
+    "module": "ESNext",
+    "target": "ES2022",
+    "skipLibCheck": true,
+    "strictNullChecks": true,
+  },
+}
+```
+
+## Install Dependencies
+
+TanStack Start is (currently\*) powered by [Vinxi](https://vinxi.vercel.app/) and [TanStack Router](https://tanstack.com/router) and requires them as dependencies.
+
+> [!NOTE] > \*Vinxi will be removed before version 1.0.0 is released and TanStack will rely only on Vite and Nitro. The commands and APIs that use Vinxi will likely be replaced with a Vite plugin.
+
+To install them, run:
+
+```shell
+npm i @tanstack/start @tanstack/react-router vinxi
+```
+
+You'll also need React and the Vite React plugin, so install them too:
+
+```shell
+npm i react react-dom; npm i -D @vitejs/plugin-react
+```
+
+and some TypeScript:
+
+```shell
+npm i -D typescript @types/react @types/react-dom
+```
+
+## Update Configuration Files
+
+We'll then update our `package.json` to reference the new Vinxi entry point and set `"type": "module"`:
+
+```json
+{
+  // ...
+  "type": "module",
+  "scripts": {
+    "dev": "vinxi dev",
+    "build": "vinxi build",
+    "start": "vinxi start"
+  }
+}
+```
+
+To tell Vinxi that it should start TanStack Start's minimal behavior, we need to configure the `app.config.ts` file:
+
+```typescript
+// app.config.ts
+import { defineConfig } from '@tanstack/start/config'
+
+export default defineConfig({})
+```
+
+## Add the Basic Templating
+
+There are four required files for TanStack Start usage:
+
+1. The router configuration
+2. The server entry point
+3. The client entry point
+4. The root of your application
+
+Once configuration is done, we'll have a file tree that looks like the following:
+
+```
+.
+├── app/
+│   ├── routes/
+│   │   └── `__root.tsx`
+│   ├── `client.tsx`
+│   ├── `router.tsx`
+│   ├── `routeTree.gen.ts`
+│   └── `ssr.tsx`
+├── `.gitignore`
+├── `app.config.ts`
+├── `package.json`
+└── `tsconfig.json`
+```
+
+## The Router Configuration
+
+This is the file that will dictate the behavior of TanStack Router used within Start. Here, you can configure everything
+from the default [preloading functionality](../guide/preloading.md) to [caching staleness](../guide/data-loading.md).
+
+```tsx
+// app/router.tsx
+import { createRouter as createTanStackRouter } from '@tanstack/react-router'
+import { routeTree } from './routeTree.gen'
+
+export function createRouter() {
+  const router = createTanStackRouter({
+    routeTree,
+  })
+
+  return router
+}
+
+declare module '@tanstack/react-router' {
+  interface Register {
+    router: ReturnType<typeof createRouter>
+  }
+}
+```
+
+> `routeTree.gen.ts` is not a file you're expected to have at this point.
+> It will be generated when you run TanStack Start (via `npm run dev` or `npm run start`) for the first time.
+
+## The Server Entry Point
+
+As TanStack Start is an [SSR](https://unicorn-utterances.com/posts/what-is-ssr-and-ssg) framework, we need to pipe this router
+information to our server entry point:
+
+```tsx
+// app/ssr.tsx
+/// <reference types="vinxi/types/server" />
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/start/server'
+import { getRouterManifest } from '@tanstack/start/router-manifest'
+
+import { createRouter } from './router'
+
+export default createStartHandler({
+  createRouter,
+  getRouterManifest,
+})(defaultStreamHandler)
+```
+
+This allows us to know what routes and loaders we need to execute when the user hits a given route.
+
+## The Client Entry Point
+
+Now we need a way to hydrate our client-side JavaScript once the route resolves to the client. We do this by piping the same
+router information to our client entry point:
+
+```tsx
+// app/client.tsx
+/// <reference types="vinxi/types/client" />
+import { hydrateRoot } from 'react-dom/client'
+import { StartClient } from '@tanstack/start'
+import { createRouter } from './router'
+
+const router = createRouter()
+
+hydrateRoot(document, <StartClient router={router} />)
+```
+
+This enables us to kick off client-side routing once the user's initial server request has fulfilled.
+
+## The Root of Your Application
+
+Finally, we need to create the root of our application. This is the entry point for all other routes. The code in this file will wrap all other routes in the application.
+
+```tsx
+// app/routes/__root.tsx
+import {
+  Outlet,
+  ScrollRestoration,
+  createRootRoute,
+} from '@tanstack/react-router'
+import { Meta, Scripts } from '@tanstack/start'
+import type { ReactNode } from 'react'
+
+export const Route = createRootRoute({
+  head: () => ({
+    meta: [
+      {
+        charSet: 'utf-8',
+      },
+      {
+        name: 'viewport',
+        content: 'width=device-width, initial-scale=1',
+      },
+      {
+        title: 'TanStack Start Starter',
+      },
+    ],
+  }),
+  component: RootComponent,
+})
+
+function RootComponent() {
+  return (
+    <RootDocument>
+      <Outlet />
+    </RootDocument>
+  )
+}
+
+function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
+  return (
+    <html>
+      <head>
+        <Meta />
+      </head>
+      <body>
+        {children}
+        <ScrollRestoration />
+        <Scripts />
+      </body>
+    </html>
+  )
+}
+```
+
+## Writing Your First Route
+
+Now that we have the basic templating setup, we can write our first route. This is done by creating a new file in the `app/routes` directory.
+
+```tsx
+// app/routes/index.tsx
+import * as fs from 'node:fs'
+import { createFileRoute, useRouter } from '@tanstack/react-router'
+import { createServerFn } from '@tanstack/start'
+
+const filePath = 'count.txt'
+
+async function readCount() {
+  return parseInt(
+    await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
+  )
+}
+
+const getCount = createServerFn({
+  method: 'GET',
+}).handler(() => {
+  return readCount()
+})
+
+const updateCount = createServerFn({ method: 'POST' })
+  .validator((d: number) => d)
+  .handler(async ({ data }) => {
+    const count = await readCount()
+    await fs.promises.writeFile(filePath, `${count + data}`)
+  })
+
+export const Route = createFileRoute('/')({
+  component: Home,
+  loader: async () => await getCount(),
+})
+
+function Home() {
+  const router = useRouter()
+  const state = Route.useLoaderData()
+
+  return (
+    <button
+      type="button"
+      onClick={() => {
+        updateCount({ data: 1 }).then(() => {
+          router.invalidate()
+        })
+      }}
+    >
+      Add 1 to {state}?
+    </button>
+  )
+}
+```
+
+That's it! 🤯 You've now set up a TanStack Start project and written your first route. 🎉
+
+You can now run `npm run dev` to start your server and navigate to `http://localhost:3000` to see your route in action.
+
+You want to deploy your application? Check out the [hosting guide](./hosting.md).
diff --git a/docs/framework/react/start/getting-started.md b/docs/framework/react/start/getting-started.md
index 7bb21ba00..f960fd9fe 100644
--- a/docs/framework/react/start/getting-started.md
+++ b/docs/framework/react/start/getting-started.md
@@ -3,300 +3,9 @@ id: getting-started
 title: Getting Started
 ---
 
-To set up a TanStack Start project, you'll need to:
+To set up a TanStack Start project, you can:
 
-1. Install the dependencies
-2. Add a configuration file
-3. Create required templating
+<!-- - Use the [TanStack Start CLI](https://github.com/tanstack/start/tree/main/packages/start-cli) to generate a new project and learn as you go -->
 
-Follow this guide to build a basic TanStack Start web application. Together, we will use TanStack Start to:
-
-- Serve an index page...
-- Which displays a counter...
-- With a button to increment the counter persistently.
-
-[Here is what that will look like](https://stackblitz.com/github/tanstack/router/tree/main/examples/react/start-counter)
-
-Create a new project if you're starting fresh.
-
-```shell
-mkdir myApp
-cd myApp
-npm init -y
-```
-
-Create a `tsconfig.json` file with at least the following settings:
-
-```jsonc
-{
-  "compilerOptions": {
-    "jsx": "react-jsx",
-    "moduleResolution": "Bundler",
-    "module": "ESNext",
-    "target": "ES2022",
-    "skipLibCheck": true,
-    "strictNullChecks": true,
-  },
-}
-```
-
-## Install Dependencies
-
-TanStack Start is powered by [Vinxi](https://vinxi.vercel.app/) and [TanStack Router](https://tanstack.com/router) and requires them as dependencies.
-
-To install them, run:
-
-```shell
-npm i @tanstack/start @tanstack/react-router vinxi
-```
-
-You'll also need React and the Vite React plugin, so install them too:
-
-```shell
-npm i react react-dom; npm i -D @vitejs/plugin-react
-```
-
-and some TypeScript:
-
-```shell
-npm i -D typescript @types/react @types/react-dom
-```
-
-## Update Configuration Files
-
-We'll then update our `package.json` to reference the new Vinxi entry point and set `"type": "module"`:
-
-```json
-{
-  // ...
-  "type": "module",
-  "scripts": {
-    "dev": "vinxi dev",
-    "build": "vinxi build",
-    "start": "vinxi start"
-  }
-}
-```
-
-To tell Vinxi that it should start TanStack Start's minimal behavior, we need to configure the `app.config.ts` file:
-
-```typescript
-// app.config.ts
-import { defineConfig } from '@tanstack/start/config'
-
-export default defineConfig({})
-```
-
-## Add the Basic Templating
-
-There are four required files for TanStack Start usage:
-
-1. The router configuration
-2. The server entry point
-3. The client entry point
-4. The root of your application
-
-Once configuration is done, we'll have a file tree that looks like the following:
-
-```
-.
-├── app/
-│   ├── routes/
-│   │   └── `__root.tsx`
-│   ├── `client.tsx`
-│   ├── `router.tsx`
-│   ├── `routeTree.gen.ts`
-│   └── `ssr.tsx`
-├── `.gitignore`
-├── `app.config.ts`
-├── `package.json`
-└── `tsconfig.json`
-```
-
-## The Router Configuration
-
-This is the file that will dictate the behavior of TanStack Router used within Start. Here, you can configure everything
-from the default [preloading functionality](../guide/preloading.md) to [caching staleness](../guide/data-loading.md).
-
-```tsx
-// app/router.tsx
-import { createRouter as createTanStackRouter } from '@tanstack/react-router'
-import { routeTree } from './routeTree.gen'
-
-export function createRouter() {
-  const router = createTanStackRouter({
-    routeTree,
-  })
-
-  return router
-}
-
-declare module '@tanstack/react-router' {
-  interface Register {
-    router: ReturnType<typeof createRouter>
-  }
-}
-```
-
-> `routeTree.gen.ts` is not a file you're expected to have at this point.
-> It will be generated when you run TanStack Start (via `npm run dev` or `npm run start`) for the first time.
-
-## The Server Entry Point
-
-As TanStack Start is an [SSR](https://unicorn-utterances.com/posts/what-is-ssr-and-ssg) framework, we need to pipe this router
-information to our server entry point:
-
-```tsx
-// app/ssr.tsx
-/// <reference types="vinxi/types/server" />
-import {
-  createStartHandler,
-  defaultStreamHandler,
-} from '@tanstack/start/server'
-import { getRouterManifest } from '@tanstack/start/router-manifest'
-
-import { createRouter } from './router'
-
-export default createStartHandler({
-  createRouter,
-  getRouterManifest,
-})(defaultStreamHandler)
-```
-
-This allows us to know what routes and loaders we need to execute when the user hits a given route.
-
-## The Client Entry Point
-
-Now we need a way to hydrate our client-side JavaScript once the route resolves to the client. We do this by piping the same
-router information to our client entry point:
-
-```tsx
-// app/client.tsx
-/// <reference types="vinxi/types/client" />
-import { hydrateRoot } from 'react-dom/client'
-import { StartClient } from '@tanstack/start'
-import { createRouter } from './router'
-
-const router = createRouter()
-
-hydrateRoot(document, <StartClient router={router} />)
-```
-
-This enables us to kick off client-side routing once the user's initial server request has fulfilled.
-
-## The Root of Your Application
-
-Finally, we need to create the root of our application. This is the entry point for all other routes. The code in this file will wrap all other routes in the application.
-
-```tsx
-// app/routes/__root.tsx
-import {
-  Outlet,
-  ScrollRestoration,
-  createRootRoute,
-} from '@tanstack/react-router'
-import { Meta, Scripts } from '@tanstack/start'
-import type { ReactNode } from 'react'
-
-export const Route = createRootRoute({
-  head: () => ({
-    meta: [
-      {
-        charSet: 'utf-8',
-      },
-      {
-        name: 'viewport',
-        content: 'width=device-width, initial-scale=1',
-      },
-      {
-        title: 'TanStack Start Starter',
-      },
-    ],
-  }),
-  component: RootComponent,
-})
-
-function RootComponent() {
-  return (
-    <RootDocument>
-      <Outlet />
-    </RootDocument>
-  )
-}
-
-function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
-  return (
-    <html>
-      <head>
-        <Meta />
-      </head>
-      <body>
-        {children}
-        <ScrollRestoration />
-        <Scripts />
-      </body>
-    </html>
-  )
-}
-```
-
-## Writing Your First Route
-
-Now that we have the basic templating setup, we can write our first route. This is done by creating a new file in the `app/routes` directory.
-
-```tsx
-// app/routes/index.tsx
-import * as fs from 'node:fs'
-import { createFileRoute, useRouter } from '@tanstack/react-router'
-import { createServerFn } from '@tanstack/start'
-
-const filePath = 'count.txt'
-
-async function readCount() {
-  return parseInt(
-    await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
-  )
-}
-
-const getCount = createServerFn({
-  method: 'GET',
-}).handler(() => {
-  return readCount()
-})
-
-const updateCount = createServerFn({ method: 'POST' })
-  .validator((d: number) => d)
-  .handler(async ({ data }) => {
-    const count = await readCount()
-    await fs.promises.writeFile(filePath, `${count + data}`)
-  })
-
-export const Route = createFileRoute('/')({
-  component: Home,
-  loader: async () => await getCount(),
-})
-
-function Home() {
-  const router = useRouter()
-  const state = Route.useLoaderData()
-
-  return (
-    <button
-      type="button"
-      onClick={() => {
-        updateCount({ data: 1 }).then(() => {
-          router.invalidate()
-        })
-      }}
-    >
-      Add 1 to {state}?
-    </button>
-  )
-}
-```
-
-That's it! 🤯 You've now set up a TanStack Start project and written your first route. 🎉
-
-You can now run `npm run dev` to start your server and navigate to `http://localhost:3000` to see your route in action.
-
-You want to deploy your application? Check out the [hosting guide](./hosting.md).
+- Use the [Quick Start Examples](../quick-start) to rapidly learn as you go
+- [Build a project from scratch](../build-from-scratch) to learn how TanStack Start works from the ground up
diff --git a/docs/framework/react/start/learn-the-basics.md b/docs/framework/react/start/learn-the-basics.md
new file mode 100644
index 000000000..685a02e2a
--- /dev/null
+++ b/docs/framework/react/start/learn-the-basics.md
@@ -0,0 +1,311 @@
+---
+id: learn-the-basics
+title: Learn the Basics
+---
+
+This guide will help you learn the basics behind how TanStack Start works, regardless of how you set up your project.
+
+## Dependencies
+
+TanStack Start is (currently\*) powered by [Vinxi](https://vinxi.vercel.app/), [Nitro](https://nitro.unjs.io/) and [TanStack Router](https://tanstack.com/router).
+
+- **TanStack Router**: A router for building web applications.
+- **Nitro**: A framework for building server applications.
+- **Vinxi**: A server framework for building web applications.
+
+> [!NOTE] Vinxi will be removed before version 1.0.0 is released and TanStack will rely only on Vite and Nitro. The commands and APIs that use Vinxi will likely be replaced with a Vite plugin.
+
+## It all "Starts" with the Router
+
+This is the file that will dictate the behavior of TanStack Router used within Start. Here, you can configure everything
+from the default [preloading functionality](../guide/preloading.md) to [caching staleness](../guide/data-loading.md).
+
+```tsx
+// app/router.tsx
+import { createRouter as createTanStackRouter } from '@tanstack/react-router'
+import { routeTree } from './routeTree.gen'
+
+export function createRouter() {
+  const router = createTanStackRouter({
+    routeTree,
+  })
+
+  return router
+}
+
+declare module '@tanstack/react-router' {
+  interface Register {
+    router: ReturnType<typeof createRouter>
+  }
+}
+```
+
+## Route Generation
+
+The `routeTree.gen.ts` file is generated when you run TanStack Start (via `npm run dev` or `npm run start`) for the first time. This file contains the generated route tree and and handful of TS utilities that make TanStack Start fully type-safe.
+
+## The Server Entry Point
+
+Althoug TanStack Start is designed with client-first APIs, it is by and large, a full-stack framework. This means that all use cases, including both dynamic and static rely on a server or build-time entry to render our application's initial HTML payload.
+
+This is done via the `app/ssr.tsx` file:
+
+```tsx
+// app/ssr.tsx
+/// <reference types="vinxi/types/server" />
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/start/server'
+import { getRouterManifest } from '@tanstack/start/router-manifest'
+
+import { createRouter } from './router'
+
+export default createStartHandler({
+  createRouter,
+  getRouterManifest,
+})(defaultStreamHandler)
+```
+
+Whether we are statically generating our app or serving it dynamically, the `ssr.tsx` file is the entry point for doing all SSR-related work.
+
+- It's important that a new router is created for each request. This ensures that any data handled by the router is unique to the request.
+- The `getRouterManifest` function is used to generate the router manifest, which is used to determine many aspects of asset management and preloading for our application.
+- The `defaultStreamHandler` function is used to render our application to a stream, allowing us to take advantage of streaming HTML to the client. (This is the default handler, but you can also use other handlers like `defaultRenderHandler`, or even build your own)
+
+## The Client Entry Point
+
+Getting our html to the client is only half the battle. Once there, we need to hydrate our client-side JavaScript once the route resolves to the client. We do this by hydrating the root of our application with the `StartClient` component:
+
+```tsx
+// app/client.tsx
+/// <reference types="vinxi/types/client" />
+import { hydrateRoot } from 'react-dom/client'
+import { StartClient } from '@tanstack/start'
+import { createRouter } from './router'
+
+const router = createRouter()
+
+hydrateRoot(document, <StartClient router={router} />)
+```
+
+This enables us to kick off client-side routing once the user's initial server request has fulfilled.
+
+## The Root of Your Application
+
+Other than the client entry point, the `__root` route of your application is the entry point for your application. The code in this file will wrap all other routes in the app, including your home page. It behaves like a layout route for your whole application.
+
+Because it is **always rendered**, it is the perfect place to construct your application shell and take care of any global logic.
+
+```tsx
+// app/routes/__root.tsx
+import {
+  Outlet,
+  ScrollRestoration,
+  createRootRoute,
+} from '@tanstack/react-router'
+import { Meta, Scripts } from '@tanstack/start'
+import type { ReactNode } from 'react'
+
+export const Route = createRootRoute({
+  head: () => ({
+    meta: [
+      {
+        charSet: 'utf-8',
+      },
+      {
+        name: 'viewport',
+        content: 'width=device-width, initial-scale=1',
+      },
+      {
+        title: 'TanStack Start Starter',
+      },
+    ],
+  }),
+  component: RootComponent,
+})
+
+function RootComponent() {
+  return (
+    <RootDocument>
+      <Outlet />
+    </RootDocument>
+  )
+}
+
+function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
+  return (
+    <html>
+      <head>
+        <Meta />
+      </head>
+      <body>
+        {children}
+        <ScrollRestoration />
+        <Scripts />
+      </body>
+    </html>
+  )
+}
+```
+
+- This layout may change in the future as we roll out SPA mode, which allows the root route to render the SPA shell without any page-specific content.
+- Notice the `ScrollRestoration` component. This is used to restore the scroll position of the page when navigating between routes.
+- Notice the `Scripts` component. This is used to load all of the client-side JavaScript for the application.
+
+## Routes
+
+Routes are an extensive feature of TanStack Router, and are covered thoroughly in the [Routing Guide](../../guide/file-based-routing). As a summary:
+
+- Routes are defined using the `createFileRoute` function.
+- Routes are automatically code-split and lazy-loaded.
+- Critical data fetching is coordinated from a Route's loader
+- Much more!
+
+```tsx
+// app/routes/index.tsx
+import * as fs from 'node:fs'
+import { createFileRoute, useRouter } from '@tanstack/react-router'
+import { createServerFn } from '@tanstack/start'
+
+const filePath = 'count.txt'
+
+async function readCount() {
+  return parseInt(
+    await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
+  )
+}
+
+const getCount = createServerFn({
+  method: 'GET',
+}).handler(() => {
+  return readCount()
+})
+
+const updateCount = createServerFn({ method: 'POST' })
+  .validator((d: number) => d)
+  .handler(async ({ data }) => {
+    const count = await readCount()
+    await fs.promises.writeFile(filePath, `${count + data}`)
+  })
+
+export const Route = createFileRoute('/')({
+  component: Home,
+  loader: async () => await getCount(),
+})
+
+function Home() {
+  const router = useRouter()
+  const state = Route.useLoaderData()
+
+  return (
+    <button
+      type="button"
+      onClick={() => {
+        updateCount({ data: 1 }).then(() => {
+          router.invalidate()
+        })
+      }}
+    >
+      Add 1 to {state}?
+    </button>
+  )
+}
+```
+
+## Navigation
+
+TanStack Start builds 100% on top of TanStack Router, so all of the navigation features of TanStack Router are available to you. In summary:
+
+- Use the `Link` component to navigate to a new route.
+- Use the `useNavigate` hook to navigate imperatively.
+- Use the `useRouter` hook anywhere in your application to access the router instance and perform invalidations.
+- Every router hook that returns state is reactive, meaning it will automatically re-run when the appropriate state changes.
+
+Here's a quick example of how you can use the `Link` component to navigate to a new route:
+
+```tsx
+import { Link } from '@tanstack/react-router'
+
+function Home() {
+  return <Link to="/about">About</Link>
+}
+```
+
+For more in-depth information on navigation, check out the [navigation guide](../../guide/navigation).
+
+## Server Functions (RPCs)
+
+You may have noticed the **server function** we created above using `createServerFn`. This is one of TanStack's most powerful features, allowing you to create server-side functions that can be called from both the server during SSR and the client!
+
+Here's a quick overview of how server functions work:
+
+- Server functions are created using the `createServerFn` function.
+- They can be called from both the server during SSR and the client.
+- They can be used to fetch data from the server, or to perform other server-side actions.
+
+Here's a quick example of how you can use server functions to fetch and return data from the server:
+
+```tsx
+import { createServerFn } from '@tanstack/start'
+import * as fs from 'node:fs'
+import { z } from 'zod'
+
+const getUserById = createServerFn({ method: 'GET' })
+  // Always validate data sent to the function, here we use Zod
+  .validator(z.string())
+  // The handler function is where you perform the server-side logic
+  .handler(async ({ data }) => {
+    return db.query.users.findFirst({ where: eq(users.id, data) })
+  })
+
+// Somewhere else in your application
+const user = await getUserById({ data: '1' })
+```
+
+To learn more about server functions, check out the [server functions guide](../server-functions).
+
+### Mutations
+
+Server Functions can also be used to perform mutations on the server. This is also done using the same `createServerFn` function, but with the additional requirement that you invalidate any data on the client that was affected by the mutation.
+
+- If you're using TanStack Router only, you can use the `router.invalidate()` method to invalidate all router data and re-fetch it.
+- If you're using TanStack Query, you can use the `queryClient.invalidateQueries()` method to invalidate data, among other more specific methods to target specific queries.
+
+Here's a quick example of how you can use server functions to perform a mutation on the server and invalidate the data on the client:
+
+```tsx
+import { createServerFn } from '@tanstack/start'
+
+const UserSchema = z.object({
+  id: z.string(),
+  name: z.string(),
+})
+
+const updateUser = createServerFn({ method: 'POST' })
+  .validator(UserSchema)
+  .handler(async ({ data }) => {
+    return db
+      .update(users)
+      .set({ name: data.name })
+      .where(eq(users.id, data.id))
+  })
+
+// Somewhere else in your application
+await updateUser({ data: { id: '1', name: 'John' } })
+```
+
+To learn more about mutations, check out the [mutations guide](../../guide/data-mutations).
+
+## Data Loading
+
+Another powerful feature of TanStack Router is data loading. This allows you to fetch data for SSR and preload route data before it is rendered. This is done using the `loader` function of a route.
+
+Here's a quick overview of how data loading works:
+
+- Data loading is done using the `loader` function of a route.
+- Data loaders are **isomorphic**, meaning they are executed on both the server and the client.
+- For performing server-only logic, call a server function from within the loader.
+- Similar to TanStack Query, data loaders are cached on the client and are re-used and even re-fetched in the background when the data is stale.
+
+To learn more about data loading, check out the [data loading guide](../../guide/data-loading).
diff --git a/docs/framework/react/start/quick-start.md b/docs/framework/react/start/quick-start.md
new file mode 100644
index 000000000..91615e0b0
--- /dev/null
+++ b/docs/framework/react/start/quick-start.md
@@ -0,0 +1,44 @@
+---
+id: quick-start
+title: Quick Start
+---
+
+TanStack Start has load of examples to get you started. Pick one of the examples below to get started!
+
+1. Play with each example in the embedded stackblitz preview to find the one that feels like a good starting point
+2. Click the **Deploy to Netlify** button to both clone and deploy the example to Netlify
+3. Or, manually clone and deploy the example to anywhere else you'd like
+4. Once you've done this, head back to the [Learn the Basics](./learn-the-basics) guide to learn how to use TanStack Start
+
+## Examples
+
+- [Basic](../../examples/start-basic)
+- [Basic + Auth](../../examples/start-basic-auth)
+- [Basic + Counter](../../examples/start-basic-counter)
+- [Basic + React Query](../../examples/start-basic-react-query)
+- [Clerk Auth](../../examples/start-clerk-basic)
+- [Convex + Trellaux](../../examples/start-convex-trellaux)
+- [Supabase](../../examples/start-supabase-basic)
+- [Trellaux](../../examples/start-trellaux)
+
+## Other Router Examples
+
+While not Start-specific examples, these may help you understand more about how TanStack Router works:
+
+- [Quickstart (file-based)](../../examples/quickstart-file-based)
+- [Quickstart (code-based)](../../examples/quickstart)
+- [Basic (file-based)](../../examples/basic-file-based)
+- [Basic (code-based)](../../examples/basic)
+- [Kitchen Sink (file-based)](../../examples/kitchen-sink-file-based)
+- [Kitchen Sink (code-based)](../../examples/kitchen-sink)
+- [Kitchen Sink + React Query (file-based)](../../examples/kitchen-sink-react-query-file-based)
+- [Kitchen Sink + React Query (code-based)](../../examples/kitchen-sink-react-query)
+- [Location Masking](../../examples/location-masking)
+- [Authenticated Routes](../../examples/authenticated-routes)
+- [Scroll Restoration](../../examples/scroll-restoration)
+- [Deferred Data](../../examples/deferred-data)
+- [Navigation Blocking](../../examples/navigation-blocking)
+- [With tRPC](../../examples/with-trpc)
+- [With tRPC + React Query](../../examples/with-trpc-react-query)
+- [Monorepo basic](../../examples/router-monorepo-simple)
+- [Monorepo with React Query](../../examples/router-monorepo-react-query)
diff --git a/examples/react/authenticated-routes/package.json b/examples/react/authenticated-routes/package.json
index d64dc5bb3..e5164c6f1 100644
--- a/examples/react/authenticated-routes/package.json
+++ b/examples/react/authenticated-routes/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-default-search-params/package.json b/examples/react/basic-default-search-params/package.json
index d745c31f4..4c722bdec 100644
--- a/examples/react/basic-default-search-params/package.json
+++ b/examples/react/basic-default-search-params/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-file-based-codesplitting/package.json b/examples/react/basic-file-based-codesplitting/package.json
index 3d3a10978..a468483c0 100644
--- a/examples/react/basic-file-based-codesplitting/package.json
+++ b/examples/react/basic-file-based-codesplitting/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-file-based/package.json b/examples/react/basic-file-based/package.json
index 8aba5c66e..137b7085a 100644
--- a/examples/react/basic-file-based/package.json
+++ b/examples/react/basic-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-react-query-file-based/package.json b/examples/react/basic-react-query-file-based/package.json
index 363f75b5a..716dade9c 100644
--- a/examples/react/basic-react-query-file-based/package.json
+++ b/examples/react/basic-react-query-file-based/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-react-query/package.json b/examples/react/basic-react-query/package.json
index 3ea1cc269..06024f40e 100644
--- a/examples/react/basic-react-query/package.json
+++ b/examples/react/basic-react-query/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/basic-ssr-file-based/package.json b/examples/react/basic-ssr-file-based/package.json
index dfe0ef767..55499f7c9 100644
--- a/examples/react/basic-ssr-file-based/package.json
+++ b/examples/react/basic-ssr-file-based/package.json
@@ -11,10 +11,10 @@
     "debug": "node --inspect-brk server"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/start": "^1.92.9",
     "get-port": "^7.1.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-ssr-streaming-file-based/package.json b/examples/react/basic-ssr-streaming-file-based/package.json
index 685c6e0f2..5e47ce4a7 100644
--- a/examples/react/basic-ssr-streaming-file-based/package.json
+++ b/examples/react/basic-ssr-streaming-file-based/package.json
@@ -11,10 +11,10 @@
     "debug": "node --inspect-brk server"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/start": "^1.92.9",
     "get-port": "^7.1.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/basic-virtual-file-based/package.json b/examples/react/basic-virtual-file-based/package.json
index 2d68844b2..49d04ea3c 100644
--- a/examples/react/basic-virtual-file-based/package.json
+++ b/examples/react/basic-virtual-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "@tanstack/virtual-file-routes": "^1.87.6",
     "react": "^18.2.0",
diff --git a/examples/react/basic-virtual-inside-file-based/package.json b/examples/react/basic-virtual-inside-file-based/package.json
index 2f208e782..552a88531 100644
--- a/examples/react/basic-virtual-inside-file-based/package.json
+++ b/examples/react/basic-virtual-inside-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "@tanstack/virtual-file-routes": "^1.87.6",
     "react": "^18.2.0",
diff --git a/examples/react/basic/package.json b/examples/react/basic/package.json
index 885eb38b1..1cf829312 100644
--- a/examples/react/basic/package.json
+++ b/examples/react/basic/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/deferred-data/package.json b/examples/react/deferred-data/package.json
index d22ed6325..a81fa5d73 100644
--- a/examples/react/deferred-data/package.json
+++ b/examples/react/deferred-data/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/kitchen-sink-file-based/package.json b/examples/react/kitchen-sink-file-based/package.json
index 8e5c3e50c..6a3a01b92 100644
--- a/examples/react/kitchen-sink-file-based/package.json
+++ b/examples/react/kitchen-sink-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "immer": "^10.1.1",
     "react": "^18.2.0",
diff --git a/examples/react/kitchen-sink-react-query-file-based/package.json b/examples/react/kitchen-sink-react-query-file-based/package.json
index 2d1817a15..01bfda62e 100644
--- a/examples/react/kitchen-sink-react-query-file-based/package.json
+++ b/examples/react/kitchen-sink-react-query-file-based/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "immer": "^10.1.1",
     "react": "^18.2.0",
diff --git a/examples/react/kitchen-sink-react-query/package.json b/examples/react/kitchen-sink-react-query/package.json
index 880da1cab..463fc2dc0 100644
--- a/examples/react/kitchen-sink-react-query/package.json
+++ b/examples/react/kitchen-sink-react-query/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "immer": "^10.1.1",
     "react": "^18.2.0",
diff --git a/examples/react/kitchen-sink/package.json b/examples/react/kitchen-sink/package.json
index 013c00eec..89d0dc63f 100644
--- a/examples/react/kitchen-sink/package.json
+++ b/examples/react/kitchen-sink/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "immer": "^10.1.1",
     "react": "^18.2.0",
diff --git a/examples/react/large-file-based/package.json b/examples/react/large-file-based/package.json
index 05f2b65d4..d5530a212 100644
--- a/examples/react/large-file-based/package.json
+++ b/examples/react/large-file-based/package.json
@@ -12,8 +12,8 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/location-masking/package.json b/examples/react/location-masking/package.json
index 30d326599..16ad0ab0b 100644
--- a/examples/react/location-masking/package.json
+++ b/examples/react/location-masking/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@radix-ui/react-dialog": "^1.1.2",
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
diff --git a/examples/react/navigation-blocking/package.json b/examples/react/navigation-blocking/package.json
index 5a5a70231..da0a9979a 100644
--- a/examples/react/navigation-blocking/package.json
+++ b/examples/react/navigation-blocking/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
diff --git a/examples/react/quickstart-esbuild-file-based/package.json b/examples/react/quickstart-esbuild-file-based/package.json
index 59f9ddc43..5068ff5b1 100644
--- a/examples/react/quickstart-esbuild-file-based/package.json
+++ b/examples/react/quickstart-esbuild-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "dev"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/quickstart-file-based/package.json b/examples/react/quickstart-file-based/package.json
index 06425d1b0..09bff0a8f 100644
--- a/examples/react/quickstart-file-based/package.json
+++ b/examples/react/quickstart-file-based/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/quickstart-rspack-file-based/package.json b/examples/react/quickstart-rspack-file-based/package.json
index 31f502857..30c4160e5 100644
--- a/examples/react/quickstart-rspack-file-based/package.json
+++ b/examples/react/quickstart-rspack-file-based/package.json
@@ -8,8 +8,8 @@
     "preview": "rsbuild preview"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1"
   },
diff --git a/examples/react/quickstart-webpack-file-based/package.json b/examples/react/quickstart-webpack-file-based/package.json
index 739b6326e..ebca94b6e 100644
--- a/examples/react/quickstart-webpack-file-based/package.json
+++ b/examples/react/quickstart-webpack-file-based/package.json
@@ -7,8 +7,8 @@
     "build": "webpack build && tsc --noEmit"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1"
   },
diff --git a/examples/react/quickstart/package.json b/examples/react/quickstart/package.json
index 3addb67c4..ce85d4379 100644
--- a/examples/react/quickstart/package.json
+++ b/examples/react/quickstart/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
   },
diff --git a/examples/react/router-monorepo-react-query/package.json b/examples/react/router-monorepo-react-query/package.json
index d3742ba4d..2ab5bdfbf 100644
--- a/examples/react/router-monorepo-react-query/package.json
+++ b/examples/react/router-monorepo-react-query/package.json
@@ -12,8 +12,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/router-monorepo-react-query/packages/app/package.json b/examples/react/router-monorepo-react-query/packages/app/package.json
index 4e7e28074..7c06bcc67 100644
--- a/examples/react/router-monorepo-react-query/packages/app/package.json
+++ b/examples/react/router-monorepo-react-query/packages/app/package.json
@@ -20,7 +20,7 @@
     "@types/react-dom": "^18.2.18",
     "@vitejs/plugin-react": "^4.3.4",
     "typescript": "^5.7.2",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/router-devtools": "^1.92.9",
     "vite": "^6.0.3",
     "vite-plugin-dts": "^4.4.0"
   },
diff --git a/examples/react/router-monorepo-react-query/packages/router/package.json b/examples/react/router-monorepo-react-query/packages/router/package.json
index 7dca9e466..12d1df00c 100644
--- a/examples/react/router-monorepo-react-query/packages/router/package.json
+++ b/examples/react/router-monorepo-react-query/packages/router/package.json
@@ -10,7 +10,7 @@
   "dependencies": {
     "@tanstack/history": "^1.90.0",
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "@router-mono-react-query/post-query": "workspace:*",
     "redaxios": "^0.5.1",
diff --git a/examples/react/router-monorepo-simple/package.json b/examples/react/router-monorepo-simple/package.json
index 94b2b02d4..eb9507462 100644
--- a/examples/react/router-monorepo-simple/package.json
+++ b/examples/react/router-monorepo-simple/package.json
@@ -8,8 +8,8 @@
     "dev": "pnpm router build && pnpm post-feature build && pnpm app dev"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/router-monorepo-simple/packages/app/package.json b/examples/react/router-monorepo-simple/packages/app/package.json
index d3eff7a29..229bfb35f 100644
--- a/examples/react/router-monorepo-simple/packages/app/package.json
+++ b/examples/react/router-monorepo-simple/packages/app/package.json
@@ -19,7 +19,7 @@
     "@types/react-dom": "^18.2.18",
     "@vitejs/plugin-react": "^4.3.4",
     "typescript": "^5.7.2",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/router-devtools": "^1.92.9",
     "vite": "^6.0.3",
     "vite-plugin-dts": "^4.4.0"
   },
diff --git a/examples/react/router-monorepo-simple/packages/router/package.json b/examples/react/router-monorepo-simple/packages/router/package.json
index 9f3fa4c88..240ed70ba 100644
--- a/examples/react/router-monorepo-simple/packages/router/package.json
+++ b/examples/react/router-monorepo-simple/packages/router/package.json
@@ -9,7 +9,7 @@
   "types": "./dist/index.d.ts",
   "dependencies": {
     "@tanstack/history": "^1.90.0",
-    "@tanstack/react-router": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "redaxios": "^0.5.1",
     "zod": "^3.23.8",
diff --git a/examples/react/scroll-restoration/package.json b/examples/react/scroll-restoration/package.json
index 787099873..00c70adc1 100644
--- a/examples/react/scroll-restoration/package.json
+++ b/examples/react/scroll-restoration/package.json
@@ -9,9 +9,9 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
     "@tanstack/react-virtual": "^3.11.1",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/router-devtools": "^1.92.9",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
   },
diff --git a/examples/react/search-validator-adapters/package.json b/examples/react/search-validator-adapters/package.json
index 4db27b491..7b7d66653 100644
--- a/examples/react/search-validator-adapters/package.json
+++ b/examples/react/search-validator-adapters/package.json
@@ -11,12 +11,12 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/arktype-adapter": "^1.92.7",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/arktype-adapter": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
-    "@tanstack/valibot-adapter": "^1.92.6",
-    "@tanstack/zod-adapter": "^1.92.6",
+    "@tanstack/valibot-adapter": "^1.92.9",
+    "@tanstack/zod-adapter": "^1.92.9",
     "arktype": "2.0.0-rc.26",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
diff --git a/examples/react/start-basic-auth/package.json b/examples/react/start-basic-auth/package.json
index a46a61335..5a9c739ff 100644
--- a/examples/react/start-basic-auth/package.json
+++ b/examples/react/start-basic-auth/package.json
@@ -11,9 +11,9 @@
   },
   "dependencies": {
     "@prisma/client": "5.22.0",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "prisma": "^5.22.0",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
diff --git a/examples/react/start-basic-react-query/package.json b/examples/react/start-basic-react-query/package.json
index a3ce1427b..eb8123fc4 100644
--- a/examples/react/start-basic-react-query/package.json
+++ b/examples/react/start-basic-react-query/package.json
@@ -11,10 +11,10 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/react-router-with-query": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/react-router-with-query": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-basic-rsc/package.json b/examples/react/start-basic-rsc/package.json
index bcecb2495..54d05a92e 100644
--- a/examples/react/start-basic-rsc/package.json
+++ b/examples/react/start-basic-rsc/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@babel/plugin-syntax-typescript": "^7.25.9",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "redaxios": "^0.5.1",
     "tailwind-merge": "^2.5.5",
     "vinxi": "0.5.1"
diff --git a/examples/react/start-basic/package.json b/examples/react/start-basic/package.json
index d904e13d3..506902504 100644
--- a/examples/react/start-basic/package.json
+++ b/examples/react/start-basic/package.json
@@ -9,9 +9,9 @@
     "start": "vinxi start"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-clerk-basic/package.json b/examples/react/start-clerk-basic/package.json
index 4b67aca4f..0a46c821b 100644
--- a/examples/react/start-clerk-basic/package.json
+++ b/examples/react/start-clerk-basic/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@clerk/tanstack-start": "0.6.5",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-convex-trellaux/package.json b/examples/react/start-convex-trellaux/package.json
index 55ecfa2e5..2d27f069a 100644
--- a/examples/react/start-convex-trellaux/package.json
+++ b/examples/react/start-convex-trellaux/package.json
@@ -13,10 +13,10 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/react-router-with-query": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/react-router-with-query": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "@convex-dev/react-query": "0.0.0-alpha.8",
     "concurrently": "^8.2.2",
     "convex": "^1.17.3",
diff --git a/examples/react/start-counter/package.json b/examples/react/start-counter/package.json
index 46391d2be..648581d91 100644
--- a/examples/react/start-counter/package.json
+++ b/examples/react/start-counter/package.json
@@ -9,8 +9,8 @@
     "start": "vinxi start"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "vinxi": "0.5.1"
diff --git a/examples/react/start-large/package.json b/examples/react/start-large/package.json
index 670335acd..01fb74c61 100644
--- a/examples/react/start-large/package.json
+++ b/examples/react/start-large/package.json
@@ -12,9 +12,9 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-supabase-basic/package.json b/examples/react/start-supabase-basic/package.json
index bc3beaa40..e1fc71b2b 100644
--- a/examples/react/start-supabase-basic/package.json
+++ b/examples/react/start-supabase-basic/package.json
@@ -15,9 +15,9 @@
   "dependencies": {
     "@supabase/ssr": "^0.5.2",
     "@supabase/supabase-js": "^2.47.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "vinxi": "0.5.1"
diff --git a/examples/react/start-trellaux/package.json b/examples/react/start-trellaux/package.json
index b31b6055f..81bc78b65 100644
--- a/examples/react/start-trellaux/package.json
+++ b/examples/react/start-trellaux/package.json
@@ -11,10 +11,10 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/react-router-with-query": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
-    "@tanstack/start": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/react-router-with-query": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
+    "@tanstack/start": "^1.92.9",
     "ky": "^1.7.2",
     "msw": "^2.6.8",
     "react": "^18.3.1",
diff --git a/examples/react/with-framer-motion/package.json b/examples/react/with-framer-motion/package.json
index e3b953fca..14d18dab2 100644
--- a/examples/react/with-framer-motion/package.json
+++ b/examples/react/with-framer-motion/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "redaxios": "^0.5.1",
     "framer-motion": "^11.13.3",
     "react": "^18.2.0",
diff --git a/examples/react/with-trpc-react-query/package.json b/examples/react/with-trpc-react-query/package.json
index fe9abe768..8a1f8dcd0 100644
--- a/examples/react/with-trpc-react-query/package.json
+++ b/examples/react/with-trpc-react-query/package.json
@@ -10,8 +10,8 @@
   "dependencies": {
     "@tanstack/react-query": "^5.62.3",
     "@tanstack/react-query-devtools": "^5.62.3",
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "@trpc/client": "11.0.0-rc.660",
     "@trpc/react-query": "11.0.0-rc.660",
diff --git a/examples/react/with-trpc/package.json b/examples/react/with-trpc/package.json
index a11ff26fc..d073954f6 100644
--- a/examples/react/with-trpc/package.json
+++ b/examples/react/with-trpc/package.json
@@ -8,8 +8,8 @@
     "start": "vinxi start"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.92.6",
-    "@tanstack/router-devtools": "^1.92.6",
+    "@tanstack/react-router": "^1.92.9",
+    "@tanstack/router-devtools": "^1.92.9",
     "@tanstack/router-plugin": "^1.91.1",
     "@trpc/client": "11.0.0-rc.660",
     "@trpc/server": "11.0.0-rc.660",
diff --git a/packages/arktype-adapter/package.json b/packages/arktype-adapter/package.json
index 2adba78da..8fe204480 100644
--- a/packages/arktype-adapter/package.json
+++ b/packages/arktype-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/arktype-adapter",
-  "version": "1.92.7",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/create-router/package.json b/packages/create-router/package.json
index 4bcad8d13..5557094f1 100644
--- a/packages/create-router/package.json
+++ b/packages/create-router/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/create-router",
-  "version": "1.92.7",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/create-start/package.json b/packages/create-start/package.json
index 43942e543..e5622e8f4 100644
--- a/packages/create-start/package.json
+++ b/packages/create-start/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/create-start",
-  "version": "1.92.8",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tim O'Connell",
   "license": "MIT",
diff --git a/packages/react-router-with-query/package.json b/packages/react-router-with-query/package.json
index cb4a1bded..5d6137b36 100644
--- a/packages/react-router-with-query/package.json
+++ b/packages/react-router-with-query/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-router-with-query",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router/package.json b/packages/react-router/package.json
index c0a807a77..d4f98b345 100644
--- a/packages/react-router/package.json
+++ b/packages/react-router/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-router",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router/src/Matches.tsx b/packages/react-router/src/Matches.tsx
index cda42fba3..724e491e9 100644
--- a/packages/react-router/src/Matches.tsx
+++ b/packages/react-router/src/Matches.tsx
@@ -13,7 +13,7 @@ import type {
 } from './structuralSharing'
 import type { AnyRoute, ReactNode, StaticDataRouteOption } from './route'
 import type { AnyRouter, RegisteredRouter, RouterState } from './router'
-import type { ResolveRelativePath, ToOptions } from './link'
+import type { ResolveRelativePath, ResolveRoute, ToOptions } from './link'
 import type {
   AllContext,
   AllLoaderData,
@@ -273,7 +273,7 @@ export type UseMatchRouteOptions<
   TFrom extends RoutePaths<TRouter['routeTree']> | string = RoutePaths<
     TRouter['routeTree']
   >,
-  TTo extends string = '',
+  TTo extends string | undefined = '',
   TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
   TMaskTo extends string = '',
   TOptions extends ToOptions<
@@ -297,16 +297,13 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
 
   return React.useCallback(
     <
-      TFrom extends RoutePaths<TRouter['routeTree']> | string = string,
-      TTo extends string = '',
-      TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
-      TMaskTo extends string = '',
-      TResolved extends string = ResolveRelativePath<TFrom, NoInfer<TTo>>,
+      const TFrom extends string = string,
+      const TTo extends string | undefined = undefined,
+      const TMaskFrom extends string = TFrom,
+      const TMaskTo extends string = '',
     >(
       opts: UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
-    ):
-      | false
-      | RouteByPath<TRouter['routeTree'], TResolved>['types']['allParams'] => {
+    ): false | ResolveRoute<TRouter, TFrom, TTo>['types']['allParams'] => {
       const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts
 
       return router.matchRoute(rest as any, {
@@ -322,11 +319,9 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
 
 export type MakeMatchRouteOptions<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends RoutePaths<TRouter['routeTree']> = RoutePaths<
-    TRouter['routeTree']
-  >,
-  TTo extends string = '',
-  TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,
+  TFrom extends string = string,
+  TTo extends string | undefined = undefined,
+  TMaskFrom extends string = TFrom,
   TMaskTo extends string = '',
 > = UseMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & {
   // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns
@@ -342,15 +337,13 @@ export type MakeMatchRouteOptions<
 
 export function MatchRoute<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends RoutePaths<TRouter['routeTree']> = RoutePaths<
-    TRouter['routeTree']
-  >,
-  TTo extends string = '',
-  TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,
-  TMaskTo extends string = '',
+  const TFrom extends string = string,
+  const TTo extends string | undefined = undefined,
+  const TMaskFrom extends string = TFrom,
+  const TMaskTo extends string = '',
 >(props: MakeMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): any {
   const matchRoute = useMatchRoute()
-  const params = matchRoute(props as any)
+  const params = matchRoute(props as any) as boolean
 
   if (typeof props.children === 'function') {
     return (props.children as any)(params)
diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx
index bff3716f4..8b68a361f 100644
--- a/packages/react-router/src/link.tsx
+++ b/packages/react-router/src/link.tsx
@@ -555,10 +555,10 @@ const preloadWarning = 'Error preloading route! ☝️'
 
 export function useLinkProps<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends RoutePaths<TRouter['routeTree']> | string = string,
-  TTo extends string = '',
-  TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
-  TMaskTo extends string = '',
+  const TFrom extends string = string,
+  const TTo extends string | undefined = undefined,
+  const TMaskFrom extends string = TFrom,
+  const TMaskTo extends string = '',
 >(
   options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
   forwardedRef?: React.ForwardedRef<Element>,
@@ -976,10 +976,10 @@ export type CreateLinkProps = LinkProps<
 
 export type LinkComponent<TComp> = <
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string = string,
-  TTo extends string | undefined = undefined,
-  TMaskFrom extends string = TFrom,
-  TMaskTo extends string = '',
+  const TFrom extends string = string,
+  const TTo extends string | undefined = undefined,
+  const TMaskFrom extends string = TFrom,
+  const TMaskTo extends string = '',
 >(
   props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
 ) => React.ReactElement
diff --git a/packages/react-router/src/redirects.ts b/packages/react-router/src/redirects.ts
index 0884f56e5..b81265d36 100644
--- a/packages/react-router/src/redirects.ts
+++ b/packages/react-router/src/redirects.ts
@@ -37,10 +37,10 @@ export type ResolvedRedirect<
 
 export function redirect<
   TRouter extends RegisteredRouter,
-  TTo extends string | undefined,
-  TFrom extends string = string,
-  TMaskFrom extends string = TFrom,
-  TMaskTo extends string = '',
+  const TTo extends string | undefined,
+  const TFrom extends string = string,
+  const TMaskFrom extends string = TFrom,
+  const TMaskTo extends string = '',
 >(
   opts: Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
 ): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
diff --git a/packages/react-router/src/route.ts b/packages/react-router/src/route.ts
index 6d266e586..9c5c26529 100644
--- a/packages/react-router/src/route.ts
+++ b/packages/react-router/src/route.ts
@@ -800,9 +800,10 @@ export type RouteTypesById<TRouter extends AnyRouter, TId> = RouteById<
   TId
 >['types']
 
-export function getRouteApi<TId, TRouter extends AnyRouter = RegisteredRouter>(
-  id: ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>,
-) {
+export function getRouteApi<
+  const TId,
+  TRouter extends AnyRouter = RegisteredRouter,
+>(id: ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>) {
   return new RouteApi<TId, TRouter>({ id })
 }
 
diff --git a/packages/react-router/src/useLoaderData.tsx b/packages/react-router/src/useLoaderData.tsx
index f174b9313..6128e5e32 100644
--- a/packages/react-router/src/useLoaderData.tsx
+++ b/packages/react-router/src/useLoaderData.tsx
@@ -69,7 +69,7 @@ export type UseLoaderDataRoute<out TId> = <
 
 export function useLoaderData<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TStrict extends boolean = true,
   TSelected = unknown,
   TStructuralSharing extends boolean = boolean,
diff --git a/packages/react-router/src/useLoaderDeps.tsx b/packages/react-router/src/useLoaderDeps.tsx
index 76f010bc4..d9c9fc5b3 100644
--- a/packages/react-router/src/useLoaderDeps.tsx
+++ b/packages/react-router/src/useLoaderDeps.tsx
@@ -48,7 +48,7 @@ export type UseLoaderDepsRoute<out TId> = <
 
 export function useLoaderDeps<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TSelected = unknown,
   TStructuralSharing extends boolean = boolean,
 >(
diff --git a/packages/react-router/src/useMatch.tsx b/packages/react-router/src/useMatch.tsx
index 43cf7edcb..367ae4f46 100644
--- a/packages/react-router/src/useMatch.tsx
+++ b/packages/react-router/src/useMatch.tsx
@@ -76,7 +76,7 @@ type ThrowConstraint<
 
 export function useMatch<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TStrict extends boolean = true,
   TThrow extends boolean = true,
   TSelected = unknown,
diff --git a/packages/react-router/src/useNavigate.tsx b/packages/react-router/src/useNavigate.tsx
index c282760ac..eb5cbb93e 100644
--- a/packages/react-router/src/useNavigate.tsx
+++ b/packages/react-router/src/useNavigate.tsx
@@ -49,10 +49,10 @@ export function useNavigate<
 
 export function Navigate<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string = string,
-  TTo extends string | undefined = '.',
-  TMaskFrom extends string = TFrom,
-  TMaskTo extends string = '.',
+  const TFrom extends string = string,
+  const TTo extends string | undefined = undefined,
+  const TMaskFrom extends string = TFrom,
+  const TMaskTo extends string = '',
 >(props: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): null {
   const { navigate } = useRouter()
 
diff --git a/packages/react-router/src/useParams.tsx b/packages/react-router/src/useParams.tsx
index bfa19e0cd..45ad4951b 100644
--- a/packages/react-router/src/useParams.tsx
+++ b/packages/react-router/src/useParams.tsx
@@ -63,7 +63,7 @@ export type UseParamsRoute<out TFrom> = <
 
 export function useParams<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TStrict extends boolean = true,
   TSelected = unknown,
   TStructuralSharing extends boolean = boolean,
diff --git a/packages/react-router/src/useRouteContext.ts b/packages/react-router/src/useRouteContext.ts
index 084354026..451807d99 100644
--- a/packages/react-router/src/useRouteContext.ts
+++ b/packages/react-router/src/useRouteContext.ts
@@ -46,7 +46,7 @@ export type UseRouteContextRoute<out TFrom> = <
 
 export function useRouteContext<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TStrict extends boolean = true,
   TSelected = unknown,
 >(
diff --git a/packages/react-router/src/useSearch.tsx b/packages/react-router/src/useSearch.tsx
index 53299d58f..9734dba4d 100644
--- a/packages/react-router/src/useSearch.tsx
+++ b/packages/react-router/src/useSearch.tsx
@@ -63,7 +63,7 @@ export type UseSearchRoute<out TFrom> = <
 
 export function useSearch<
   TRouter extends AnyRouter = RegisteredRouter,
-  TFrom extends string | undefined = undefined,
+  const TFrom extends string | undefined = undefined,
   TStrict extends boolean = true,
   TSelected = unknown,
   TStructuralSharing extends boolean = boolean,
diff --git a/packages/router-devtools/package.json b/packages/router-devtools/package.json
index 5317d5cc3..032760f88 100644
--- a/packages/router-devtools/package.json
+++ b/packages/router-devtools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-devtools",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/start/package.json b/packages/start/package.json
index 1af84b494..b564f65a4 100644
--- a/packages/start/package.json
+++ b/packages/start/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/start/src/client/Scripts.tsx b/packages/start/src/client/Scripts.tsx
index 3070caac4..19d6b305d 100644
--- a/packages/start/src/client/Scripts.tsx
+++ b/packages/start/src/client/Scripts.tsx
@@ -33,8 +33,8 @@ export const Scripts = () => {
       scripts: (
         state.matches
           .map((match) => match.scripts!)
-          .filter(Boolean)
-          .flat(1) as Array<RouterManagedTag>
+          .flat(1)
+          .filter(Boolean) as Array<RouterManagedTag>
       ).map(({ children, ...script }) => ({
         tag: 'script',
         attrs: {
diff --git a/packages/valibot-adapter/package.json b/packages/valibot-adapter/package.json
index 583bff5e3..dfd9f696d 100644
--- a/packages/valibot-adapter/package.json
+++ b/packages/valibot-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/valibot-adapter",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/zod-adapter/package.json b/packages/zod-adapter/package.json
index f5652c04d..e592043b3 100644
--- a/packages/zod-adapter/package.json
+++ b/packages/zod-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/zod-adapter",
-  "version": "1.92.6",
+  "version": "1.92.9",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",


Test patch:
diff --git a/e2e/start/basic/app/routeTree.gen.ts b/e2e/start/basic/app/routeTree.gen.ts
index 97f04f768..3dc72a54f 100644
--- a/e2e/start/basic/app/routeTree.gen.ts
+++ b/e2e/start/basic/app/routeTree.gen.ts
@@ -15,6 +15,7 @@ import { Route as UsersImport } from './routes/users'
 import { Route as StatusImport } from './routes/status'
 import { Route as ServerFnsImport } from './routes/server-fns'
 import { Route as SearchParamsImport } from './routes/search-params'
+import { Route as ScriptsImport } from './routes/scripts'
 import { Route as PostsImport } from './routes/posts'
 import { Route as LinksImport } from './routes/links'
 import { Route as IsomorphicFnsImport } from './routes/isomorphic-fns'
@@ -66,6 +67,12 @@ const SearchParamsRoute = SearchParamsImport.update({
   getParentRoute: () => rootRoute,
 } as any)
 
+const ScriptsRoute = ScriptsImport.update({
+  id: '/scripts',
+  path: '/scripts',
+  getParentRoute: () => rootRoute,
+} as any)
+
 const PostsRoute = PostsImport.update({
   id: '/posts',
   path: '/posts',
@@ -266,6 +273,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof PostsImport
       parentRoute: typeof rootRoute
     }
+    '/scripts': {
+      id: '/scripts'
+      path: '/scripts'
+      fullPath: '/scripts'
+      preLoaderRoute: typeof ScriptsImport
+      parentRoute: typeof rootRoute
+    }
     '/search-params': {
       id: '/search-params'
       path: '/search-params'
@@ -501,6 +515,7 @@ export interface FileRoutesByFullPath {
   '/isomorphic-fns': typeof IsomorphicFnsRoute
   '/links': typeof LinksRoute
   '/posts': typeof PostsRouteWithChildren
+  '/scripts': typeof ScriptsRoute
   '/search-params': typeof SearchParamsRoute
   '/server-fns': typeof ServerFnsRoute
   '/status': typeof StatusRoute
@@ -530,6 +545,7 @@ export interface FileRoutesByTo {
   '/env-only': typeof EnvOnlyRoute
   '/isomorphic-fns': typeof IsomorphicFnsRoute
   '/links': typeof LinksRoute
+  '/scripts': typeof ScriptsRoute
   '/search-params': typeof SearchParamsRoute
   '/server-fns': typeof ServerFnsRoute
   '/status': typeof StatusRoute
@@ -559,6 +575,7 @@ export interface FileRoutesById {
   '/isomorphic-fns': typeof IsomorphicFnsRoute
   '/links': typeof LinksRoute
   '/posts': typeof PostsRouteWithChildren
+  '/scripts': typeof ScriptsRoute
   '/search-params': typeof SearchParamsRoute
   '/server-fns': typeof ServerFnsRoute
   '/status': typeof StatusRoute
@@ -592,6 +609,7 @@ export interface FileRouteTypes {
     | '/isomorphic-fns'
     | '/links'
     | '/posts'
+    | '/scripts'
     | '/search-params'
     | '/server-fns'
     | '/status'
@@ -620,6 +638,7 @@ export interface FileRouteTypes {
     | '/env-only'
     | '/isomorphic-fns'
     | '/links'
+    | '/scripts'
     | '/search-params'
     | '/server-fns'
     | '/status'
@@ -647,6 +666,7 @@ export interface FileRouteTypes {
     | '/isomorphic-fns'
     | '/links'
     | '/posts'
+    | '/scripts'
     | '/search-params'
     | '/server-fns'
     | '/status'
@@ -679,6 +699,7 @@ export interface RootRouteChildren {
   IsomorphicFnsRoute: typeof IsomorphicFnsRoute
   LinksRoute: typeof LinksRoute
   PostsRoute: typeof PostsRouteWithChildren
+  ScriptsRoute: typeof ScriptsRoute
   SearchParamsRoute: typeof SearchParamsRoute
   ServerFnsRoute: typeof ServerFnsRoute
   StatusRoute: typeof StatusRoute
@@ -696,6 +717,7 @@ const rootRouteChildren: RootRouteChildren = {
   IsomorphicFnsRoute: IsomorphicFnsRoute,
   LinksRoute: LinksRoute,
   PostsRoute: PostsRouteWithChildren,
+  ScriptsRoute: ScriptsRoute,
   SearchParamsRoute: SearchParamsRoute,
   ServerFnsRoute: ServerFnsRoute,
   StatusRoute: StatusRoute,
@@ -722,6 +744,7 @@ export const routeTree = rootRoute
         "/isomorphic-fns",
         "/links",
         "/posts",
+        "/scripts",
         "/search-params",
         "/server-fns",
         "/status",
@@ -759,6 +782,9 @@ export const routeTree = rootRoute
         "/posts/"
       ]
     },
+    "/scripts": {
+      "filePath": "scripts.tsx"
+    },
     "/search-params": {
       "filePath": "search-params.tsx"
     },
diff --git a/e2e/start/basic/app/routes/__root.tsx b/e2e/start/basic/app/routes/__root.tsx
index 876210e14..d3e1f7d33 100644
--- a/e2e/start/basic/app/routes/__root.tsx
+++ b/e2e/start/basic/app/routes/__root.tsx
@@ -112,6 +112,14 @@ function RootDocument({ children }: { children: React.ReactNode }) {
           >
             Layout
           </Link>{' '}
+          <Link
+            to="/scripts"
+            activeProps={{
+              className: 'font-bold',
+            }}
+          >
+            Scripts
+          </Link>{' '}
           <Link
             to="/deferred"
             activeProps={{
diff --git a/e2e/start/basic/app/routes/scripts.tsx b/e2e/start/basic/app/routes/scripts.tsx
new file mode 100644
index 000000000..511f66e36
--- /dev/null
+++ b/e2e/start/basic/app/routes/scripts.tsx
@@ -0,0 +1,33 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const isProd = import.meta.env.PROD
+
+export const Route = createFileRoute('/scripts')({
+  head: () => ({
+    scripts: [
+      {
+        src: 'script.js',
+        ['data-testid']: 'script',
+      },
+      isProd
+        ? undefined
+        : {
+            src: 'script2.js',
+            ['data-testid']: 'script2',
+          },
+    ],
+  }),
+  component: ScriptsComponent,
+})
+
+function ScriptsComponent() {
+  return (
+    <div className="p-2">
+      <h3>Scripts Test</h3>
+      <p>
+        Both `script.js` and `script2.js` are included in development, but only
+        `script.js` is included in production.
+      </p>
+    </div>
+  )
+}
diff --git a/e2e/start/basic/public/script.js b/e2e/start/basic/public/script.js
new file mode 100644
index 000000000..d24edb364
--- /dev/null
+++ b/e2e/start/basic/public/script.js
@@ -0,0 +1,2 @@
+// eslint-disable no-empty-file
+// This empty script file is for testing purposes only
diff --git a/e2e/start/basic/public/script2.js b/e2e/start/basic/public/script2.js
new file mode 100644
index 000000000..d24edb364
--- /dev/null
+++ b/e2e/start/basic/public/script2.js
@@ -0,0 +1,2 @@
+// eslint-disable no-empty-file
+// This empty script file is for testing purposes only
diff --git a/e2e/start/basic/tests/base.spec.ts b/e2e/start/basic/tests/base.spec.ts
index 80c30f9d0..3b6158ed0 100644
--- a/e2e/start/basic/tests/base.spec.ts
+++ b/e2e/start/basic/tests/base.spec.ts
@@ -32,6 +32,15 @@ test('Navigating nested layouts', async ({ page }) => {
   await expect(page.locator('body')).toContainText("I'm layout B!")
 })
 
+test('Navigating to route with scripts', async ({ page }) => {
+  await page.goto('/')
+
+  await page.getByRole('link', { name: 'Scripts' }).click()
+
+  await expect(page.getByTestId('script')).toHaveCount(1)
+  await expect(page.getByTestId('script2')).toHaveCount(0)
+})
+
 test('Navigating to a not-found route', async ({ page }) => {
   await page.goto('/')
 
@@ -79,10 +88,12 @@ test('invoking a server function with custom response status code', async ({
       expect(response.status()).toBe(225)
       expect(response.statusText()).toBe('hello')
       expect(response.headers()['content-type']).toBe('application/json')
-      expect(await response.json()).toEqual({
-        result: { hello: 'world' },
-        context: {},
-      })
+      expect(await response.json()).toEqual(
+        expect.objectContaining({
+          result: { hello: 'world' },
+          context: {},
+        }),
+      )
       resolve()
     })
   })
@@ -193,7 +204,7 @@ test('env-only functions can only be called on the server or client respectively
   )
 })
 
-test.only('Server function can return null for GET and POST calls', async ({
+test('Server function can return null for GET and POST calls', async ({
   page,
 }) => {
   await page.goto('/server-fns')
diff --git a/e2e/start/basic/tsconfig.json b/e2e/start/basic/tsconfig.json
index d1b5b7766..a6747faec 100644
--- a/e2e/start/basic/tsconfig.json
+++ b/e2e/start/basic/tsconfig.json
@@ -1,5 +1,5 @@
 {
-  "include": ["**/*.ts", "**/*.tsx"],
+  "include": ["**/*.ts", "**/*.tsx", "public/script*.js"],
   "compilerOptions": {
     "strict": true,
     "esModuleInterop": true,
diff --git a/packages/react-router/tests/link.bench.tsx b/packages/react-router/tests/link.bench.tsx
index 74f7d37ad..4854c908c 100644
--- a/packages/react-router/tests/link.bench.tsx
+++ b/packages/react-router/tests/link.bench.tsx
@@ -149,16 +149,20 @@ describe.each([
     'link to relative path',
     () => {
       const router = renderRouter(
-        Array.from({ length: numberOfLinks }).map((_, i) => (
-          <Link
-            key={i}
-            from="/"
-            to={`./params/$param${Math.min(i, matchedParamId)}`}
-            params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
-          >
-            {i}
-          </Link>
-        )),
+        Array.from({ length: numberOfLinks }).map((_, i) => {
+          const to = `./params/$param${Math.min(i, matchedParamId)}`
+
+          return (
+            <Link
+              key={i}
+              from="/"
+              to={to}
+              params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
+            >
+              {i}
+            </Link>
+          )
+        }),
       )
       render(<RouterProvider router={router} />)
     },
diff --git a/packages/start/src/client/tests/index.test.tsx b/packages/start/src/client/tests/index.test.tsx
index e1757cc88..321c1ab6a 100644
--- a/packages/start/src/client/tests/index.test.tsx
+++ b/packages/start/src/client/tests/index.test.tsx
@@ -72,6 +72,55 @@ describe('ssr scripts', () => {
       `<script src="script.js"></script><script src="script2.js"></script><script src="script3.js"></script>`,
     )
   })
+
+  test('excludes `undefined` script values', async () => {
+    const rootRoute = createRootRoute({
+      head: () => {
+        return {
+          scripts: [
+            { src: 'script.js' },
+            undefined, // 'script2.js' opted out by certain conditions, such as `NODE_ENV=production`.
+          ],
+        }
+      },
+      component: () => {
+        return <Scripts />
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+      head: () => {
+        return {
+          scripts: [{ src: 'script3.js' }],
+        }
+      },
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    router.isServer = true
+
+    await router.load()
+
+    expect(router.state.matches.map((d) => d.scripts).flat(1)).toEqual([
+      { src: 'script.js' },
+      undefined,
+      { src: 'script3.js' },
+    ])
+
+    const { container } = render(<RouterProvider router={router} />)
+
+    expect(container.innerHTML).toEqual(
+      `<script src="script.js"></script><script src="script3.js"></script>`,
+    )
+  })
 })
 
 describe('ssr meta', () => {