Skip to main content
Calling formbricks.track() does not mean a survey appeared. Formbricks still checks the cooldown period, recontact options, targeting and the percentage setting, and often decides not to show anything. Lifecycle events tell you what really happened, so your app can react to the survey it actually displayed.

The events

responseId is the id of the stored response — the same id you see in the Responses tab — so your app can link its own analytics or session replays to the exact response. It is optional: when the id is not available the key is absent, and GTM’s dataLayer carries null for it. formbricks_survey_shown reports what the respondent saw, so every appearance is paired with a formbricks_survey_closed. The Displays number in your Formbricks dashboard counts what reached the server instead, so it can be lower if the network dropped.

Listening for events

You can subscribe before or after formbricks.setup(), and your listeners stay registered after formbricks.logout(). window.formbricks exists as soon as the SDK script has loaded — setup() does not need to have run — so the reliable order is: load the script, register your listeners, then call setup().
Events are delivered live, not replayed: a listener registered after an event fired will not receive it. This matters most for formbricks_setup_successful — register it before calling setup(). If you only need to know when your own setup() call finished, you can also simply await the promise it returns; the event is for code that did not make that call, like a decoupled module or a tag. On GTM the dataLayer buffers, so its triggers are immune to this ordering.

Stopping a listener

formbricks.on() returns a function that removes the listener:
If you kept the handler in a variable, formbricks.off() does the same:

Example: show a survey once per session

A survey that is never shown sends no events at all. That silence is the signal: it means the user did not see a survey, so nothing needs to be recorded.
There is no separate “finished” event. formbricks_survey_closed covers both dismissing and completing a survey — a formbricks_response_submitted with finished: true for the same surveyId is what tells them apart. Correlate on the id, not on arrival order: that event is sent once the server has stored the response, so it normally lands before the close but can follow it, and if the response cannot be saved it never lands at all.

Google Tag Manager

The same events, under the same names, are pushed to window.dataLayer automatically — no formbricks.on() call needed. Create a GTM Custom Event trigger matching the event name (for example formbricks_setup_successful) and read the payload from Data Layer Variables under the formbricks key. See Google Tag Manager for the full setup.
Lifecycle events are available in the JavaScript SDK. Support for React Native, iOS, Android and Flutter is coming in a later release.