Two things go on your site. The testimonial wall plays the voices you have approved and pinned, in your colours, matching your page. The collector is a button that opens the recorder right there, so a customer can leave a testimonial - or a user can report a problem - without leaving your page. Both take the same two things: a collection to send replies to, and a key that names your site.
Overview
The whole path, which the walkthrough at the end shows in ninety seconds:
Create a collection - what you are asking, and whether replies carry a name.
Add your website - a key, locked to the domains you list.
Copy the code from the Install card, with your appearance settings baked in.
Paste it - the wall where testimonials go, the collector next to your button.
Approve and pin replies as they land. The wall follows.
You need an account (free) and, for the collector, a site served over HTTPS - browsers only allow the microphone on secure pages. One website on Free and PRO, five on PRO+.
1 · Create a collection
In the dashboard, open the Business workspace (Coaches and Recruiter have their own; each gets its own collections and walls) and press New collection.
- Title - what it is: “Customer testimonials”, “App problem reports”.
- Prompt (optional) - the question people see: “How was working with us?”
- How should people answer?
- Named testimonials - they give a name, company and role, and choose whether you may show it publicly. This is the one for a wall.
- Anonymous feedback - no name, and they can disguise their voice before it uploads. Private by nature: it can never be shown on a wall.
- Contact form - name and email required so you can write back; never published, no rating. For support and problem reports.
- Ask for a star rating - for named and anonymous collections.
Save it and you have a link, staging.platformvoice.com/f/your-collection, you can share on its own. The collector is the same page, framed on your site.
Only a named reply whose author agreed to be shown can go on a wall - the Approve button stays off for everything else. If the wall is the point, choose Named testimonials here.
2 · Add your website
Open Embeds in the dashboard and create a key: a name for your own reference, and the sites allowed to use it - the origins your pages are served from, comma-separated.
https://acme.com- exactly that origin: scheme and host, no path.https://*.acme.com- every subdomain (www.,app.,a.b.), but not the bareacme.com. List both if you use both.http://localhost:3000- allowed, for development.
Press Create key and copy it now. Only a hash is stored, so this is the one time it can be shown; if you lose it, revoke it and make another. The key is public by design - it names your account, it does not authorise anything. The site list is what restricts it: a snippet copied to a site you did not list shows nothing.
3 · Copy the code
The Install card, under your keys:
- Collection - which one the wall shows and the collector sends to.
- Theme - Match my page (default), Always light, Always dark.
- Brand colour - the stars, the play button and the progress.
- Scroll through testimonials automatically - off by default.
Copy the Testimonial wall snippet, the Feedback collectorsnippet, or both. Only the settings you changed are written into the code. If the key card is already closed the snippet says YOUR_KEY - paste the key you saved.
4 · The testimonial wall
Paste it where the testimonials should appear:
<div data-pv-testimonials
data-pv-key="YOUR_KEY"
data-pv-collection="customer-testimonials"></div>
<script async src="https://staging.platformvoice.com/embed/v1/testimonials.js"></script>The widget renders in its own shadow root, so your stylesheet cannot break it and it cannot break yours. It reads the background painted behind it and picks a light or dark face that reads on it, and follows your site’s own theme toggle. It shows the testimonials you have pinned, in the order you set, with one shared player - starting a second one stops the first - and a transcript behind the icon on each card.
Options
| Attribute | Values | What it does |
|---|---|---|
data-pv-key | your key | Required. Names your account; the site list decides where it works. |
data-pv-collection | collection slug | Required. Which wall to show. |
data-pv-theme | auto · light · dark | Default auto: reads the page. Pin it only if your page paints nothing behind the widget. |
data-pv-accent | #rrggbb | Your brand colour. |
data-pv-autoscroll | true | Advances the rail every few seconds. Stops while someone hovers, tabs through it, or listens, and never runs for visitors who asked for reduced motion. |
data-pv-limit | number | At most this many cards. Default 20. |
<div data-pv-testimonials
data-pv-key="YOUR_KEY"
data-pv-collection="customer-testimonials"
data-pv-accent="#e0662e"
data-pv-theme="dark"
data-pv-autoscroll="true"
data-pv-limit="8"></div>On a single-page app
The script mounts what is on the page when it loads. If your framework renders the mount element later, or re-creates it on a route change, ask it to look again; and if you want a button of your own that starts the first testimonial:
// A page that inserts the mount element after load
// (React, Vue, Turbo…) asks the script to look again:
PlatformVoiceTestimonials.scan();
// A "hear one" button of your own:
PlatformVoiceTestimonials.play(document.querySelector("[data-pv-testimonials]"));5 · The collector
The collector is a small loader. Paste it once, anywhere on the page, and point data-pv-trigger at your button - any CSS selector; every element that matches opens the recorder in a modal:
<button id="leave-feedback">Leave a testimonial</button>
<script async src="https://staging.platformvoice.com/embed/v1/collector.js"
data-pv-key="YOUR_KEY"
data-pv-collection="customer-testimonials"
data-pv-trigger="#leave-feedback"></script>The recorder is our own page, framed on yours, so the microphone handling, the in-browser voice disguise and the upload all run on our origin and ship with a normal deploy - you never rebuild anything. Two things your site has to allow, and both are the usual cause of “the button opens but the mic doesn’t”:
- HTTPS. Browsers do not offer the microphone on an insecure page.
- Permissions-Policy. If your site sends one, it must let the frame use the microphone:
Permissions-Policy: microphone=(self "https://staging.platformvoice.com"). A policy ofmicrophone=()cannot be overridden by the frame.
The permission prompt names your domain, not ours. That is correct, and it surprises people the first time.
For testimonials
A named collection with the rating on, and a button that says what it does - “Leave a testimonial”. The person records, leaves their name and role, rates you, and agrees (or not) to be shown. It lands in the collection like any other reply.
For in-app feedback and problem reports
Put “Report a problem” in your app and point it at its own collection - a contact form if you want to answer people (name and email required), or a named one. A person will say in twenty seconds what they would never type into a form, and you get the voice, the transcript, and an email as it lands.
<button id="report-problem">Report a problem</button>
<script async src="https://staging.platformvoice.com/embed/v1/collector.js"
data-pv-key="YOUR_KEY"
data-pv-collection="app-problem-reports"
data-pv-trigger="#report-problem"></script>From your own code you can open the recorder with the signed-in user already filled in, so a report never arrives without someone to reply to:
// Open the recorder from your own code, with the signed-in
// user filled in so you can answer them.
PlatformVoice.open({
name: user.fullName,
email: user.email,
company: "Acme", // optional
role: "Admin", // optional
});What the collector does not capture: the page, the browser, or what went wrong in code. It records a voice; the only thing attached automatically is the site it came from, which the email shows as “via app.acme.com”. Ask people to say which screen they were on, and make one collection per app or area so the inbox sorts itself.
For anonymous feedback inside a product - “what would you change?” - use an anonymous collection; the disguise is offered before anything uploads.
6 · Approve and pin
You get an email as replies land, worded for what the link is (“New testimonial from Ada Lovelace via acme.com”), at most one every thirty minutes per collection. Open the collection in the dashboard:
- Listen. Every reply arrives private, with a transcript.
- Approve the ones you want to show. The button is only enabled when the person agreed to be shown publicly.
- Pin to wall. Pinned testimonials are the wall; drag to reorder. Three per wall on Free and PRO, fifty on PRO+.
The wall on your site follows within about five minutes - the list is cached briefly in the visitor’s browser and at the edge. Unpin or unapprove and it leaves the same way. If a paid plan lapses, pins wind down gradually with notice; nothing disappears the day it ends.
If something’s off
The wall shows nothing
- The page’s origin is not in the key’s site list. It has to match exactly -
https://www.acme.comis nothttps://acme.com; add both, or a wildcard plus the apex. - Nothing is pinned yet, or the collection is inactive. An empty wall renders nothing at all - by design, a marketing page never shows an error box.
- The script is blocked by a content blocker or a strict
script-src. Allowstaging.platformvoice.com. - On a single-page app the mount element arrived after the script ran - call
PlatformVoiceTestimonials.scan().
The wall is the wrong colour
- It reads the background behind it. If your page paints nothing there (a transparent body over a dark image, say), pin the theme with
data-pv-theme. - You just deployed a change and see the old look: the script is cached for a few minutes. Hard-refresh.
The button does nothing
data-pv-triggerdoes not match your button - check the selector in the console withdocument.querySelector(…).- The button is added to the page after the script ran. Call
PlatformVoice.open()from its click handler instead. - The recorder opens but the microphone is refused: HTTPS and the Permissions-Policy header, above.
Still stuck? Leave us a voice message - the contact page is a collector, so you will be using the thing you are asking about.
Walkthrough
The six steps, ninety seconds, drawn from the dashboard as it is today. Press play; the narration is the transcript underneath, and each chapter is a place you can jump to.
New collection
Start in your dashboard, in the Business workspace. Press New collection, give it a title, and the question people will answer. Choose Named testimonials - only a reply with a name and consent can go on a wall. Save it, and you already have a link you can share.
Start in your dashboard, in the Business workspace. Press New collection, give it a title, and the question people will answer. Choose Named testimonials - only a reply with a name and consent can go on a wall. Save it, and you already have a link you can share.
Next, Embeds. Add your website: a name, and the sites allowed to use it - your domain, plus a wildcard if you use subdomains. Create the key and copy it now. Only a hash is stored, so this is the one time it can be shown.
In Install, pick the collection. Appearance is optional: the widget matches your page by default, and you can set your brand colour. Copy the testimonial wall snippet - and the collector too, if you want a button on your site that opens the recorder.
Paste the wall where the testimonials should go. Paste the collector once, anywhere, and give it the selector of your button - every element that matches opens the recorder. Deploy. The page must be served over HTTPS for the microphone to work.
As replies land you get an email. Open the collection, listen, and approve the ones the person agreed to show. Then pin: the pinned testimonials are the wall, in the order you set - three per wall on Free and PRO, fifty on PRO+.
That's it. The wall on your site updates within a few minutes, matches your page in light or dark, and plays with a synced transcript. Change what is pinned and the site follows.