Install the widget
One script tag, anywhere before the closing </body>. No package to install, no build step, no dependency on your framework. Takes about a minute.
Get your project key
Open the Widget page in your dashboard. The snippet there already has your key filled in, so the fastest path is to copy it from there rather than from this page. Keys look like pk_live_a1b2c3… and are safe to put in your page source, see Security & privacy.
Add the script
Pick your stack. Every one of these does the same thing, the only difference is where the tag lives.
<!-- Anywhere before </body> -->
<script async
src="https://www.usevoicebox.dev/widget.js"
data-project="pk_live_your_key"></script>Site builders and no-code
No developer needed. Each of these is a paste into a settings field.
Appearance → Theme File Editor → footer.php
Paste immediately before </body>:
<script async
src="https://www.usevoicebox.dev/widget.js"
data-project="pk_live_your_key"></script>
Using a block theme with no footer.php? Any
"insert headers and footers" plugin works, or add it
under Site Kit / Custom HTML in the footer template.Check that it worked
Load your site and look for the feedback button in the corner. If it is there, you are done, send yourself a test message and watch it land in the inbox within a few seconds.
If you would rather confirm from the console, this tells you whether the script ran and whether it mounted:
// Did the script execute?
typeof window.Voicebox === "function" // → true
// Did it mount?
!!document.querySelector("[data-voicebox]") // → true
// Force it open, regardless of your trigger settings
Voicebox("open")Nothing appears?
Single-page apps
Nothing to do. The widget mounts once and lives outside your framework's DOM tree, in its own shadow root attached to <body>, so client-side route changes leave it untouched. It does not re-mount, re-fetch its config, or flicker between routes.
The page a submission came from is captured at the moment it is sent, not at page load, so feedback written after three route changes records the URL the person was actually looking at.
Staging and production
Use a separate project per environment rather than one key everywhere. Staging noise stays out of your real themes, and each project keeps its own allowlist so a leaked staging key cannot post to production.
<Script
src="https://www.usevoicebox.dev/widget.js"
data-project={process.env.NEXT_PUBLIC_VOICEBOX_KEY}
strategy="lazyOnload"
/>Create the second project under Settings → Projects, then set the variable per environment in your host.
Weight and timing