Plain HTML
The canonical install. Works on any site, framework or not.
<script src="https://bugloop.ai/w.js" data-bugloop-key="bl_pk_…" defer></script>Next.js (App Router)
Use next/script with the afterInteractive strategy so the widget never competes with your first paint. Put it in your root layout to get the button on every page, or in a nested layout to scope it to one section.
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://bugloop.ai/w.js"
data-bugloop-key={process.env.NEXT_PUBLIC_BUGLOOP_KEY}
strategy="afterInteractive"
/>
</body>
</html>
);
}React (Vite, CRA, SPA)
Add the tag to index.html. The widget attaches itself to document.body and lives outside your React tree, so it survives route changes without re-mounting.
WordPress
Either add the snippet to your theme's footer.php before </body>, or use any "insert headers and footers" plugin and paste it into the footer field. No BugLoop plugin is required.
Shopify
Online Store → Themes → Edit code → layout/theme.liquid. Paste the snippet immediately before </body> and save.
Google Tag Manager
Create a Custom HTML tag containing the snippet, and fire it on All Pages. Leave "Support document.write" unchecked.
One caveat: because GTM injects the script, the widget reads its key from the data-bugloop-key attribute on its own tag, which GTM preserves. It works, but a direct install is one less moving part.
Verifying the install
Open your browser console. If the key is missing or malformed, BugLoop logs a single warning and does nothing else. If the key is fine but the origin is not on your allowlist, the config request returns 403 and the button does not render — add the origin and reload.