Features
Funnels
See how many people get from one step to the next, in order, and exactly where the rest stop. Pages are tracked for you; for anything else, one capture() line per step.
What a funnel shows
A funnel follows the same peoplethrough steps in the order you set, within a time limit. Someone counts at step 3 only if they also did steps 1 and 2 before it. That is what makes it different from putting three counts side by side: three counts can't tell you who moved on.
Its headline is the conversion rate, the people who finished divided by the people who started. Each step shows how many dropped off, and the step that lost the most people is named for you.
1. Pick the steps
Write the journey down as 2 to 5 moments that each mean real progress. Fewer, clearer steps make the drop-off easy to act on.
- Signup:
/pricing→signup_completed→project_created - Checkout:
plan_selected→checkout_started→checkout_completed - Newsletter:
/blog→newsletter_form_viewed→newsletter_subscribed - Onboarding:
signup_completed→invite_sent→first_report_viewed
A step that is a page needs no code. A step that is an action (a button that did its job, a payment that went through) is an event you send.
2. Send each step
Call capture()at the moment each step really happens. The name becomes the step; the properties let you split and filter it later. This assumes you've called FlowGrid.init(); see the SDK Quickstart.
1import { FlowGrid } from 'flowgrid-sdk';
2
3const fg = FlowGrid.instance();
4
5// Step 2: the plan picker opened
6fg?.capture('plan_selected', { plan: 'pro', interval: 'yearly' });
7
8// Step 3: checkout started, once the form is on screen
9fg?.capture('checkout_started', { plan: 'pro' });
10
11// Step 4: paid, only after your payment call succeeds
12fg?.capture('checkout_completed', { plan: 'pro', amount: 290, currency: 'USD' });Where to call it
1import { FlowGrid } from 'flowgrid-sdk';
2
3export function PlanPicker({ plans }: { plans: Plan[] }) {
4 const choose = (plan: Plan) => {
5 FlowGrid.instance()?.capture('plan_selected', { plan: plan.id, interval: plan.interval });
6 router.push(`/checkout?plan=${plan.id}`);
7 };
8
9 return plans.map((plan) => (
10 <button key={plan.id} onClick={() => choose(plan)}>{plan.name}</button>
11 ));
12}Steps sent from your server
Pass visitorId (or userIdfor a signed-in user) so the step joins the same person's browser steps. Without it, a payment confirmed in a webhook looks like a different person, and the funnel shows everyone dropping off at the last step.
Signups, logins and forms are already steps
If you track signups and logins with fg.signup() / fg.login() (see Signups & Logins) or forms with Form Events, pick them as steps as they are. Don't send a second capture() for the same moment.
Pages in single-page apps
A page step matches a page someone loaded. For a screen your app shows without a full page load (a modal, a step inside a wizard, a route your router swaps in), send an event when it appears, such as capture('checkout_viewed'), and use that as the step.
3. Build it on a board
- Open a board and choose Edit.
- With no widget selected, the panel on the right is Add a widget. Pick Funnel under Custom widgets.
- Add each step: Visited a page (is exactly, starts with, or contains a path) or Did something (any event your website has sent).
- Pick how long people have, under Finish within.
- Add it to the board. It uses the board's period unless you give it its own.
Only pages and events your website has really sent are offered, with how many times each happened, so a misspelt step can't silently show everyone dropping off.
Waiting on your code?
A new event shows up in the step list within a few minutes of its first arrival. Ship the capture() line, trigger it once yourself, then add the step.
Reading a funnel
- Conversion: the people who finished out of the people who started, compared with the period before.
- Drop-off: how many people each step lost. Click the number to watch those people's sessions.
- Biggest drop: the step that lost the most people, named on the card. Start there.
- Split by device: mobile and desktop side by side, when the leak is one of them.
- Layouts: top to bottom, left to right, the conversion alone, or a table.
Ask the agent
The Flowgrid Agent builds funnels from the events your website already sends, and can add the missing capture() lines to your code. Nothing changes until you approve it: a funnel arrives as a card you authorise, code arrives as a pull request.
- “Build a funnel from /pricing to signup to the first project created.”
- “Where do people drop off between checkout started and paid?”
- “Set up a checkout funnel in my code: track plan picked, checkout started and paid.”
Limits
| Steps | 2 to 5, in the order people take them |
| A step can be | A page someone visited, or an event: your own capture() events, signups, logins and form submissions |
| Finish within | 1 hour, 1 day, 7 days, 14 days or 30 days from the first step |
| Split by | Device (mobile or desktop) |
| Period | The board's period, or the widget's own |
Common mistakes
- Sending on click, not on success.
checkout_completedsent when the button is pressed counts failed payments as sales. - Two names for one step.
Checkout Startedandcheckout_startedare different events. Pick one style. - Server steps without a visitor. Pass
visitorIdoruserId, or the step can't join the person's earlier steps. - A window too short. A trial that converts in two weeks needs 14 or 30 days, not 1 day.
- Steps in the wrong order. People are counted in the order you set. A step most people do before the first one will look like a huge drop.