JM Family Design System

Link

Links move users to another destination. Use them for navigation, references, and related resources; use buttons when the interface performs an action.

Start here before choosing examples or props. These notes explain where Link helps, where another pattern is better, and what should stay true in product work.

When to use

  • Page navigation
  • Inline references
  • Related resources
  • External destinations

When not to use

  • Submitting data
  • Opening destructive actions
  • Fake button styling

Accessibility expectations

  • Make link purpose clear from its text.
  • Preserve visible focus styles.
  • Avoid relying on color alone to indicate inline links.

Content guidance

  • Write link text that names the destination, such as "Active vendors" or "Policy library".
  • Avoid vague labels like "click here", "learn more", or "read this" when the destination can be named.
  • Indicate external destinations when leaving the product context would otherwise surprise the user.
  • Keep inline links part of the sentence and standalone links focused on one clear destination.

Implementation notes

  • Use Link only for navigation. Use Button when the interface submits, saves, deletes, opens, or changes state.
  • External links set target and rel attributes, but the visual external icon is still supplied by the consumer.
  • Current-page navigation state is derived by the consumer with aria-current and active styling.
  • Use descriptive hrefs and avoid turning non-navigation controls into fake links.

Import

import { Link } from '@/components/ui/Link';

Renders Next.js Link for internal paths; native anchor for external and in-page hrefs.

Usage patterns

Links should make the destination predictable. The style can change by placement, but the behavior should always be navigation.

Inline reference

Review the vendor setup guide before submitting the request.

Use links inside body copy when the destination is part of the sentence.

Standalone link

Use a standalone link when navigation is useful but not the primary page action.

Related resource

Use a document icon only when it helps identify the destination type.

External destination

Show when a link opens an outside destination or leaves the product context.

Section jump

Use anchored links for nearby page movement, not for submitting or changing data.

Props

The component accepts every native HTMLAnchorElement attribute on top of the design system props below.

PropTypeDefaultDescription
hrefstringDestination. Internal paths render Next.js Link; external, mailto, and anchor (#) hrefs render a native anchor.
variant'inline' | 'standalone' | 'resource' | 'external' | 'anchor' | 'row''inline'Placement and emphasis. Behavior is always navigation; the variant changes affordance only.
leadingIconReactNodeIcon rendered before the label, e.g., a document glyph for related-resource links.
trailingIconReactNodeIcon rendered after the label, e.g., an arrow for standalone or an external icon for external links.

Usage rules

Use links for navigation

Links move users to another page, section, document, or external destination.

Do not use links for actions

Submitting, saving, deleting, opening dialogs, and changing state should use Button instead.

Name the destination

Write link text that tells users where they will go. The destination should be clear out of context.

Do not write vague link text

Avoid generic labels like click here, learn more, or read this when the destination can be named.

What Link does not do yet, and what consumers need to compose themselves.

  • No visual external-destination cue. The external variant opens a new tab and sets rel attributes but does not render an external-link icon; consumers must pass trailingIcon manually for the affordance to appear.
  • No active or current-page state. There is no aria-current handling or active variant, so navigation lists must derive and apply that styling themselves.

Catalog entries to watch for when using Link. Read these before shipping; they describe the failure modes the system has already documented.

Agent guidance

Agents should choose Link only when the user is moving somewhere. If the UI changes state, submits data, or opens a dialog, generate a Button instead.

Generation rules

  • Use links for navigation and buttons for actions.
  • Write link text that names the destination.
  • Indicate external destinations when context would otherwise be unclear.
  • For external links, pass the external variant and supply a trailing icon yourself. The component sets target and rel attributes but does not render an external-link affordance automatically.
  • For the current page in a navigation list, derive active state in the consumer and pass aria-current="page" plus an active styling class. There is no active variant on Link.
  • Avoid bare URLs as link text. Use a descriptive phrase such as "Read the release notes" so screen reader users hear the destination, not "https colon slash slash".
  • Never style a button to look like a link or a link to look like a button. If the affordance is action, switch to Button; if the affordance is navigation, switch to Link.

Baseline example

import { Link } from '@/components/ui/Link';
import { ExternalLink } from 'lucide-react';

<Link href="/vendors/active" variant="standalone">
  Active vendors
</Link>

<Link
  href="https://example.com/policy"
  variant="external"
  trailingIcon={<ExternalLink size={16} aria-hidden="true" />}
>
  Policy library
</Link>
Agents should not style links to look like primary buttons. If the destination needs to be the main call to action, use a link pattern with clear navigation affordance, not an action button.

Decision standard

Links navigate. Buttons act. When generated UI is ambiguous, decide by behavior before deciding by appearance.