Framework
Version

Routing-Konzepte

TanStack Router unterstΓΌtzt eine Reihe von leistungsstarken Routing-Konzepten, mit denen Sie komplexe und dynamische Routing-Systeme einfach erstellen kΓΆnnen.

Jedes dieser Konzepte ist nΓΌtzlich und leistungsstark, und wir werden uns in den folgenden Abschnitten mit jedem einzelnen befassen.

Anatomie einer Route

Alle anderen Routen, außer der Root-Route, werden mit der Funktion createFileRoute konfiguriert, die Typsicherheit bei der Verwendung von Dateibasiertem Routing bietet.

tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/')({
  component: PostsComponent,
})
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/')({
  component: PostsComponent,
})

Die Funktion createFileRoute nimmt ein einziges Argument entgegen, den Pfad der Datei-Route als String.

❓❓❓ β€žMoment, Sie lassen mich den Pfad der Routendatei an createFileRoute ΓΌbergeben?β€œ

Ja! Aber keine Sorge, dieser Pfad wird automatisch vom Router fΓΌr Sie ΓΌber das TanStack Router Bundler Plugin oder den Router CLI geschrieben und verwaltet. Wenn Sie also neue Routen erstellen, Routen verschieben oder umbenennen, wird der Pfad automatisch fΓΌr Sie aktualisiert.

Der Grund fΓΌr diesen Pfadnamen hat alles mit der magischen Typsicherheit von TanStack Router zu tun. Ohne diesen Pfadnamen wΓΌsste TypeScript nicht, in welcher Datei wir uns befinden! (Wir wΓΌnschen uns, dass TypeScript dafΓΌr eine integrierte Funktion hΓ€tte, aber das gibt es noch nicht πŸ€·β€β™‚οΈ)

Die Root-Route

Die Root-Route ist die oberste Route im gesamten Baum und kapselt alle anderen Routen als Kinder.

  • Sie hat keinen Pfad
  • Sie wird immer abgeglichen
  • Ihre component wird immer gerendert

Obwohl sie keinen Pfad hat, hat die Root-Route Zugriff auf alle Funktionen wie andere Routen, einschließlich

  • Komponenten
  • Loader
  • Suchparameter-Validierung
  • usw.

Um eine Root-Route zu erstellen, rufen Sie die Funktion createRootRoute() auf und exportieren Sie sie als Variable Route in Ihrer Routendatei.

tsx
// Standard root route
import { createRootRoute } from '@tanstack/solid-router'

export const Route = createRootRoute()

// Root route with Context
import { createRootRouteWithContext } from '@tanstack/solid-router'
import type { QueryClient } from '@tanstack/react-query'

export interface MyRouterContext {
  queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()
// Standard root route
import { createRootRoute } from '@tanstack/solid-router'

export const Route = createRootRoute()

// Root route with Context
import { createRootRouteWithContext } from '@tanstack/solid-router'
import type { QueryClient } from '@tanstack/react-query'

export interface MyRouterContext {
  queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()

Um mehr ΓΌber Kontexte in TanStack Router zu erfahren, lesen Sie den Leitfaden Router Context.

Basics Routen

Grundlegende Routen stimmen mit einem bestimmten Pfad ΓΌberein, z. B. sind /about, /settings und /settings/notifications alles grundlegende Routen, da sie exakt mit dem Pfad ΓΌbereinstimmen.

Werfen wir einen Blick auf eine /about Route

tsx
// about.tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/about')({
  component: AboutComponent,
})

function AboutComponent() {
  return <div>About</div>
}
// about.tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/about')({
  component: AboutComponent,
})

function AboutComponent() {
  return <div>About</div>
}

Grundlegende Routen sind einfach und unkompliziert. Sie stimmen exakt mit dem Pfad ΓΌberein und rendern die bereitgestellte Komponente.

Index-Routen

Index-Routen zielen speziell auf ihre Elternroute ab, wenn diese exakt ΓΌbereinstimmt und keine Kindroute ΓΌbereinstimmt.

Werfen wir einen Blick auf eine Index-Route fΓΌr eine /posts URL

tsx
// posts.index.tsx
import { createFileRoute } from '@tanstack/solid-router'

// Note the trailing slash, which is used to target index routes
export const Route = createFileRoute('/posts/')({
  component: PostsIndexComponent,
})

function PostsIndexComponent() {
  return <div>Please select a post!</div>
}
// posts.index.tsx
import { createFileRoute } from '@tanstack/solid-router'

// Note the trailing slash, which is used to target index routes
export const Route = createFileRoute('/posts/')({
  component: PostsIndexComponent,
})

function PostsIndexComponent() {
  return <div>Please select a post!</div>
}

Diese Route wird abgeglichen, wenn die URL exakt /posts lautet.

Dynamische Routensegmente

Routenpfadsegmente, die mit einem $ gefolgt von einem Label beginnen, sind dynamisch und erfassen diesen Teil der URL in das params Objekt zur Verwendung in Ihrer Anwendung. Zum Beispiel wΓΌrde ein Pfadname von /posts/123 mit der Route /posts/$postId ΓΌbereinstimmen, und das params Objekt wΓ€re { postId: '123' }.

Diese Parameter kΓΆnnen dann in der Konfiguration und den Komponenten Ihrer Route verwendet werden! Sehen wir uns eine Route posts.$postId.tsx an

tsx
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts/$postId')({
  // In a loader
  loader: ({ params }) => fetchPost(params.postId),
  // Or in a component
  component: PostComponent,
})

function PostComponent() {
  // In a component!
  const { postId } = Route.useParams()
  return <div>Post ID: {postId}</div>
}
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts/$postId')({
  // In a loader
  loader: ({ params }) => fetchPost(params.postId),
  // Or in a component
  component: PostComponent,
})

function PostComponent() {
  // In a component!
  const { postId } = Route.useParams()
  return <div>Post ID: {postId}</div>
}

🧠 Dynamische Segmente funktionieren in jedem Pfadsegment. Sie kânnten zum Beispiel eine Route mit dem Pfad /posts/$postId/$revisionId haben, und jedes $ Segment würde in das params Objekt erfasst werden.

Splat / Catch-All Routen

Eine Route mit einem Pfad von nur $ wird als β€žSplatβ€œ-Route bezeichnet, da sie immer jeden verbleibenden Teil des URL-Pfadnamens vom $ bis zum Ende erfasst. Der erfasste Pfadname ist dann im params Objekt unter der speziellen Eigenschaft _splat verfΓΌgbar.

Zum Beispiel ist eine Route, die auf den Pfad files/$ abzielt, eine Splat-Route. Wenn der URL-Pfadname /files/documents/hello-world lautet, wΓΌrde das params Objekt documents/hello-world unter der speziellen Eigenschaft _splat enthalten.

js
{
  '_splat': 'documents/hello-world'
}
{
  '_splat': 'documents/hello-world'
}

⚠️ In v1 des Routers werden Splat-Routen aus Gründen der AbwÀrtskompatibilitÀt auch mit einem * anstelle eines _splat Schlüssels bezeichnet. Dies wird in v2 entfernt.

🧠 Warum $ verwenden? Dank Tools wie Remix wissen wir, dass, obwohl * das gebrÀuchlichste Zeichen zur Darstellung eines Wildcards sind, sie nicht gut mit Dateinamen oder CLI-Tools zusammenarbeiten. Daher haben wir uns, genau wie sie, entschieden, stattdessen $ zu verwenden.

Optionale Pfadparameter

Optionale Pfadparameter ermΓΆglichen es Ihnen, Routensegmente zu definieren, die in der URL vorhanden sein kΓΆnnen oder nicht. Sie verwenden die Syntax {-$paramName} und bieten flexible Routing-Muster, bei denen bestimmte Parameter optional sind.

tsx
// posts.{-$category}.tsx - Optional category parameter
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts/{-$category}')({
  component: PostsComponent,
})

function PostsComponent() {
  const { category } = Route.useParams()

  return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>
}
// posts.{-$category}.tsx - Optional category parameter
import { createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts/{-$category}')({
  component: PostsComponent,
})

function PostsComponent() {
  const { category } = Route.useParams()

  return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>
}

Diese Route stimmt sowohl mit /posts (Kategorie ist undefined) als auch mit /posts/tech (Kategorie ist "tech") ΓΌberein.

Sie kΓΆnnen auch mehrere optionale Parameter in einer einzigen Route definieren

tsx
// posts.{-$category}.{-$slug}.tsx
export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
  component: PostsComponent,
})
// posts.{-$category}.{-$slug}.tsx
export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
  component: PostsComponent,
})

Diese Route stimmt mit /posts, /posts/tech und /posts/tech/hello-world ΓΌberein.

🧠 Routen mit optionalen Parametern haben eine niedrigere PrioritÀt als exakte Übereinstimmungen, um sicherzustellen, dass spezifischere Routen wie /posts/featured vor /posts/{-$category} abgeglichen werden.

Layout-Routen

Layout-Routen werden verwendet, um Kindrouten mit zusÀtzlichen Komponenten und Logik zu umschließen. Sie sind nützlich für

  • Umschließen von Kindrouten mit einer Layout-Komponente
  • Erzwingen einer loader-Anforderung, bevor Kindrouten angezeigt werden
  • Validieren und Bereitstellen von Suchparametern fΓΌr Kindrouten
  • Bereitstellen von Fallbacks fΓΌr Fehlerkomponenten oder ausstehende Elemente fΓΌr Kindrouten
  • Bereitstellen eines gemeinsamen Kontexts fΓΌr alle Kindrouten
  • Und mehr!

Werfen wir einen Blick auf eine Beispiel-Layout-Route namens app.tsx

routes/
β”œβ”€β”€ app.tsx
β”œβ”€β”€ app.dashboard.tsx
β”œβ”€β”€ app.settings.tsx
routes/
β”œβ”€β”€ app.tsx
β”œβ”€β”€ app.dashboard.tsx
β”œβ”€β”€ app.settings.tsx

Im obigen Baum ist app.tsx eine Layout-Route, die zwei Kindrouten umschließt: app.dashboard.tsx und app.settings.tsx.

Diese Baumstruktur wird verwendet, um die Kindrouten mit einer Layout-Komponente zu umschließen.

tsx
import { Outlet, createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/app')({
  component: AppLayoutComponent,
})

function AppLayoutComponent() {
  return (
    <div>
      <h1>App Layout</h1>
      <Outlet />
    </div>
  )
}
import { Outlet, createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/app')({
  component: AppLayoutComponent,
})

function AppLayoutComponent() {
  return (
    <div>
      <h1>App Layout</h1>
      <Outlet />
    </div>
  )
}

Die folgende Tabelle zeigt, welche Komponente(n) basierend auf der URL gerendert werden.

URL-PfadKomponente
/app<AppLayout>
/app/dashboard<AppLayout><Dashboard>
/app/settings<AppLayout><Settings>

Da TanStack Router gemischte flache und Verzeichnisrouten unterstΓΌtzt, kΓΆnnen Sie das Routing Ihrer Anwendung auch mithilfe von Layout-Routen innerhalb von Verzeichnissen ausdrΓΌcken.

routes/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ route.tsx
β”‚   β”œβ”€β”€ dashboard.tsx
β”‚   β”œβ”€β”€ settings.tsx
routes/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ route.tsx
β”‚   β”œβ”€β”€ dashboard.tsx
β”‚   β”œβ”€β”€ settings.tsx

In diesem verschachtelten Baum ist die Datei app/route.tsx eine Konfiguration für die Layout-Route, die zwei Kindrouten umschließt: app/dashboard.tsx und app/settings.tsx.

Layout-Routen ermΓΆglichen es Ihnen auch, Komponenten- und Loaderlogik fΓΌr dynamische Routensegmente zu erzwingen.

routes/
β”œβ”€β”€ app/users/
β”‚   β”œβ”€β”€ $userId/
|   |   β”œβ”€β”€ route.tsx
|   |   β”œβ”€β”€ index.tsx
|   |   β”œβ”€β”€ edit.tsx
routes/
β”œβ”€β”€ app/users/
β”‚   β”œβ”€β”€ $userId/
|   |   β”œβ”€β”€ route.tsx
|   |   β”œβ”€β”€ index.tsx
|   |   β”œβ”€β”€ edit.tsx

Pfadlose Layout-Routen

Γ„hnlich wie Layout-Routen werden pfadlose Layout-Routen verwendet, um Kindrouten mit zusΓ€tzlichen Komponenten und Logik zu umschließen. Pfadlose Layout-Routen erfordern jedoch keinen ΓΌbereinstimmenden path in der URL und werden verwendet, um Kindrouten mit zusΓ€tzlichen Komponenten und Logik zu umschließen, ohne dass ein ΓΌbereinstimmender path in der URL erforderlich ist.

Pfadlose Layout-Routen werden mit einem Unterstrich (_) prΓ€fixiert, um anzuzeigen, dass sie "pfadlos" sind.

🧠 Der Teil des Pfades nach dem _ PrÀfix wird als ID der Route verwendet und ist erforderlich, da jede Route eindeutig identifizierbar sein muss, insbesondere bei der Verwendung von TypeScript, um Fehler zu vermeiden und AutovervollstÀndigung effektiv zu nutzen.

Werfen wir einen Blick auf eine Beispielroute namens _pathlessLayout.tsx


routes/
β”œβ”€β”€ _pathlessLayout.tsx
β”œβ”€β”€ _pathlessLayout.a.tsx
β”œβ”€β”€ _pathlessLayout.b.tsx

routes/
β”œβ”€β”€ _pathlessLayout.tsx
β”œβ”€β”€ _pathlessLayout.a.tsx
β”œβ”€β”€ _pathlessLayout.b.tsx

Im obigen Baum ist _pathlessLayout.tsx eine pfadlose Layout-Route, die zwei Kindrouten umschließt: _pathlessLayout.a.tsx und _pathlessLayout.b.tsx.

Die Route _pathlessLayout.tsx wird verwendet, um die Kindrouten mit einer pfadlosen Layout-Komponente zu umschließen.

tsx
import { Outlet, createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/_pathlessLayout')({
  component: PathlessLayoutComponent,
})

function PathlessLayoutComponent() {
  return (
    <div>
      <h1>Pathless layout</h1>
      <Outlet />
    </div>
  )
}
import { Outlet, createFileRoute } from '@tanstack/solid-router'

export const Route = createFileRoute('/_pathlessLayout')({
  component: PathlessLayoutComponent,
})

function PathlessLayoutComponent() {
  return (
    <div>
      <h1>Pathless layout</h1>
      <Outlet />
    </div>
  )
}

Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.

URL-PfadKomponente
/<Index>
/a<PathlessLayout><A>
/b<PathlessLayout><B>

Da TanStack Router gemischte flache und Verzeichnisrouten unterstΓΌtzt, kΓΆnnen Sie Ihr Anwendungsrouting auch mithilfe von pfadlosen Layout-Routen innerhalb von Verzeichnissen ausdrΓΌcken.

routes/
β”œβ”€β”€ _pathlessLayout/
β”‚   β”œβ”€β”€ route.tsx
β”‚   β”œβ”€β”€ a.tsx
β”‚   β”œβ”€β”€ b.tsx
routes/
β”œβ”€β”€ _pathlessLayout/
β”‚   β”œβ”€β”€ route.tsx
β”‚   β”œβ”€β”€ a.tsx
β”‚   β”œβ”€β”€ b.tsx

Im Gegensatz zu Layout-Routen passen diese pfadlosen Layout-Routen jedoch nicht basierend auf URL-Pfadsegmenten, was bedeutet, dass diese Routen keine dynamischen Routensegmente in ihrem Pfad unterstΓΌtzen und daher nicht in der URL abgeglichen werden kΓΆnnen.

Das bedeutet, dass Sie dies nicht tun kΓΆnnen

routes/
β”œβ”€β”€ _$postId/ ❌
β”‚   β”œβ”€β”€ ...
routes/
β”œβ”€β”€ _$postId/ ❌
β”‚   β”œβ”€β”€ ...

Stattdessen mΓΌssten Sie dies tun

routes/
β”œβ”€β”€ $postId/
β”œβ”€β”€ _postPathlessLayout/ βœ…
β”‚   β”œβ”€β”€ ...
routes/
β”œβ”€β”€ $postId/
β”œβ”€β”€ _postPathlessLayout/ βœ…
β”‚   β”œβ”€β”€ ...

Nicht-verschachtelte Routen

Nicht verschachtelte Routen kΓΆnnen erstellt werden, indem ein Eltern-Datei-Routensegment mit einem _ angehΓ€ngt wird. Sie werden verwendet, um eine Route von ihren Eltern zu ent-verschachteln und ihren eigenen Komponentenbaum zu rendern.

Betrachten Sie den folgenden flachen Routenbaum

routes/
β”œβ”€β”€ posts.tsx
β”œβ”€β”€ posts.$postId.tsx
β”œβ”€β”€ posts_.$postId.edit.tsx
routes/
β”œβ”€β”€ posts.tsx
β”œβ”€β”€ posts.$postId.tsx
β”œβ”€β”€ posts_.$postId.edit.tsx

Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.

URL-PfadKomponente
/posts<Posts>
/posts/123<Posts><Post postId="123">
/posts/123/edit<PostEditor postId="123">
  • Die Route posts.$postId.tsx ist wie gewohnt unter der Route posts.tsx verschachtelt und rendert <Posts><Post>.
  • Die Route posts_.$postId.edit.tsx teilt nicht denselben posts PrΓ€fix wie die anderen Routen und wird daher als Top-Level-Route behandelt und rendert <PostEditor>.

Dateien und Ordner von Routen ausschließen

Dateien und Ordner kΓΆnnen von der Routengenerierung ausgeschlossen werden, indem ein - PrΓ€fix an den Dateinamen angehΓ€ngt wird. Dies gibt Ihnen die MΓΆglichkeit, Logik in den Routenverzeichnissen zu lokalisieren.

Betrachten Sie den folgenden Routenbaum

routes/
β”œβ”€β”€ posts.tsx
β”œβ”€β”€ -posts-table.tsx // πŸ‘ˆπŸΌ ignored
β”œβ”€β”€ -components/ // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ header.tsx // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ footer.tsx // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ ...
routes/
β”œβ”€β”€ posts.tsx
β”œβ”€β”€ -posts-table.tsx // πŸ‘ˆπŸΌ ignored
β”œβ”€β”€ -components/ // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ header.tsx // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ footer.tsx // πŸ‘ˆπŸΌ ignored
β”‚   β”œβ”€β”€ ...

Wir kΓΆnnen aus den ausgeschlossenen Dateien in unsere Posts-Route importieren.

tsx
import { createFileRoute } from '@tanstack/solid-router'
import { PostsTable } from './-posts-table'
import { PostsHeader } from './-components/header'
import { PostsFooter } from './-components/footer'

export const Route = createFileRoute('/posts')({
  loader: () => fetchPosts(),
  component: PostComponent,
})

function PostComponent() {
  const posts = Route.useLoaderData()

  return (
    <div>
      <PostsHeader />
      <PostsTable posts={posts} />
      <PostsFooter />
    </div>
  )
}
import { createFileRoute } from '@tanstack/solid-router'
import { PostsTable } from './-posts-table'
import { PostsHeader } from './-components/header'
import { PostsFooter } from './-components/footer'

export const Route = createFileRoute('/posts')({
  loader: () => fetchPosts(),
  component: PostComponent,
})

function PostComponent() {
  const posts = Route.useLoaderData()

  return (
    <div>
      <PostsHeader />
      <PostsTable posts={posts} />
      <PostsFooter />
    </div>
  )
}

Die ausgeschlossenen Dateien werden nicht zu routeTree.gen.ts hinzugefΓΌgt.

Pfadlose Routengruppenverzeichnisse

Pfadlose Routengruppenverzeichnisse verwenden (), um Routendateien unabhΓ€ngig von ihrem Pfad zu gruppieren. Sie sind rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise.

routes/
β”œβ”€β”€ index.tsx
β”œβ”€β”€ (app)/
β”‚   β”œβ”€β”€ dashboard.tsx
β”‚   β”œβ”€β”€ settings.tsx
β”‚   β”œβ”€β”€ users.tsx
β”œβ”€β”€ (auth)/
β”‚   β”œβ”€β”€ login.tsx
β”‚   β”œβ”€β”€ register.tsx
routes/
β”œβ”€β”€ index.tsx
β”œβ”€β”€ (app)/
β”‚   β”œβ”€β”€ dashboard.tsx
β”‚   β”œβ”€β”€ settings.tsx
β”‚   β”œβ”€β”€ users.tsx
β”œβ”€β”€ (auth)/
β”‚   β”œβ”€β”€ login.tsx
β”‚   β”œβ”€β”€ register.tsx

Im obigen Beispiel sind die Verzeichnisse app und auth rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise. Sie werden verwendet, um zusammengehΓΆrige Routen zur einfacheren Navigation und Organisation zu gruppieren.

Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.

URL-PfadKomponente
/<Index>
/dashboard<Dashboard>
/settings<Settings>
/users<Users>
/login<Login>
/register<Register>

Wie Sie sehen, sind die Verzeichnisse app und auth rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise.

Unsere Partner
Code Rabbit
Netlify
Neon
Clerk
Convex
Sentry
Bytes abonnieren

Ihre wΓΆchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an ΓΌber 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kΓΌndbar.

Bytes abonnieren

Ihre wΓΆchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an ΓΌber 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kΓΌndbar.