Detailed changes
@@ -0,0 +1,37 @@
+import { Link, useCanGoBack, useRouter } from "@tanstack/react-router";
+import type { LinkProps } from "@tanstack/react-router";
+import { ArrowLeft } from "lucide-react";
+
+// A "Back to ..." link that uses browser history when available,
+// falling back to a typed Link destination otherwise.
+// This preserves scroll position and filter state when navigating
+// back from a detail page to a list.
+export function BackLink({
+ children,
+ ...fallbackProps
+}: LinkProps & { children: React.ReactNode }) {
+ const canGoBack = useCanGoBack();
+ const router = useRouter();
+
+ if (canGoBack) {
+ return (
+ <button
+ onClick={() => router.history.back()}
+ className="text-muted-foreground hover:text-foreground mb-4 flex items-center gap-1.5 text-sm"
+ >
+ <ArrowLeft className="size-3.5" />
+ {children}
+ </button>
+ );
+ }
+
+ return (
+ <Link
+ {...fallbackProps}
+ className="text-muted-foreground hover:text-foreground mb-4 flex items-center gap-1.5 text-sm"
+ >
+ <ArrowLeft className="size-3.5" />
+ {children}
+ </Link>
+ );
+}
@@ -1,7 +1,6 @@
import { useReadQuery } from "@apollo/client/react";
import { createFileRoute, Link } from "@tanstack/react-router";
import { formatDistanceToNow } from "date-fns";
-import { ArrowLeft } from "lucide-react";
import { type BugDetailQuery, BugDetailDocument } from "@/__generated__/graphql";
import { CommentBox } from "@/components/bugs/CommentBox";
@@ -10,6 +9,7 @@ import { StatusBadge } from "@/components/bugs/StatusBadge";
import { Timeline } from "@/components/bugs/Timeline";
import { TitleEditor } from "@/components/bugs/TitleEditor";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+import { BackLink } from "@/components/ui/back-link";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
@@ -42,15 +42,9 @@ function RouteComponent() {
return (
<div>
- <Link
- to="/$repo/issues"
- params={{ repo: repo }}
- search={{ q: "status:open", after: "" }}
- className="text-muted-foreground hover:text-foreground mb-4 flex items-center gap-1.5 text-sm"
- >
- <ArrowLeft className="size-3.5" />
+ <BackLink to="/$repo/issues" params={{ repo }} search={{ q: "status:open", after: "" }}>
Back to issues
- </Link>
+ </BackLink>
{/* Title row — hover reveals edit button when logged in */}
<div className="mb-3">
@@ -1,9 +1,9 @@
-import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
-import { ArrowLeft } from "lucide-react";
+import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useState } from "react";
import { useBugCreateMutation } from "@/__generated__/graphql";
import { Markdown } from "@/components/content/Markdown";
+import { BackLink } from "@/components/ui/back-link";
import { Button } from "@/components/ui/button";
import { ButtonLink } from "@/components/ui/button-link";
import { Input } from "@/components/ui/input";
@@ -38,15 +38,9 @@ function RouteComponent() {
return (
<div className="mx-auto max-w-3xl">
- <Link
- to="/$repo/issues"
- params={{ repo: repo }}
- search={{ q: "status:open", after: "" }}
- className="text-muted-foreground hover:text-foreground mb-6 flex items-center gap-1.5 text-sm"
- >
- <ArrowLeft className="size-3.5" />
+ <BackLink to="/$repo/issues" params={{ repo }} search={{ q: "status:open", after: "" }}>
Back to issues
- </Link>
+ </BackLink>
<h1 className="mb-6 text-xl font-semibold">New issue</h1>
@@ -9,7 +9,6 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { formatDistanceToNow } from "date-fns";
import {
- ArrowLeft,
MessageSquare,
CircleDot,
CircleCheck,
@@ -22,6 +21,7 @@ import { useState } from "react";
import { Status, useUserProfileQuery } from "@/__generated__/graphql";
import { LabelBadge } from "@/components/bugs/LabelBadge";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+import { BackLink } from "@/components/ui/back-link";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
@@ -96,15 +96,9 @@ function RouteComponent() {
return (
<div>
- <Link
- to="/$repo/issues"
- params={{ repo: repo }}
- search={{ q: "status:open", after: "" }}
- className="text-muted-foreground hover:text-foreground mb-6 flex items-center gap-1.5 text-sm"
- >
- <ArrowLeft className="size-3.5" />
+ <BackLink to="/$repo/issues" params={{ repo }} search={{ q: "status:open", after: "" }}>
Back to issues
- </Link>
+ </BackLink>
{/* ── Profile header ─────────────────────────────────────────────── */}
<div className="mb-8 flex items-start gap-5">
@@ -3,11 +3,12 @@
import { gql } from "@apollo/client";
import { useReadQuery } from "@apollo/client/react";
-import { createFileRoute, Link, useCanGoBack, useRouter } from "@tanstack/react-router";
+import { createFileRoute, Link } from "@tanstack/react-router";
import { format } from "date-fns";
-import { ArrowLeft, GitCommit } from "lucide-react";
+import { GitCommit } from "lucide-react";
import { FileDiffView } from "@/components/code/FileDiffView";
+import { BackLink } from "@/components/ui/back-link";
import { Skeleton } from "@/components/ui/skeleton";
const COMMIT_QUERY = gql`
@@ -68,8 +69,6 @@ function RouteComponent() {
const { repo } = Route.useParams();
const { commitRef } = Route.useLoaderData();
const { data } = useReadQuery(commitRef);
- const canGoBack = useCanGoBack();
- const router = useRouter();
const commit = data?.repository?.commit;
if (!commit) return null;
@@ -79,15 +78,9 @@ function RouteComponent() {
return (
<div>
- {canGoBack && (
- <button
- onClick={() => router.history.back()}
- className="text-muted-foreground hover:text-foreground mb-6 flex items-center gap-1.5 text-sm"
- >
- <ArrowLeft className="size-3.5" />
- Back
- </button>
- )}
+ <BackLink to="/$repo" params={{ repo }}>
+ Back
+ </BackLink>
<div className="border-border mb-6 rounded-md border p-5">
<div className="mb-1 flex items-start gap-3">