Skip to content

Open sourceMITAbout 13 kB

Show people around your product.

Docent spotlights one element, explains it in a sentence or two, and gets out of the way. Tours are plain JSON, so they are easy to write, review and change.

Get started
pnpm add @docentjs/dom
LedgerSearch invoicesAK

Invoices

April · 24 open

+ New invoice
$48,200Outstanding
$12,940Overdue
6 daysAverage to pay

A still of one step.

How it works

A tour is a small JSON document.

You describe the steps, point each one at an element, and start it. Docent draws the spotlight, places the popover, follows the element as the page scrolls and resizes, and remembers where each user got to.

01

Describe the steps

Each step has a title, a sentence or two, and the element it points at.

const tour = defineTour({
id: 'welcome',
steps: [
{ id: 'hi', title: 'Welcome' },
{ id: 'new', target: { name: 'new' },
title: 'Create a project' },
],
})
02

Name the elements

A data-docent name survives redesigns and refactors, unlike a CSS class.

<button data-docent="new">
New project
</button>
03

Start it

Start one tour yourself, or let the manager decide who sees which tour, and when.

createTour(tour).start()
// or, for many tours with rules:
createDocent({ tours: [welcome, billing] })

Make it yours

Quiet by default. Expressive when you want it.

The default is a small caret, a soft spotlight and a dimmed page. Pick anything below to see it on the button. Every choice is one field in the tour's JSON, for the whole tour or a single step.

Arrow
Spotlight shape
Ring
Overlay
Share report

Choosing an option plays it. Press Escape or click the page to close.

Details

Made carefully where it counts.

Small
About 13 kB compressed for the engine and the web renderer together. Drawn arrows load only when a tour uses one.
Accessible
Dialog semantics, focus kept inside the popover and returned after, full keyboard control, reduced motion, and 44 px touch targets.
Isolated
The popover renders in a shadow root. Your CSS cannot break it, and its CSS cannot leak into your page.
Mobile-ready
On narrow screens the popover becomes a bottom sheet and scrolls the target clear of it.
Data, not code
Tours are JSON. Store them in your repo, load them from an API, or edit them in a builder.
Rules built in
Triggers, conditions on user traits, and per-user frequency decide who sees which tour.
Any framework
React, Vue and Svelte bindings, each about 1 kB. Or none at all.
Devtools
See why a tour is or is not showing, edit it live, audit targets and contrast.

Frameworks

Fits the app you already have.

One package per framework, each a thin layer over the same engine. Use the built-in popover, or render your own component and keep the spotlight, positioning and keyboard handling.

import { DocentDevtools } from '@docentjs/devtools/react'
import { useDocent } from '@docentjs/react'
import { billing, welcome } from './tours'
export function App({ user }) {
const docent = useDocent({ tours: [welcome, billing] })
useEffect(() => docent.identify(user.id, { plan: user.plan }), [user])
return <DocentDevtools docent={docent} />
}

Start here

Your first tour takes about five minutes.