Product showcase
Interactive and informational sections that show the product off: a guided tour, a live theme playground, role-based solutions, integrations, release news and a comparison table.
Installation & usage
npx @youj/cli add marketing-product-tourAlso installs async-button, avatar, badge, button, icon-arrow-right, icon-check, icon-check-circle, icon-git-branch, icon-message, icon-rocket, progress, reveal, slider, switch, tabs, textarea, use-controllable-state, use-visible, youj-core, youj-presets, youj-ui-core.
The CLI copies the block to blocks/marketing/product-tour.tsx with every component it uses, so it’s yours to edit.
Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:
'use client'
import Link from 'next/link'
import { ProductTour, type ProductTourProps } from '@/blocks/marketing/product-tour'
export function ProductTourView({ steps, done }: Pick<ProductTourProps, 'steps' | 'done'>) {
return (
<ProductTour
steps={steps}
done={done}
copy={{ eyebrow: 'Product tour' }}
linkComponent={Link}
onValueChange={(value) => {
// your code
}}
onDoneChange={(done) => {
// your code
}}
/>
)
}Description
Let visitors try the product instead of watching it: a rail of steps beside a live window of real components, a beacon pinging on the control each step asks them to try, each step checked off as they do it and a progress line that fills.
Let visitors re-theme a small landing page live with a preset, accent, corners, control size and style. Pick it to show how far the theme goes.
Demo only. Its content is fixed in the block: it takes no data or copy props, only the few settings and callbacks listed in its props. Copy the source to build on it.
Speak to each buyer on one page: pick a role and an industry, and the pitch, a customer quote, the call to action, the live numbers and the activity feed change to match.
Show what the product connects to with searchable, categorized cards that each carry a status, and a detail sheet with the connection’s health and sync history.
Show that the product keeps moving: the newest change as a feature card, earlier changes as a dated list with kind tags and expandable details, an area filter and a way to load more.
Put the product beside the alternatives in one table: yours raised on a panel of its own, a sticky head with price, coverage and a call to action, grouped features that explain themselves, a switch for only the differences, and one alternative at a time on a phone.
Code
Product Tour, the Product tour story: the files youj add writes.
blocks/marketing
Reference
Props12 props, 2 types
Props
| Prop | Type | |
|---|---|---|
theme | ThemeInputDefault: the theme around it. The showcase passes the chosen preset here. | – |
embedded | booleanA section inside another page: the host lays it out (no page background, section padding or max width). default false | false |
steps | ProductTourStep[]The steps, in order. default the demo's connect, guardrails, review and canary | the demo's connect, guardrails, review and canary |
value | stringThe open step's id, controlled. | – |
defaultValue | stringThe step shown first, uncontrolled. default the first | the first |
onValueChange | (value: string) => voidCalled with the step's id when someone opens one. | – |
done | string[]The ids of the steps done, controlled. | – |
onDoneChange | (done: string[]) => voidCalled with the ids of the steps done, as each is completed or the tour restarted. | – |
cta | { label?: string; href: string; onClick?: ComponentProps<'a'>['onClick']; }The call to action after the last step; default "Start with your own project" to `#signup` | "Start with your own project" to `#signup` |
linkComponent | ElementTypeRenders the call to action: pass your router's Link. default 'a' | 'a' |
copy | Partial<ProductTourCopy>Any of the block's strings, to rewrite or translate. | – |
headingLevel | 1 | 2 | 3The heading's level; each open step's heading sits one below. default 2 | 2 |
ProductTourStep
| Prop | Type | |
|---|---|---|
idRequired | string | – |
titleRequired | stringThe step's name on the rail. | – |
descriptionRequired | stringWhat happens, in a sentence or two; shown under the title while the step is open. | – |
prompt | stringWhat to try ("Connect a repository"), shown over the picture as a prompt. | – |
renderRequired | (context: ProductTourStepContext) => ReactNodeThe live picture: real components the visitor can operate. Call | – |
ProductTourStepContext
| Prop | Type | |
|---|---|---|
doneRequired | booleanWhether the visitor has done this step's thing. | – |
completeRequired | () => voidCall it when they do: the step gets its check and the progress moves. | – |
copyRequired | ProductTourCopyThe block's strings, for a step's own labels. | – |
Strings18 keys for copy
Strings
copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.
eyebrowtitledescriptionstepsLabelstepNameprogressaddressbacknextfinishresettrystepDoneconnectRepocommentPinreplyPlaceholderreplyLabeltrafficLabelAccessibilitylandmarks, tabs, dialogs, tables
Accessibility
Every section here is a <section> named by its own heading (aria-labelledby). The heading is an h2 by default and headingLevel changes it; the pieces with items below the title (Product tour, Solutions, What’s new) set theirs one level deeper.
Product tour and Solutions are built on Tabs: the tab list is named, Left and Right Arrow move between tabs, Home and End jump to the ends, and the panel follows the selected tab. Product tour announces a finished tour in a polite status region; Solutions announces the role and industry in view the same way. Product tour’s beacon is decoration (aria-hidden, and it never takes a click): the step’s “Try it” prompt says the same in words, and under reduced motion the beacon is a still dot.
Integrations has a labelled search field, a categories nav whose buttons use aria-pressed, and a result count in a status region; its detail sheet traps focus and closes with Escape. What’s new’s area filter and Product comparison’s alternative picker and “only differences” switch are named controls, and Product comparison is a real table with visually hidden text in its cells and a labelled coverage bar. Theme playground groups its controls under a label, announces the applied recipe in a status region, and renders its preview as a decorative frame (inert) around a real page.
The links and buttons are real a and button elements with the kit’s focus ring.
App logos in the Integrations demo are trademarks of their owners, shown for illustration only.