Most product feedback is asked for too late.
The user gets stuck in onboarding today. They ignore a feature today. They abandon checkout today. Then, three days later, we email them a survey and ask them to remember what happened.
That is obviously not ideal, and the data agrees. A feedback trigger that fires within the hour consistently outperforms a weekly batch email sent days after the moment you actually care about. Memory fades, context disappears, and response rates fall.
So we built the Formaly SDK: a small JavaScript SDK that shows targeted surveys inside your product, right where the context exists.
The actual problem
The problem with survey links is not that links are bad. Links are fine. The problem is that links are usually disconnected from the moment you care about.
- To understand why someone did not finish onboarding, ask while they are still in onboarding.
- To understand whether a new feature lands, ask right after they use it.
- To understand why someone almost upgraded, ask near the pricing or checkout moment.
That is what the SDK is for.
What we shipped
The SDK supports three display modes:
| Mode | Best for | Why it exists |
|---|---|---|
| Popup | Important feedback moments | Hard to miss, for questions that matter |
| Slide-in | Lightweight contextual prompts | Visible without taking over the screen |
| Widget | Always-available feedback | Lets users open feedback when they want |
And a set of triggers:
| Trigger | Example |
|---|---|
| Page view | Show on /pricing |
| Delay | Ask after 20 seconds on docs |
| Scroll depth | Ask after someone reads most of a page |
| Exit intent | Ask why someone is leaving |
| Element click | Ask after a feature button is used |
| Manual | Call Formaly.show("survey_id") yourself |
You can also layer targeting conditions (URL, user attributes, and more) on top of triggers, so a survey only fires for the segment you mean. That is enough to cover the common cases without turning the product into a complicated rule engine.
The simplest setup
Add the SDK:
<script src="https://www.formaly.io/embed.js" data-formaly-key="YOUR_KEY"></script>
Then call it when something meaningful happens:
Formaly.show("survey_id");
That is the simple path. Everything else (triggers, targeting, display mode, chat vs form) you configure from the dashboard, no redeploy required.
The UX constraint
The most important rule for this SDK is: do not make the host product worse.
Survey tools become annoying fast, too many popups, bad timing, no cooldowns, no respect for what the user is doing. So the SDK is deliberately careful:
- Respect cooldowns.
- Avoid showing the same survey repeatedly.
- Keep display modes lightweight.
- Let teams choose the right moment.
- Make manual control possible.
Good feedback UX is mostly restraint. (I wrote about the engineering behind that restraint in In-Product Targeting: How We Built a 10KB Survey SDK.)
What I am optimizing for
The best feedback is contextual. Not every survey should live inside the product, some belong in email invites, some on a landing page, some as anonymous links. But product feedback (onboarding, activation, pricing, feature usage) should often happen inside the product itself.
That is why this SDK matters for Formaly. It moves us from "forms you send" to "feedback you ask for at the right moment."