Qaid
ARTICLE

Progressive Loading and Legacy Browser Fallback

One script tag that loads only what a visitor uses and automatically falls back to a compatible build on older browsers — no detection to write yourself.

Qaid Team

The thumbs embed loads only what a visitor actually uses, and it picks the right build for the browser on its own. Both of those happen through a single copy-paste script tag — there's nothing to configure and no compatibility logic for you to write. This guide explains what's going on under the hood, and how to take manual control if you ever want to.

The install: one tag

The snippet the dashboard customizer generates is a single classic script tag:

<script
  src="https://unpkg.com/@qaiddev/thumbs-embed/dist/embed.js"
  data-endpoint="/api/feedback"
  data-api-key="your-api-key"
></script>

embed.js is a tiny (~0.5 KB gzipped) loader that runs in every browser. It looks at what the browser supports and pulls in the right build, carrying your data-* config across so exactly one embed initializes.

What loads, and when

On a modern browser, embed.js loads the progressive build: only the core (~16 KB gzipped — the thumbs buttons, element targeting, accessibility, styles, and submit) is fetched up front. Everything else is a separate chunk the browser only requests the first time that feature is used:

FeatureLoads when
Element targetingthe first thumbs-up/down click (pre-warmed on hover)
Message modalfeedback is submitted
Screenshot + annotationa screenshot is captured
Video recording + redactionrecording starts

So a visitor who gives a quick thumbs-up and leaves never downloads the screenshot, video, or redaction code.

Legacy browser fallback (automatic)

Progressive loading relies on native ES modules, supported by every browser released since 2018 (Chrome 61+, Firefox 60+, Safari 11+, Edge 16+) — roughly 98–99% of traffic. embed.js feature-detects module support and, on an older browser that lacks it, loads the all-in-one UMD bundle (qaid.umd.cjs) instead — a single classic script with everything baked in.

You don't add anything for this. One tag covers both paths:

  • Module-capable browsers get the progressive loader (loader.js) and its on-demand chunks.
  • Older browsers get the single UMD bundle (~25 KB, no splitting) — only those visitors download it.

Because embed.js chooses exactly one build, the embed only ever initializes once — no double-render, no detection code.

How far back this reaches. The embed itself needs modern browser APIs (Shadow DOM, getDisplayMedia, and friends) that landed around the same time as ES modules, so genuinely ancient browsers like Internet Explorer 11 won't run it even via the UMD fallback. The fallback is most useful for the narrow band of environments that support the embed's runtime but not module loading — for example a locked-down corporate browser or an older mobile WebView.

Manual control (optional)

embed.js costs one extra tiny request (itself) before it loads the real build. If you'd rather skip that hop, point straight at the build you want:

Progressive loader only — if you don't need the legacy fallback, load loader.js directly:

<script
  type="module"
  src="https://unpkg.com/@qaiddev/thumbs-embed/dist/loader.js"
  data-endpoint="/api/feedback"
></script>

Explicit two-tag fallback — if you'd rather not have embed.js inject a script at all, use the browser-native module / nomodule pair. The browser runs exactly one:

<script type="module"
  src="https://unpkg.com/@qaiddev/thumbs-embed/dist/loader.js"
  data-endpoint="/api/feedback"></script>
<script nomodule defer
  src="https://unpkg.com/@qaiddev/thumbs-embed/dist/qaid.umd.cjs"
  data-endpoint="/api/feedback"></script>

Both of these are exactly what embed.js does for you — reach for them only when you want the extra control.

Self-hosting

If you'd rather not load from a CDN, the simplest option is to download the single UMD file and serve it from your own origin:

<script
  defer
  src="/js/qaid-thumbs.umd.cjs"
  data-endpoint="/api/feedback"
  data-api-key="your-api-key"
></script>

Grab it from https://unpkg.com/@qaiddev/thumbs-embed/dist/qaid.umd.cjs. It's a classic script (no type="module" needed) and is the simplest thing to host — one file, no chunks to mirror. To keep progressive loading from your own origin instead, serve the package's whole dist/ directory (including dist/chunks/ and loader.js) and point an embed.js or loader.js tag at your copy.

Verifying it loaded

Open your site with the browser devtools Network panel filtered to JS:

  • On a modern browser you'll see embed.js, then loader.js and the core chunk load immediately, then a chunk like targeting-*.js appear the moment you click a thumbs button.
  • To confirm the fallback, load the page in an older browser (or one with module support disabled) and check that qaid.umd.cjs loads instead.

If nothing loads at all, double-check the script's data-endpoint points at your feedback API and that the page isn't blocking the CDN via a Content-Security-Policy script-src directive. See Troubleshooting Common Issues for CSP and endpoint fixes.

Back to all articles