SDK
JavaScript SDK for embedding feedback surveys (NPS, CES, CSAT) into any website or web application. This is the reference for the hosted widgets.js script installed from the Embed step — for framework-specific install snippets, see that step directly.
How it works
Integration has two independent phases:
Phase 1 — Load the script. The loader snippet creates a command queue (window.ftools.q) and injects the SDK script asynchronously. Any commands called before the script loads are queued and replayed automatically once it's ready.
Phase 2 — Initialize surveys. Call ftools('init', { surveyId: '...', publishableKey: '...' }) to set up a survey. This can be in the same <script> block as the loader, or called later from a component's lifecycle hook — both work because of the queue.
The simplest integration combines both phases in one script tag:
<script>
(function(w,d,n,s,k,e,p){
w[k]=w[k]||function(){(w[k].q=w[k].q||[]).push(arguments)};
e=d.createElement(n),p=d.getElementsByTagName(n)[0];
e.async=!0;e.src=s;p.parentNode.insertBefore(e,p);
})(window,document,'script','__SDK_URL__','ftools');
ftools('init', { surveyId: '__SURVEY_ID__', publishableKey: '__PUBLISHABLE_KEY__' });
</script>For component-based frameworks (React, Vue, Nuxt), it's often better to separate the phases: load the script globally (e.g. in the document <head>), then call init() from a component where you have access to callbacks and lifecycle hooks.
See Initialization for the full init() parameter list.
Survey modes
Popup mode (default)
The survey appears as a floating overlay above the page. It opens automatically based on triggers configured in the dashboard (time delay, scroll depth), or manually via open().
ftools('init', { surveyId: '__SURVEY_ID__', publishableKey: '__PUBLISHABLE_KEY__' });- Supports delay and scroll triggers
- Shows a floating feedback button (if enabled)
- Destroyed and re-initialized on URL change (SPA navigation aware)
- Supports
onRender,onSubmit,onClosecallbacks
Embed mode
The survey renders inline inside a container element you provide. It appears immediately when init() is called, without any triggers.
// CSS selector
ftools('init', { surveyId: '__SURVEY_ID__', publishableKey: '__PUBLISHABLE_KEY__', root: '#my-container' });
// HTMLElement reference
ftools('init', { surveyId: '__SURVEY_ID__', publishableKey: '__PUBLISHABLE_KEY__', root: document.getElementById('my-container') });- No triggers, no close button, no feedback button
- Survives URL changes (not destroyed on SPA navigation)
- Multiple embed surveys can be active simultaneously
- Supports
onRender,onSubmitcallbacks (onCloseis not supported) - Automatically cleaned up if the container is removed from the DOM
Next steps
- Initialization —
init()parameters, popup vs. embed setup - Custom variables — attach your own data (user id, plan, order value...) to a response via
metadata - Events — subscribe to
onRender/onSubmit/onClosewithon() - Methods —
open(),close(),destroy(),destroyAll()