Skip to content
goodtabs UI
BrowseBrowse components

Back link

A quiet arrow link to the parent page. The arrow nudges left on hover.

npx shadcn@latest add https://ui.goodtabs.co/r/back-link.json

With the @goodtabs namespace in components.json: npx shadcn@latest add @goodtabs/back-link

Grey text with a left arrow. Hover or focus to see the arrow move.

Above a page title

Settings

Billing

Plan, invoices and the card on file.

Where it usually sits: just above the heading of a detail page.

Small

The sm size, with the default Back label and a custom one.

Usage

import { BackLink } from "@/components/ui/back-link"

<BackLink href="/projects">Back to projects</BackLink>

Props

PropTypeDefaultDescription
hrefstring | UrlObjectThe parent page. Passed to next/link.
childrenReactNode"Back"Link text.
size"sm" | "default""default"Text size: 12px with a 12px arrow, or 14px with a 14px arrow.

Source

back-link/back-link.tsx
import * as React from "react";
import Link from "next/link";
import { ArrowLeftIcon } from "lucide-react";
import { cn } from "@/lib/utils";

type BackLinkProps = Omit<React.ComponentProps<typeof Link>, "children"> & {
  /** Link text. */
  children?: React.ReactNode;
  /** Text size. sm is 12px, default is 14px. */
  size?: "sm" | "default";
};

/**
 * A quiet link back to the parent page. Grey, foreground on hover, the arrow nudges left.
 */
export function BackLink({ size = "default", className, children = "Back", ...props }: BackLinkProps) {
  return (
    <Link
      data-slot="back-link"
      className={cn(
        "group/back-link inline-flex items-center gap-1 rounded-sm text-muted-foreground transition-colors duration-100 ease-out outline-none hover:text-foreground focus-visible:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50",
        size === "sm" ? "text-xs" : "text-sm",
        className,
      )}
      {...props}
    >
      <ArrowLeftIcon
        aria-hidden="true"
        className={cn(
          "shrink-0 transition-transform duration-150 ease-out group-hover/back-link:-translate-x-0.5 group-focus-visible/back-link:-translate-x-0.5 motion-reduce:transition-none motion-reduce:group-hover/back-link:translate-x-0 motion-reduce:group-focus-visible/back-link:translate-x-0",
          size === "sm" ? "size-3" : "size-3.5",
        )}
      />
      <span>{children}</span>
    </Link>
  );
}

For AI agents

Hand your agent this page, the markdown at /components/back-link/prompt.md, or the Copy AI prompt button above.

When to use

  • At the top of a detail page that has one obvious parent
  • In a settings sub page above the title
  • In a drawer or panel that was opened from a list

When not to use

  • When the page sits three or more levels deep, use breadcrumbs
  • As a browser back button: it goes to a fixed href, not history
  • For forward actions, use the arrow link

Agent notes

  • It is next/link with the link props, so pass a real href; it does not call router.back()
  • Name the destination in children when the parent is not obvious, for example Back to projects
  • The arrow moves 2px on hover and focus and stays still under prefers-reduced-motion
  • Server component; place it directly above the page heading with a small gap