Fehler "Nicht gefunden" (Not Found Errors)

⚠️ Diese Seite behandelt die neuere notFound Funktion und die notFoundComponent API zur Behandlung von Nicht gefunden Fehlern. Die Route NotFoundRoute ist veraltet und wird in einer zukünftigen Version entfernt. Weitere Informationen finden Sie unter Migration von NotFoundRoute.

Übersicht

Es gibt 2 Anwendungsfälle für Nicht gefunden Fehler in TanStack Router

  • Nicht übereinstimmende Pfade: Wenn ein Pfad keinem bekannten Routenmuster entspricht ODER wenn er teilweise mit einer Route übereinstimmt, aber zusätzliche Pfadsegmente aufweist.
    • Der Router löst automatisch einen Nicht gefunden Fehler aus, wenn ein Pfad keinem bekannten Routenmuster entspricht.
    • Wenn der notFoundMode des Routers auf fuzzy gesetzt ist, wird die nächstgelegene übergeordnete Route mit einer notFoundComponent den Fehler behandeln. Wenn der notFoundMode des Routers auf root gesetzt ist, wird die Root-Route den Fehler behandeln.
    • Beispiele
      • Versuch, auf /users zuzugreifen, wenn es keine /users Route gibt
      • Versuch, auf /posts/1/edit zuzugreifen, wenn der Routenbaum nur /posts/$postId behandelt.
  • Fehlende Ressourcen: Wenn eine Ressource nicht gefunden werden kann, z. B. ein Beitrag mit einer bestimmten ID oder beliebige asynchrone Daten, die nicht verfügbar oder nicht vorhanden sind.
    • Sie, der Entwickler, müssen einen Nicht gefunden Fehler auslösen, wenn eine Ressource nicht gefunden werden kann. Dies kann in den Funktionen beforeLoad oder loader unter Verwendung des notFound Hilfsprogramms erfolgen.
    • Wird von der nächstgelegenen übergeordneten Route mit einer notFoundComponent behandelt (wenn notFound innerhalb von loader aufgerufen wird) oder von der Root-Route.
    • Beispiele
      • Versuch, auf /posts/1 zuzugreifen, wenn der Beitrag mit der ID 1 nicht existiert.
      • Versuch, auf /docs/path/to/document zuzugreifen, wenn das Dokument nicht existiert.

Intern werden beide Fälle mit derselben notFound Funktion und notFoundComponent API implementiert.

Die Option notFoundMode

Wenn TanStack Router auf einen Pfadnamen stößt, der keinem bekannten Routenmuster entspricht ODER teilweise einem Routenmuster entspricht, aber zusätzliche Pfadsegmente aufweist, löst er automatisch einen Nicht gefunden Fehler aus.

Abhängig von der Option notFoundMode behandelt der Router diese automatischen Fehler unterschiedlich:

  • "fuzzy" Modus (Standard): Der Router findet intelligent die nächstgelegene passende geeignete Route und zeigt die notFoundComponent an.
  • "root" Modus: Alle Nicht gefunden Fehler werden von der notFoundComponent der Root-Route behandelt, unabhängig von der nächstgelegenen übereinstimmenden Route.

notFoundMode: 'fuzzy'

Standardmäßig ist der notFoundMode des Routers auf fuzzy eingestellt. Dies bedeutet, dass der Router, wenn ein Pfadname keiner bekannten Route entspricht, versucht, die nächstgelegene übereinstimmende Route mit Kindern/(einem Outlet) und einer konfigurierten Nicht gefunden Komponente zu verwenden.

❓ Warum ist das der Standard? Fuzzy-Matching bewahrt so viel wie möglich vom übergeordneten Layout für den Benutzer, was ihm mehr Kontext gibt, um zu einem nützlichen Ort zu navigieren, basierend darauf, wo er anzukommen dachte.

Die nächstgelegene geeignete Route wird anhand der folgenden Kriterien gefunden

  • Die Route muss Kinder und damit ein Outlet zum Rendern der notFoundComponent haben.
  • Die Route muss eine konfigurierte notFoundComponent haben oder der Router muss eine konfigurierte defaultNotFoundComponent haben.

Betrachten Sie zum Beispiel den folgenden Routenbaum

  • __root__ (hat eine konfigurierte notFoundComponent)
    • posts (hat eine konfigurierte notFoundComponent)
      • $postId (hat eine konfigurierte notFoundComponent)

Bei Angabe des Pfads /posts/1/edit wird die folgende Komponentenstruktur gerendert

  • <Root>
    • <Posts>
      • <Posts.notFoundComponent>

Die notFoundComponent der posts Route wird gerendert, da es sich um die nächstgelegene geeignete übergeordnete Route mit Kindern (und damit einem Outlet) und einer konfigurierten notFoundComponent handelt.

notFoundMode: 'root'

Wenn notFoundMode auf root gesetzt ist, werden alle Nicht gefunden Fehler von der notFoundComponent der Root-Route behandelt, anstatt von der nächstgelegenen Fuzzy-übereinstimmenden Route nach oben zu propagieren.

Betrachten Sie zum Beispiel den folgenden Routenbaum

  • __root__ (hat eine konfigurierte notFoundComponent)
    • posts (hat eine konfigurierte notFoundComponent)
      • $postId (hat eine konfigurierte notFoundComponent)

Bei Angabe des Pfads /posts/1/edit wird die folgende Komponentenstruktur gerendert

  • <Root>
    • <Root.notFoundComponent>

Die notFoundComponent der __root__ Route wird gerendert, da der notFoundMode auf root gesetzt ist.

Konfigurieren einer notFoundComponent für eine Route

Um beide Arten von Nicht gefunden Fehlern zu behandeln, können Sie eine notFoundComponent an eine Route anhängen. Diese Komponente wird gerendert, wenn ein Nicht gefunden Fehler ausgelöst wird.

Zum Beispiel das Konfigurieren einer notFoundComponent für eine /settings Route, um nicht existierende Einstellungsseiten zu behandeln.

tsx
export const Route = createFileRoute('/settings')({
  component: () => {
    return (
      <div>
        <p>Settings page</p>
        <Outlet />
      </div>
    )
  },
  notFoundComponent: () => {
    return <p>This setting page doesn't exist!</p>
  },
})
export const Route = createFileRoute('/settings')({
  component: () => {
    return (
      <div>
        <p>Settings page</p>
        <Outlet />
      </div>
    )
  },
  notFoundComponent: () => {
    return <p>This setting page doesn't exist!</p>
  },
})

Oder das Konfigurieren einer notFoundComponent für eine /posts/$postId Route, um nicht existierende Beiträge zu behandeln.

tsx
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post) throw notFound()
    return { post }
  },
  component: ({ post }) => {
    return (
      <div>
        <h1>{post.title}</h1>
        <p>{post.body}</p>
      </div>
    )
  },
  notFoundComponent: () => {
    return <p>Post not found!</p>
  },
})
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post) throw notFound()
    return { post }
  },
  component: ({ post }) => {
    return (
      <div>
        <h1>{post.title}</h1>
        <p>{post.body}</p>
      </div>
    )
  },
  notFoundComponent: () => {
    return <p>Post not found!</p>
  },
})

Standardmäßige Router-weite Behandlung von Nicht gefunden Fehlern

Möglicherweise möchten Sie eine Standard-Nicht-gefunden-Komponente für jede Route in Ihrer App mit untergeordneten Routen bereitstellen.

Warum nur Routen mit Kindern? Leaf-Knoten-Routen (Routen ohne Kinder) rendern niemals ein Outlet und können daher keine Nicht gefunden Fehler behandeln.

Um dies zu tun, übergeben Sie eine defaultNotFoundComponent an die Funktion createRouter.

tsx
const router = createRouter({
  defaultNotFoundComponent: () => {
    return (
      <div>
        <p>Not found!</p>
        <Link to="/">Go home</Link>
      </div>
    )
  },
})
const router = createRouter({
  defaultNotFoundComponent: () => {
    return (
      <div>
        <p>Not found!</p>
        <Link to="/">Go home</Link>
      </div>
    )
  },
})

Auslösen eigener notFound Fehler

Sie können Nicht gefunden Fehler manuell in Loader-Methoden und Komponenten mithilfe der Funktion notFound auslösen. Dies ist nützlich, wenn Sie signalisieren müssen, dass eine Ressource nicht gefunden werden kann.

Die Funktion notFound funktioniert ähnlich wie die Funktion redirect. Um einen Nicht gefunden Fehler zu verursachen, können Sie eine notFound() werfen.

tsx
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    // Returns `null` if the post doesn't exist
    const post = await getPost(postId)
    if (!post) {
      throw notFound()
      // Alternatively, you can make the notFound function throw:
      // notFound({ throw: true })
    }
    // Post is guaranteed to be defined here because we threw an error
    return { post }
  },
})
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    // Returns `null` if the post doesn't exist
    const post = await getPost(postId)
    if (!post) {
      throw notFound()
      // Alternatively, you can make the notFound function throw:
      // notFound({ throw: true })
    }
    // Post is guaranteed to be defined here because we threw an error
    return { post }
  },
})

Der obige Nicht gefunden Fehler wird von derselben Route oder nächstgelegenen übergeordneten Route behandelt, die entweder eine Routenoption notFoundComponent oder die Router-Option defaultNotFoundComponent konfiguriert hat.

Wenn weder die Route noch eine geeignete übergeordnete Route gefunden wird, um den Fehler zu behandeln, behandelt die Root-Route ihn mit der extrem einfachen (und bewusst unerwünschten) Standard-Nicht-gefunden-Komponente von TanStack Router, die einfach <div>Not Found</div> rendert. Es wird dringend empfohlen, entweder mindestens eine notFoundComponent an die Root-Route anzuhängen oder eine Router-weite defaultNotFoundComponent zu konfigurieren, um Nicht gefunden Fehler zu behandeln.

Festlegen, welche Routen Nicht gefunden Fehler behandeln

Manchmal möchten Sie möglicherweise einen Nicht gefunden Fehler für eine bestimmte übergeordnete Route auslösen und die normale Nicht gefunden Komponentenpropagierung umgehen. Um dies zu tun, übergeben Sie eine Routen-ID an die Option route in der Funktion notFound.

tsx
// _pathlessLayout.tsx
export const Route = createFileRoute('/_pathlessLayout')({
  // This will render
  notFoundComponent: () => {
    return <p>Not found (in _pathlessLayout)</p>
  },
  component: () => {
    return (
      <div>
        <p>This is a pathless layout route!</p>
        <Outlet />
      </div>
    )
  },
})

// _pathlessLayout/route-a.tsx
export const Route = createFileRoute('/_pathless/route-a')({
  loader: async () => {
    // This will make LayoutRoute handle the not-found error
    throw notFound({ routeId: '/_pathlessLayout' })
    //                      ^^^^^^^^^ This will autocomplete from the registered router
  },
  // This WILL NOT render
  notFoundComponent: () => {
    return <p>Not found (in _pathlessLayout/route-a)</p>
  },
})
// _pathlessLayout.tsx
export const Route = createFileRoute('/_pathlessLayout')({
  // This will render
  notFoundComponent: () => {
    return <p>Not found (in _pathlessLayout)</p>
  },
  component: () => {
    return (
      <div>
        <p>This is a pathless layout route!</p>
        <Outlet />
      </div>
    )
  },
})

// _pathlessLayout/route-a.tsx
export const Route = createFileRoute('/_pathless/route-a')({
  loader: async () => {
    // This will make LayoutRoute handle the not-found error
    throw notFound({ routeId: '/_pathlessLayout' })
    //                      ^^^^^^^^^ This will autocomplete from the registered router
  },
  // This WILL NOT render
  notFoundComponent: () => {
    return <p>Not found (in _pathlessLayout/route-a)</p>
  },
})

Manuelles Anvisieren der Root-Route

Sie können auch die Root-Route anvisieren, indem Sie die exportierte Variable rootRouteId an die Eigenschaft route der Funktion notFound übergeben.

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

export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post) throw notFound({ routeId: rootRouteId })
    return { post }
  },
})
import { rootRouteId } from '@tanstack/solid-router'

export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post) throw notFound({ routeId: rootRouteId })
    return { post }
  },
})

Auslösen von Nicht gefunden Fehlern in Komponenten

Sie können auch Nicht gefunden Fehler in Komponenten auslösen. Es wird jedoch empfohlen, Nicht gefunden Fehler in Loader-Methoden anstelle von Komponenten auszulösen, um die Typen der Loader-Daten korrekt zu definieren und Flackern zu verhindern.

TanStack Router stellt eine CatchNotFound Komponente zur Verfügung, ähnlich wie CatchBoundary, die verwendet werden kann, um Nicht gefunden Fehler in Komponenten abzufangen und die Benutzeroberfläche entsprechend anzuzeigen.

Datenladen innerhalb von notFoundComponent

notFoundComponent ist ein Sonderfall beim Datenladen. SomeRoute.useLoaderData ist möglicherweise nicht definiert, abhängig davon, auf welche Route Sie zugreifen und wo der Nicht gefunden Fehler ausgelöst wird. Jedoch geben Route.useParams, Route.useSearch, Route.useRouteContext usw. einen definierten Wert zurück.

Wenn Sie unvollständige Loader-Daten an notFoundComponent übergeben müssen, übergeben Sie die Daten über die Option data in der Funktion notFound und validieren Sie sie in notFoundComponent.

tsx
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post)
      throw notFound({
        // Forward some data to the notFoundComponent
        // data: someIncompleteLoaderData
      })
    return { post }
  },
  // `data: unknown` is passed to the component via the `data` option when calling `notFound`
  notFoundComponent: ({ data }) => {
    // ❌ useLoaderData is not valid here: const { post } = Route.useLoaderData()

    // ✅:
    const { postId } = Route.useParams()
    const search = Route.useSearch()
    const context = Route.useRouteContext()

    return <p>Post with id {postId} not found!</p>
  },
})
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params: { postId } }) => {
    const post = await getPost(postId)
    if (!post)
      throw notFound({
        // Forward some data to the notFoundComponent
        // data: someIncompleteLoaderData
      })
    return { post }
  },
  // `data: unknown` is passed to the component via the `data` option when calling `notFound`
  notFoundComponent: ({ data }) => {
    // ❌ useLoaderData is not valid here: const { post } = Route.useLoaderData()

    // ✅:
    const { postId } = Route.useParams()
    const search = Route.useSearch()
    const context = Route.useRouteContext()

    return <p>Post with id {postId} not found!</p>
  },
})

Verwendung mit SSR

Weitere Informationen finden Sie im SSR-Leitfaden.

Migration von NotFoundRoute

Die API NotFoundRoute ist zugunsten von notFoundComponent veraltet. Die API NotFoundRoute wird in einer zukünftigen Version entfernt.

Die Funktion notFound und die notFoundComponent funktionieren nicht, wenn NotFoundRoute verwendet wird.

Die Hauptunterschiede sind

  • NotFoundRoute ist eine Route, die ein <Outlet> auf ihrer übergeordneten Route zum Rendern benötigt. notFoundComponent ist eine Komponente, die an jede Route angehängt werden kann.
  • Bei Verwendung von NotFoundRoute können Sie keine Layouts verwenden. notFoundComponent kann mit Layouts verwendet werden.
  • Bei Verwendung von notFoundComponent ist die Pfadübereinstimmung streng. Das bedeutet, wenn Sie eine Route unter /post/$postId haben, wird ein Nicht gefunden Fehler ausgelöst, wenn Sie versuchen, auf /post/1/2/3 zuzugreifen. Mit NotFoundRoute würde /post/1/2/3 mit der NotFoundRoute übereinstimmen und diese nur rendern, wenn ein <Outlet> vorhanden ist.

Um von NotFoundRoute zu notFoundComponent zu migrieren, müssen Sie nur wenige Änderungen vornehmen.

tsx
// router.tsx
import { createRouter } from '@tanstack/solid-router'
import { routeTree } from './routeTree.gen.'
- import { notFoundRoute } from './notFoundRoute'  // [!code --]

export const router = createRouter({
  routeTree,
- notFoundRoute // [!code --]
})

// routes/__root.tsx
import { createRootRoute } from '@tanstack/solid-router'

export const Route = createRootRoute({
  // ...
+ notFoundComponent: () => {  // [!code ++]
+   return <p>Not found!</p>  // [!code ++]
+ } // [!code ++]
})
// router.tsx
import { createRouter } from '@tanstack/solid-router'
import { routeTree } from './routeTree.gen.'
- import { notFoundRoute } from './notFoundRoute'  // [!code --]

export const router = createRouter({
  routeTree,
- notFoundRoute // [!code --]
})

// routes/__root.tsx
import { createRootRoute } from '@tanstack/solid-router'

export const Route = createRootRoute({
  // ...
+ notFoundComponent: () => {  // [!code ++]
+   return <p>Not found!</p>  // [!code ++]
+ } // [!code ++]
})

Wichtige Änderungen

  • Eine notFoundComponent wird zur Root-Route für die globale Nicht gefunden-Behandlung hinzugefügt.
    • Sie können auch eine notFoundComponent zu jeder anderen Route in Ihrem Routenbaum hinzufügen, um Nicht gefunden Fehler für diese spezifische Route zu behandeln.
  • Die notFoundComponent unterstützt nicht das Rendern eines <Outlet>.
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.