KQ-1660 · FIRST/EVENT

First Event

An analytics panel with nothing in it yet, drawn honestly: the axes, the gridlines and a listening pulse at the origin, with the install steps beside it and the minutes counted from a now prop. When the first event arrives the pulse stops, the point drops onto the y-axis and lands on springs.recoil with a ripple along the baseline, and the line begins to draw from it — a clip sweeping right to each new reading — while the scale rises on springs.glide and the steps tick off on springs.flick in a cascade. The steps' Copy buttons are one tab stop that Up, Down, Home and End move through, and silence past the timeout lists what usually goes wrong.

KQ-1660 · FIRST/EVENT

Waylight events

Production · listening since 14:04

Listening · 4 min

Send your first event

  1. Add the tracker

    Import it where your app starts.

    import { track } from "waylight/track";
  2. Initialise with your key

    Once, before any event is sent.

    track.init("wl_pub_7c2e91");
  3. Send a test event

    From anywhere a visitor acts.

    track("signup", { plan: "trial" });
  4. Open your app

    Click around like a visitor. Events land here within a minute.

Up and Down move between the copy buttons.

listening · 4 min · waiting for the first signup

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/first-event

Props

project
{ name: string; environment?: string }
default defaultFirstEventProject
The project being wired up, named in the header.
installSteps
FirstEventStep[]
default defaultFirstEventSteps
What to do to send the first event, in order: { id, title, detail?, code? }; steps with code get a Copy button.
events
{ at: number; count: number }[]
default []
Received buckets, oldest first. The first one to arrive plays the drop; later ones extend the line.
listeningSince
number
default four minutes before now
When listening began, in ms.
now
number
default defaultFirstEventNow
The moment the waiting minutes count to, in ms; never read from the clock during render.
timeoutMinutes
number
default 15
Minutes of silence before the pulse slows and the panel lists what usually goes wrong.
troubleshooting
{ id: string; title: string; detail?: string }[]
default defaultFirstEventTroubleshooting
What usually goes wrong, shown once listening times out.
windowMinutes
number
default 30
Minutes the x-axis spans from the first event; later readings slide the window.
metric
string
default "events"
What is being counted, in the chart's words and announcements.
onCopy
(stepId: string, text: string) => void
default —
A step's snippet was copied (it is also written to the clipboard when one is available).
onCheckNow
() => void | Promise<unknown>
default —
Check now was pressed. Return a promise to show the check in flight.
pulseStyle
"rings" | "sweep" | "dot"
default "rings"
How the origin listens: rings leaving it, a scanning sweep between the axes, or a breathing dot.
axisStyle
"grid" | "ticks" | "bare"
default "grid"
Full gridlines, axis lines with tick marks, or just the baseline.
accent
string
default "var(--accent-bright)"
The pulse, the line, the points and the finished steps. Any CSS colour.
maxHeight
number
default 540
Tallest the surface grows before its body scrolls inside, px.
disabled
boolean
default false
Nothing can be copied or checked; the surface dims.
className
string
default —
Classes for the outer surface.