---
url: /frontend/link-navigation.md
description: >-
  Link component wrapping each framework's native router with compile-time route
  validation. Autocomplete navigation targets, parameter enforcement, and query
  string handling for React, SolidJS, Vue, Svelte and MDX.
---

The `Link` component wraps each framework's native router link with compile-time route validation.
It knows your complete route structure and parameters, delivering autocomplete and type checking throughout navigation code.

The component is available at `components/Link.{tsx,vue,svelte}` in your source folder.

## Usage

The API is consistent across all frameworks - a `to` prop accepting a
typed tuple, an optional `query` prop for search parameters, and standard
router props passed through:

### Type-Safe Navigation | Usage | Menu.tsx

```tsx
// Menu.tsx
import Link from "~/components/Link";

export default function Menu() {
  return (
    <nav>
      {/* Navigate to a static route */}
      <Link to={["index"]}>Home</Link>

      {/* Navigate with a required parameter */}
      <Link to={["users/[id]", 123]}>User Profile</Link>

      {/* Navigate with a parameter and query string */}
      <Link to={["posts/[slug]", "hello-world"]} query={{ ref: "sidebar" }}>
        Blog Post
      </Link>
    </nav>
  );
}
```

### Type-Safe Navigation | Usage | Menu.vue

```vue
<!-- Menu.vue -->
<script setup lang="ts">
import Link from "~/components/Link.vue";
</script>

<template>
  <nav>
    <!-- Navigate to a static route -->
    <Link :to="['index']">Home</Link>

    <!-- Navigate with a required parameter -->
    <Link :to="['users/[id]', 123]">User Profile</Link>

    <!-- Navigate with a parameter and query string -->
    <Link :to="['posts/[slug]', 'hello-world']" :query="{ ref: 'sidebar' }">
      Blog Post
    </Link>
  </nav>
</template>
```

### Type-Safe Navigation | Usage | Menu.svelte

```svelte
<!-- Menu.svelte -->
<script lang="ts">
import Link from "~/components/Link.svelte";
</script>

<nav>
  <!-- Navigate to a static route -->
  <Link to={["index"]}>Home</Link>

  <!-- Navigate with a required parameter -->
  <Link to={["users/[id]", 123]}>User Profile</Link>

  <!-- Navigate with a parameter and query string -->
  <Link to={["posts/[slug]", "hello-world"]} query={{ ref: "sidebar" }}>
    Blog Post
  </Link>
</nav>
```

## LinkProps Type

The `to` prop is typed as `LinkProps` - a discriminated union derived from
your route structure:

```ts
export type LinkProps =
  | ["index"]
  | ["users/[id]", id: string | number]
  | ["posts/[slug]", slug: string]
  // ... all other routes
```

Typing the first array element triggers TypeScript's IntelliSense with valid
route suggestions. Selecting a parameterized route requires providing those
parameters as subsequent array elements - the type system enforces this.

Renaming a route directory produces TypeScript errors at every `Link`
referencing the old name, turning refactors into an automated checklist.
