Embedding¶
Wall¶
<div id="testimonials"></div>
<script async
src="https://withfeedback.fra1.cdn.digitaloceanspaces.com/widget/v1/widget.js"
data-wf-key="YOUR_PUBLIC_KEY"
data-wf-widget="YOUR_WALL_ID"></script>
The widget is inserted immediately after its own script tag, so put the tag where you want the wall. Columns are configurable 1–4 and collapse to two, then one, on narrower screens.
Carousel¶
The same content, one at a time. Optional autoplay with an interval between 2 and 30 seconds, and dot navigation that respects a click.
Filtering an embed¶
Each widget carries its own content filter, so two embeds can show different slices of the same project without any code:
| Filter | Use |
|---|---|
| Kind | Testimonials only, on a landing page |
| Minimum rating | A "5 stars only" wall |
| Tags | Per feature, per plan, per campaign |
Caching, and how fresh it is¶
Payloads are cached and keyed on a content version for the project. Anything that changes what an embed should show — an approval, a withdrawal, a widget setting — bumps that version, and the next request builds a fresh payload.
So an approval appears in your embeds promptly rather than after a cache expiry. A withdrawal is the case that matters most, and it takes the same path.
Performance¶
- ~9 KB gzipped, one request,
async, with a CI size budget. - No render blocking. The tag does not hold up your page.
- Videos do not preload. A wall of ten video testimonials fetches ten poster images, not ten videos, and nothing plays by itself.
- Avatars are lazy-loaded.
- Silent failure. If the API is unreachable you get no widget — never a broken page or a console full of errors.
Branding¶
The "Powered by withfeedback" line is removed on plans that include white-labelling. It is computed from the plan server-side on every payload, so it is not something a client can switch off — and not something you have to remember to turn off after upgrading.