Skip to content
Template Empire
Browse components

Guided Path FAQ

A free guided FAQ that narrows to one answer, with a reversible path and validated graph.

Find the right answer

Choose a path

What are you trying to do?

Customise

22px
280px
26px

Code

<FaqGuidedPath nodes={guideNodes} rootId="root" />

Guided Path FAQ is a free guided faq react component for Next.js: instead of asking the reader to scan a list, it asks one branching question at a time and narrows to the answer that actually applies to them. Once they take their first step, the route appears as a readable trail or as numbered steps, and Back and Start over make every decision reversible.

The graph is validated before anything renders. Edges pointing at ids that do not exist are removed, and so is any edge that would close a cycle, so traversal is finite whatever the data does and the visited path can always be unwound. A node left with no way forward renders a plain-language message rather than looping or emptying the panel. Panels swap one at a time along the axis you choose, focus moves to each newly chosen question and never on the initial render, and with reduced motion enabled the swap is instant while the path, the focus move and every button behave identically.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/faq-guided-path

Usage

import { FaqGuidedPath } from "@/components/faq-guided-path";

const nodes = [
  {
    id: "root",
    question: "What do you need help with?",
    options: [
      { label: "Billing", nextId: "billing" },
      { label: "Your account", nextId: "account" },
    ],
  },
  {
    id: "billing",
    question: "Billing",
    answer: "Invoices are issued on the first of the month.",
  },
  {
    id: "account",
    question: "Your account",
    answer: "You can change your email from Settings at any time.",
  },
];

export default function Page() {
  return <FaqGuidedPath nodes={nodes} rootId="root" />;
}

Props

PropTypeDefaultDescription
nodesReadonlyArray<{ id: string; question: string; answer?: string; options?: ReadonlyArray<{ label: string; nextId: string }> }>requiredThe guided graph. Ids must be unique; duplicates are dropped, first wins. Options pointing at ids that do not exist, and options that would close a cycle, are removed during validation.
rootIdstringrequiredThe id of the node the guide starts on. If it names no usable node the section renders a short unavailable message instead of an empty panel.
headingstring"Find the right answer"The section's visible h2, which is also its accessible name. Override it to translate the section or to match surrounding copy.
direction"horizontal" | "vertical""horizontal"The axis panels travel along as they swap. Forward and back use opposite directions on that axis.
transitionDistancenumber22How far a panel travels as it swaps, in CSS pixels, clamped to 0-48. Zero gives a pure crossfade.
depthIndicator"steps" | "trail""trail"How the route is shown: trail renders the questions as breadcrumbs, steps renders numbered markers with the question available to screen readers. Both describe the path actually taken, and neither renders until there is at least one step to retrace.
panelMinHeightnumber280Minimum panel height in CSS pixels, clamped to 200-520. It is a floor, not a fixed height: longer answers expand the panel naturally rather than being animated to a measured height.
radiusnumber26Guide panel corner radius in CSS pixels, clamped to 0-48.
onPathChange(ids: string[]) => voidundefinedCalled with the visited path after each user navigation, including Back and Start over. Not called on the initial render.
classNamestringundefinedAdditional classes merged onto the section root with cn().

Customisation

Guided Path FAQ declares six tokens of its own, each falling back to a global semantic or motion token, so it retints and retimes from an ancestor without touching the component source. Geometry comes from props rather than tokens, because it is clamped: --guided-faq-accent colours the current step, the option hover border and the focus ring, --guided-faq-accent-text colours the option arrow on hover, --guided-faq-panel is the guide surface, and --guided-faq-track is the trail connector. Timing is a token, not a prop: --guided-faq-swap-duration and --guided-faq-swap-ease set the one beat the panel swap and the trail settle share, defaulting to --dur-2 and --ease-out-quart, so retuning those global motion tokens moves both halves of the swap together. The fill and text accents are separate tokens rather than one shared knob, because the arrow on hover is read as text: it falls back to the AA-safe --primary-accent rung rather than to --primary, which is tuned as a fill.

:root {
  --guided-faq-accent: var(--chart-3);
  --guided-faq-accent-text: var(--primary-accent);
  --guided-faq-panel: var(--muted);
  --guided-faq-track: oklch(from var(--border) l c h / 0.7);
  --guided-faq-swap-duration: var(--dur-1);
  --guided-faq-swap-ease: var(--ease-in-out-quart);
}

<FaqGuidedPath nodes={nodes} rootId="root" depthIndicator="steps" direction="vertical" />

Frequently asked questions

Is Guided Path FAQ free for commercial use?
Yes. Guided Path FAQ is MIT licensed, so you can use it in personal and commercial projects without attribution.
What happens if the guide data has a cycle or a broken link?
Neither can reach the reader. The graph is walked once before rendering: an option pointing at an id that does not exist is removed, and so is any option pointing back at a node already on the current path, which is what would close a cycle. Options are walked in declaration order, so it is always the later edge that goes and the result is deterministic. If that leaves a node with no way forward and no answer, its panel shows a short message telling the reader to go back or start over, rather than looping or rendering an empty box.
Is Guided Path FAQ accessible for keyboard and screen reader users?
Yes. Every option, Back and Start over is a native button with a visible focus ring, and the panel question is a heading with tabIndex -1 so navigation can land on it without adding a tab stop. After each explicit choice focus moves to the newly chosen question, and never on the initial render. The route is an ordered list with the current step marked by aria-current and repeated in text, so it does not depend on colour, and no total is announced because the depth varies per branch. The trail and both controls render only once there is a step to retrace, so the opening state never presents disabled controls. Because only one panel is on screen at a time, there is a beat between the old one leaving and the new one arriving, and the guide panel itself holds focus across it: anything being removed with focus still on it hands focus to the panel, so focus is never dropped to the document mid-swap however the swap was caused. Browser Back is not intercepted and no history entries are added.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates