Integration Guides

Chrome extension

Add Fluxner analytics to your Chrome extension

SDK release pending

The Fluxner web SDK is not published to npm. This guide is an integration reference, not a ready-to-run installation. Do not install similarly named npm packages. See the Web SDK availability page before using it.

Manifest V3 requires every piece of executable code to ship inside the extension package, and the extension_pages Content Security Policy is fixed at script-src 'self' 'wasm-unsafe-eval'; object-src 'self' with no way to relax it. A remote <script> tag can therefore never load in an extension page. Bundle the @fluxner/js SDK into your popup, options or side panel page instead, and grant host_permissions for the analytics host.

Get your tracking snippet

In your Fluxner dashboard, open Site Settings → Tracking Script and copy your snippet. It looks like this:

<script src="https://fluxner.com/api/script.js?siteId=YOUR_SITE_ID" defer></script>

YOUR_SITE_ID is the numeric ID of your site. If you self-host Fluxner on another domain, replace fluxner.com with your instance's domain.

You only need the site ID from the snippet; the script tag itself is not used in an extension.

Add the snippet to Chrome extension

  1. Install the SDK in the extension project:
# No npm installation is available yet. See the Web SDK availability page.
  1. Initialise it in the entry script of each extension page you want to track (the popup from action.default_popup, the options page from options_ui.page, the side panel from side_panel.default_path). The SDK needs window and document, so do not import it in the service worker.
src/popup.js
import fluxner from "@fluxner/js";

await fluxner.init({
  analyticsHost: "https://fluxner.com/api",
  siteId: "YOUR_SITE_ID",
});

// Extension pages have URLs like chrome-extension://<id>/popup.html.
// Report a readable path instead:
fluxner.pageview("/popup");
  1. Grant the extension permission to call the analytics host. Requests from extension pages to origins listed in host_permissions are not subject to CORS:
manifest.json
{
  "manifest_version": 3,
  "host_permissions": ["https://fluxner.com/*"]
}
  1. Build the extension with your bundler (Vite, webpack, Rollup) so @fluxner/js ends up inside the package, then reload the unpacked extension at chrome://extensions.

The default extension CSP does not restrict connect-src, so no content_security_policy entry is required. If you define your own policy, add https://fluxner.com to its connect-src.

Do not initialise the SDK in a content script. Content scripts run inside third-party websites; tracking there records other people's pages under your site ID, and content scripts are subject to the host page's same-origin policy in any case.

Verify installation

Open your live site in a new tab and click through a few pages. Within a few seconds the pageviews appear in the Fluxner dashboard.

If nothing shows up:

  • View the page source and search for script.js?siteId= to confirm the snippet is on the page.
  • Open the browser Network tab and check that script.js returns 200 and that POST requests go to /api/track.
  • Disable ad blockers, or set up a proxy so the script loads from your own domain.
  • See the script troubleshooting guide for other common causes.

Track custom events

Call fluxner.event() from the page script, or use data attributes on buttons in your popup HTML:

src/popup.js
document.getElementById("save")?.addEventListener("click", () => {
  fluxner.event("settings_saved", { theme: "dark" });
});
popup.html
<button data-fluxner-event="upgrade_click" data-fluxner-prop-plan="pro">Upgrade</button>

Troubleshooting

  • Refused to load the script in the popup console: the fixed extension_pages CSP blocked a remote tag. Remove it and use the SDK.
  • POST /api/track blocked by CORS: host_permissions is missing or does not match. The pattern must include the path wildcard: https://fluxner.com/*.
  • Self-hosted Fluxner: replace https://fluxner.com in both analyticsHost and host_permissions with your own instance URL.
  • Every pageview shows the extension ID as hostname: expected. Extension pages live on chrome-extension://<id>; use fluxner.pageview("/name") for readable paths.

Next steps

On this page