feedback.tools 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: 'API_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: 'API_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: 'API_KEY', root: '#my-container' });
// HTMLElement reference
ftools('init', { surveyId: 'SURVEY_ID', publishableKey: 'API_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()