Back / Up

Free

Back and Up as two different controls, because they are two different promises: back is history and may leave the site, up is hierarchy and is always defined. A back control with nothing behind it goes up rather than dead-ending, and says which it did.

</>sv-back-up backupnavigationhistoryhierarchymobilebreadcrumb
import { SvBackUpComponent } from '@styloviz/back-up';

Demo & usage

Basic usage

Usage example — open the gallery for the full interactive demo.

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Back, with somewhere safe to land

example.htmlAngular
<sv-back-up [up]="'/orders'" upLabel="Orders" />

Up — a real link, always

example.htmlAngular
<sv-back-up mode="up" [up]="['/orders', order.id]" upLabel="Order details" />

A breadcrumb's mobile form

example.htmlAngular
<!-- A breadcrumb knows the "up" target; a back button does not. Below the
     breakpoint, the trail collapses to the one crumb that matters. -->
@if (narrow()) {
  <sv-back-up mode="up" [up]="parentPath()" [upLabel]="parentLabel()" />
} @else {
  <sv-breadcrumb [items]="crumbs" />
}

When to use

  • A detail page that people arrive at by deep link — from an email, a chat, a notification — and need a reliable way out of.
  • The mobile form of a breadcrumb: one control pointing at the one crumb that matters.
  • When you need to know afterwards whether "back" actually went back. `(navigated)` carries `reason`, and a fallback is otherwise indistinguishable from a working back button.
  • For a full trail, use Breadcrumb; for moving between peers, use Tabs or Jump Menu. This is for moving out and up.

Async states

None — this component has nothing to load, so it has no loading, empty or error state to drive.

Inputs

NameTypeDefaultDescription
modeBackUpMode'back'What this control promises. `back` returns through history and falls back to up; `up` always goes to up.
upSvLinkTarget | nullnullThe hierarchical parent — where "up" goes, and where "back" lands when there is no history. **Required in practice**: without it a `back` control has no fallback and can still dead-end, which is the defect this component exists to prevent. Warns once in dev when it is missing.
upLabelstring''Name of the up destination, used in the visible text and the accessible name — "Back to Orders", "Up to Orders". Without it the control reads as a bare "Back", which tells a screen-reader user nothing about where they will end up.
labelstring''Override the whole visible text. Leave unset to compose it from mode and upLabel.
stayInSitebooleanfalseOnly use history when the previous entry is provably this app's — otherwise go up. OFF BY DEFAULT, AND THAT IS THE RIGHT DEFAULT FOR A *BACK* CONTROL. Back meaning "the browser's back", including off the site, is what the word has always meant and what the hardware button does. Turn this on for a control that is really *"return to where you were in this app"* — a wizard's escape hatch, a detail page's return-to-list — where leaving the site is never the intended answer. "Provably ours" means: this control has observed at least one in-app navigation since it was created, **or** `document.referrer` is same-origin. Anything else is treated as not ours, because the failure modes are not symmetric — going up when back would have worked is a mild surprise; leaving the site when the user expected to stay is a lost session. ⚠️ In a single-page app both signals are weaker: a router's `pushState` is not observed, a control inside a routed page starts counting from zero on each route, and `document.referrer` describes how the reader entered the app, not the entry behind this one. So it errs towards going up.
variantBackUpVariant'ghost'Visual treatment.
sizeBackUpSize'md'Control size.
disabledbooleanfalsePrevents the control from being used.
iconOnlybooleanfalseShow only the arrow, keeping the text as the accessible name. Useful in a dense toolbar.
surfaceIdstring | nullnullNames this control in the shared navigation-analytics stream, when a page has more than one. Ignored unless `provideSvNavTelemetry()` is wired up.
customClassstring''Additional CSS classes on the control.

Outputs

EventPayload typeDescription
navigatedBackUpNavigationWhat the control did. Always emitted, including when the fallback fired — see BackUpNavigation.reason.

Customization & theming

  • Three variants: ghost, outline, link. Three sizes: sm, md, lg.
  • `iconOnly` for a dense toolbar — the text stays as the accessible name.
  • `label` overrides the composed text entirely; `upLabel` alone composes "Back to X" / "Up to X".
  • The up target routes through `SvLinkAdapter`, so no router dependency — with none wired up the anchor is simply followed.

Best practices

  • Do: Always give it an `up` target, even in `back` mode. Without one, a deep-linked page has nothing to fall back to and the control can still dead-end — which is the defect the component exists to prevent.
  • Do: Name the destination with `upLabel`. "Back to Orders" tells a screen-reader user where they will land; a bare "Back" tells them nothing.
  • Tip: Turn on `stayInSite` for a control that means "return to where you were in this app" — a wizard's escape hatch, a detail page's return-to-list. `history.length > 1` proves only that something is behind you, and a search engine counts.
  • Don't: Don't use `back` where you actually mean `up`. They look identical and behave differently, and the one that surprises people is a back button that goes somewhere they have never been.

Accessibility

  • Up renders a real `<a href>` and back renders a `<button>`, chosen by what each can promise: only one of them has a destination a browser could open in a new tab.
  • A modified click (⌘, middle, Shift) on the up control is never intercepted — that gesture means "open this somewhere else".
  • Icon-only keeps the composed text as `aria-label`, so the control is never announced as a bare graphic.
  • Disabled is `disabled` on the button and `aria-disabled` on the anchor, which cannot take the former.

Feedback on Back / Up

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.