Jump to

SDK: Events

Callbacks

on() subscribes to survey events. It is the only way to set callbacks: init() and open() don't take them.

ftools('on', '__SURVEY_ID__', {
  onRender: () => {
    console.log('survey mounted');
  },
  onSubmit: ({ score, text, email }) => {
    console.log('step submitted', score, text, email);
  },
  onClose: () => {
    console.log('visitor closed the popup');
  }
});
Comparison table
CallbackPopupEmbedWhen it fires
onRender✅✅The survey is mounted into the page. Its CSS may still be loading. For embed, it fires even when the container is off screen.
onSubmit✅✅The respondent submits a step. See below.
onClose✅❌The visitor clicks the popup's close button. Not for close() or SPA navigation.

onSubmit fires once per submitted step, with everything collected so far:

  1. Score: { score }.
  2. Follow-up text or choices: { score, text }. Selected choices come as one string, joined with ;\n.
  3. Email on the contact screen: { score, text, email }.

A skipped step doesn't fire it. For a general (text-only) survey, score is undefined. onSubmit reports what the respondent sent; it fires even if the request to the server failed.

Call on() after init(), at any time before or after the survey opens. A second on() updates only the callbacks you pass. If the survey is already mounted, onRender fires at once. off() removes all callbacks.

ftools('on', surveyId, callbacks)

Sets callbacks for an initialized survey. See Callbacks.

Comparison table
ParameterTypeDescription
surveyIdstringSurvey ID
callbacks.onRender() => voidThe survey is mounted.
callbacks.onSubmit({ score?, text?, email? }) => voidThe respondent submitted a step.
callbacks.onClose() => voidThe visitor clicked the close button (popup only).

ftools('off', surveyId)

Removes all callbacks set with on(). Use it in component cleanup.

ftools('off', '__SURVEY_ID__');

In React, subscribe in an effect and remove the callbacks on unmount. The ref keeps the latest callbacks without subscribing again:

import { useEffect, useRef } from 'react';

export function useSurveyEvents(surveyId, {
  onSubmit,
  onClose
} = {}) {
  const callbacks = useRef({ onSubmit, onClose });

  useEffect(() => {
    callbacks.current = { onSubmit, onClose };
  });

  useEffect(() => {
    window.ftools?.('on', surveyId, {
      onSubmit: (data) => callbacks.current.onSubmit?.(data),
      onClose: () => callbacks.current.onClose?.()
    });

    return () => {
      window.ftools?.('off', surveyId);
    };
  }, [surveyId]);
}