Rebar UI

1.0

imitation

useHashTarget

Opens and scrolls to the section named in the URL, clear of a sticky header.

Transparency pageUse the links to change the hash: the item opens and is highlighted

Current target

None: open this page with #journal

Unknown id

Ignored. The page stays where it is.

API

useHashTarget(ids: readonly string[], options?: {
  offset?: number | "auto";      // default "auto"
  behavior?: "smooth" | "auto";  // default "smooth", instant under reduced motion
  focus?: boolean;               // default false
  defaultOpen?: string[];
  highlightMs?: number;          // default 2400
}): { target: string | null; open: string[]; setOpen }

Reads location.hash on mount and on hashchange. An id that is not in ids is ignored and the page stays where it is. For a known id it returns it as target, adds it to open (for a multiple Accordion), waits for the item to open and lay out, sets scroll-margin-top on the element, scrolls it into view, and marks it data-hash-target="true" for a short ring (style hook only).

offset: "auto" reads --rebar-header-height from <html> and adds 20px. The site-header block publishes that variable and keeps it current with a ResizeObserver; with a header of your own, set it yourself. Give each target an id: AccordionItem takes an id prop for this.

Accessibility

With focus: true the target gets tabindex="-1" and focus (without a second scroll), so screen readers announce it. Scrolling is instant under prefers-reduced-motion. The browser's own back and forward still work because the hook only listens.