studio/frontend: friendlier 404 fallback for unknown routes (#5664)
* studio/frontend: friendlier 404 fallback for unknown routes TanStack Router defaults to a bare "Not Found" string when no route matches. With Studio's root layout that string sits alone in the main content area while the sidebar still renders, which looks broken when the user hits a typo'd path, a stale share link, or a chat URL with an extra path segment. Provide a small DefaultNotFound component to createRouter: sloth mascot, "Page not found" heading, the offending pathname, and a Back to chat button. Studio chrome continues to render around it, so the user gets the same sidebar nav for free. Resolves #5663. * studio/frontend: 404 fallback uses useRouterState + URL-encoded sloth path Address review feedback on #5664: - Read pathname via useRouterState({ select: s => s.location.pathname }) instead of window.location.pathname. Matches the pattern already used in __root.tsx, drops the window-typeof guard, and stays consistent with the router store on subsequent client navigations. - URL-encode the sloth mascot src so the space-containing path resolves cleanly without relying on the browser to encode it. - Add break-all on the pathname paragraph so long offending URLs wrap instead of pushing the card wider than the viewport. --------- Co-authored-by: danielhanchen <michaelhan2050@gmail.com>
This commit is contained in:
parent
966d3cda47
commit
43beeae39d
1 changed files with 30 additions and 2 deletions
|
|
@ -1,7 +1,8 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import { createRouter } from "@tanstack/react-router";
|
||||
import { Link, createRouter, useRouterState } from "@tanstack/react-router";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Route as rootRoute } from "./routes/__root";
|
||||
import { Route as dataRecipesRoute } from "./routes/data-recipes";
|
||||
import { Route as dataRecipeRoute } from "./routes/data-recipes.$recipeId";
|
||||
|
|
@ -29,7 +30,34 @@ const routeTree = rootRoute.addChildren([
|
|||
dataRecipeRoute,
|
||||
]);
|
||||
|
||||
export const router = createRouter({ routeTree });
|
||||
function DefaultNotFound() {
|
||||
const pathname = useRouterState({ select: (s) => s.location.pathname });
|
||||
return (
|
||||
<div className="flex flex-1 flex-col items-center justify-center gap-4 p-8 text-center">
|
||||
<img
|
||||
src="/Sloth%20emojis/sloth%20shy%20large.png"
|
||||
alt="Sloth mascot"
|
||||
className="size-24"
|
||||
/>
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
<h1 className="font-heading font-semibold text-2xl tracking-tight">
|
||||
Page not found
|
||||
</h1>
|
||||
<p className="text-muted-foreground text-sm break-all">
|
||||
{pathname} does not exist.
|
||||
</p>
|
||||
</div>
|
||||
<Button asChild>
|
||||
<Link to="/chat">Back to chat</Link>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const router = createRouter({
|
||||
routeTree,
|
||||
defaultNotFoundComponent: DefaultNotFound,
|
||||
});
|
||||
|
||||
declare module "@tanstack/react-router" {
|
||||
interface Register {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue