> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tailor-platform/app-shell/llms.txt
> Use this file to discover all available pages before exploring further.

# Routing and navigation

> Master client-side navigation, route parameters, and the command palette in AppShell

AppShell manages routing internally using React Router v7. To ensure proper functionality, you must use AppShell's re-exported navigation components and hooks instead of installing React Router directly.

## Why use AppShell's exports?

AppShell has its own `RouterProvider` instance. Using components and hooks from `@tailor-platform/app-shell` ensures they connect to the correct router context.

<Warning>
  Do not install `react-router` directly or import from it. Always use AppShell's re-exports to avoid context mismatches.
</Warning>

## Navigation hooks

AppShell re-exports these essential React Router hooks:

| Hook              | Purpose                                     |
| ----------------- | ------------------------------------------- |
| `useLocation`     | Access the current location object          |
| `useNavigate`     | Programmatic navigation                     |
| `useParams`       | Access route parameters                     |
| `useSearchParams` | Access and manipulate URL search parameters |
| `useRouteError`   | Access error details in error boundaries    |

## Navigation components

| Component | Purpose                          |
| --------- | -------------------------------- |
| `Link`    | Client-side navigation component |

## Basic usage

### Programmatic navigation

```tsx theme={null}
import { useNavigate, useParams, useLocation } from "@tailor-platform/app-shell";

const MyComponent = () => {
  const navigate = useNavigate();
  const { id } = useParams();
  const location = useLocation();
  
  const handleClick = () => {
    // Navigate programmatically
    navigate("/dashboard/overview");
  };
  
  return (
    <div>
      <p>Current path: {location.pathname}</p>
      <p>Route param ID: {id}</p>
      <button onClick={handleClick}>Go to Dashboard</button>
    </div>
  );
};
```

### Link component

```tsx theme={null}
import { Link } from "@tailor-platform/app-shell";

const Navigation = () => {
  return (
    <nav>
      <Link to="/products">View Products</Link>
      <Link to="/orders/123">Order #123</Link>
    </nav>
  );
};
```

## Search parameters

Manipulate query strings with `useSearchParams`:

```tsx theme={null}
import { useSearchParams } from "@tailor-platform/app-shell";

const ProductList = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  
  const category = searchParams.get("category");
  const page = searchParams.get("page") || "1";
  
  const updateCategory = (newCategory: string) => {
    setSearchParams({ category: newCategory, page: "1" });
  };
  
  return (
    <div>
      <p>Current category: {category}</p>
      <p>Page: {page}</p>
      <button onClick={() => updateCategory("electronics")}>Electronics</button>
    </div>
  );
};
```

## Command palette

The `CommandPalette` component provides keyboard-driven quick navigation to any page in your application.

### Features

* **Keyboard shortcut**: `Cmd+K` (Mac) or `Ctrl+K` (Windows/Linux)
* **Fuzzy search**: Find pages by title or path
* **Hierarchical display**: Shows module > resource breadcrumbs
* **Keyboard navigation**: Arrow keys and Enter to navigate
* **Multilingual**: Supports English and Japanese locales
* **Smart filtering**: Respects access control (hidden routes don't appear)

### Setup

Add the `CommandPalette` to your AppShell layout:

```tsx theme={null}
import { 
  AppShell, 
  SidebarLayout, 
  CommandPalette 
} from "@tailor-platform/app-shell";

const App = () => (
  <AppShell modules={modules} locale="en">
    <>
      <SidebarLayout />
      <CommandPalette />
    </>
  </AppShell>
);
```

### How it works

The CommandPalette automatically:

1. Collects all navigable routes from your module definitions
2. Respects guard functions (routes with `hidden()` won't appear)
3. Updates when navigation items change
4. Adapts to the current locale

<Info>
  No additional configuration needed—just add the component and it works!
</Info>

### User experience

<Steps>
  <Step title="Open command palette">
    User presses `Cmd+K` or `Ctrl+K` anywhere in the app
  </Step>

  <Step title="Search for pages">
    Dialog opens with fuzzy search. Type to filter (e.g., "order detail")
  </Step>

  <Step title="Navigate results">
    Use arrow keys to navigate through results
  </Step>

  <Step title="Navigate to page">
    Press Enter to navigate to the selected page
  </Step>
</Steps>

## Type-safe navigation

When using file-based routing with the Vite plugin, you can enable automatic generation of type-safe route helpers.

### Enable typed routes

Configure in your Vite config:

```ts theme={null}
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { appShellRoutes } from "@tailor-platform/app-shell-vite-plugin";

export default defineConfig({
  plugins: [
    react(),
    appShellRoutes({
      pagesDir: "src/pages",
      // Enable with default output path ("src/routes.generated.ts")
      generateTypedRoutes: true,
      // Or customize output path:
      // generateTypedRoutes: { output: "src/my-routes.ts" },
    }),
  ],
});
```

### Generated file

The plugin generates `src/routes.generated.ts`:

```ts theme={null}
// src/routes.generated.ts (auto-generated)
import { createTypedPaths } from "@tailor-platform/app-shell";

type RouteParams = {
  "/": {};
  "/dashboard": {};
  "/orders": {};
  "/orders/:id": { id: string };
  "/orders/:orderId/items/:itemId": { orderId: string; itemId: string };
};

export const paths = createTypedPaths<RouteParams>();

export type { RouteParams };
```

### Usage with TypeScript

```tsx theme={null}
import { useNavigate } from "@tailor-platform/app-shell";
import { paths } from "./routes.generated";

const MyComponent = () => {
  const navigate = useNavigate();

  // ✅ Static route - no params needed
  const goToDashboard = () => {
    navigate(paths.for("/dashboard"));
  };

  // ✅ Dynamic route - params required and type-checked
  const goToOrder = (orderId: string) => {
    navigate(paths.for("/orders/:id", { id: orderId }));
  };

  // ✅ Multiple params
  const goToOrderItem = (orderId: string, itemId: string) => {
    navigate(paths.for("/orders/:orderId/items/:itemId", { orderId, itemId }));
  };

  // ✅ Query string passthrough
  const goToOrderWithTab = (orderId: string) => {
    navigate(paths.for("/orders/:id?tab=details", { id: orderId }));
  };

  // ✅ Dynamic query values via template literal
  const goToOrderWithDynamicQuery = (orderId: string, tab: string) => {
    navigate(paths.for(`/orders/:id?tab=${tab}`, { id: orderId }));
  };

  // ❌ TypeScript error: missing required params
  // navigate(paths.for("/orders/:id"));

  // ❌ TypeScript error: invalid path
  // navigate(paths.for("/invalid/path"));

  return <button onClick={goToDashboard}>Go to Dashboard</button>;
};
```

### Benefits

<CardGroup cols={2}>
  <Card title="Compile-time safety" icon="shield-check">
    TypeScript catches invalid routes and missing parameters before runtime
  </Card>

  <Card title="Auto-completion" icon="keyboard">
    IDE autocomplete for all routes and their required parameters
  </Card>

  <Card title="Refactoring support" icon="rotate">
    Rename routes and parameters with confidence
  </Card>

  <Card title="Opt-in design" icon="toggle-on">
    Use only when needed—manual path strings still work
  </Card>
</CardGroup>

### Opt-in design

Typed routes are completely optional. Without `generateTypedRoutes`, you can continue building paths dynamically:

```tsx theme={null}
// Still works without typed routes
navigate(`/orders/${orderId}`);
```

### HMR support

The generated file automatically updates when:

* A new `page.tsx` is added
* A `page.tsx` is deleted
* The dev server starts

<Note>
  The file regenerates automatically during development, so your types always stay in sync with your routes.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="File-based routing" icon="folder-tree" href="/concepts/file-based-routing">
    Define routes using directory structure
  </Card>

  <Card title="Modules and resources" icon="sitemap" href="/concepts/modules-and-resources">
    Understand AppShell's routing architecture
  </Card>
</CardGroup>
