Documentation Index

Fetch the complete documentation index at: https://supporthub.usheru.com/llms.txt

Use this file to discover all available pages before exploring further.

usheru Select GTM Injector  (usheru-select-injector.js)

Prev Next

Overview

usheru-select-injector.js is a lightweight helper script served from the Usheru CDN. Its purpose is to insert the usheru Select widget into a film page using configuration that GTM provides at runtime.

This helper is required because GTM Web Custom Templates cannot directly manipulate the DOM. The GTM template sets configuration and loads this injector; the injector does the DOM insertion in normal browser JavaScript.


How it works (end-to-end flow)

  1. A GTM tag fires on a film page.

  2. The tag writes a configuration object to a known global:
    window.__usheruSelectCfg

  3. The tag loads usheru-select-injector.js.

  4. The injector:

    • validates the configuration (security hardening)

    • resolves and loads the client script if needed

    • waits for the target element (SPA-safe)

    • inserts a single <where-to-watch> element in the requested location

    • prevents duplicates

In one line:
GTM Tag → window.__usheruSelectCfg → injector → loads client script + injects <where-to-watch>


Configuration the injector expects

The injector relies on a global object structured like this:

window.__usheruSelectCfg = {
  targetSelector: "...",
  insertPosition: "before|after|inside_first|inside_last",
  scriptValue: "...",
  movieId: "tt1234567",
  language: "en",        // optional
  elementId: "usheru-select" // optional
};

The GTM Template article explains how to populate these fields. This article focuses on what the injector does with them.


Accepted scriptValue formats

The injector accepts multiple input styles for scriptValue and normalizes them to the correct CDN URL.

1) Base name (with or without .js)

  • wc-testing

  • wc-testing.js
    Both resolve to:
    https://cdnstatic.usheru.com/js/wc-testing.js

2) Full URL

  • https://cdnstatic.usheru.com/js/wc-testing.js

  • //cdnstatic.usheru.com/js/wc-testing.js

3) Full script tag

  • <script src="https://cdnstatic.usheru.com/js/wc-testing.js"></script>

  • <script async src='//cdnstatic.usheru.com/js/wc-testing.js'></script>

If a full script tag is provided, the injector extracts the src automatically.


Insert positions

The injector supports four placements relative to targetSelector:

  • before — inserts immediately before the target element

  • after — inserts immediately after the target element

  • inside_first — inserts as the first child inside the target element

  • inside_last — inserts as the last child inside the target element


SPA-friendly retry

Many client sites are SPAs (React/Vue/Angular/etc.) where the film page DOM renders after initial load. To support this, the injector retries briefly:

  • checks for the target selector every ~250ms

  • stops after ~5 seconds

  • inserts as soon as the element exists

If the target element never appears within the timeout, the injector exits safely without inserting.


Duplicate prevention

The injector avoids duplicates in two ways:

Script dedupe
If the resolved script URL is already present in the DOM (a <script src="..."> exists), it won’t be added again.

Widget dedupe
If a <where-to-watch movie="MOVIE_ID"> already exists, the injector won’t insert another widget for the same movie.

This protects against double-firing GTM triggers, SPA route re-entries, and manual setup errors.


Security controls

The injector is intentionally strict to reduce abuse risk.

1) Script origin allow-list
Even when scriptValue is a full URL or a pasted <script> tag, the injector will only load scripts from:

https://cdnstatic.usheru.com/js/

Any other origin or path is rejected.

2) Field validation

  • movieId must match IMDb style: tt + 7–10 digits (example: tt30144839)

  • language is optional but must be exactly two letters (example: en, es)
    Invalid values are ignored.

  • insertPosition must be one of the four supported values.

  • elementId is optional, but must be a safe HTML id; otherwise it defaults to usheru-select.

3) Selector blocking
To prevent unsafe placements, selectors targeting top-level or sensitive nodes are blocked, including:
html, head, body, script, iframe, meta, link, object, embed

If blocked, the injector skips insertion.


What gets inserted

On success, the DOM will contain:

  1. The resolved Usheru client script (if not already present).

  2. A single <where-to-watch> node inserted at the chosen position.

Example output:

<where-to-watch
  id="usheru-select"
  movie="tt30144839"
  language="es">
</where-to-watch>

If language is not provided, it’s omitted.
If elementId is not provided, the id defaults to usheru-select.


Deep-linking & scroll behavior (GTM injector)

The Usheru Select widget is injected asynchronously via Google Tag Manager, so native browser fragment scrolling (e.g., #usheru-select) may happen before the widget exists in the DOM. To make deep links reliable, the injector assigns a stable id to the widget root and automatically scrolls to it once the widget is inserted.

How to use it in campaigns:
Add a fragment to your landing-page URL that matches the widget elementId (default is usheru-select). Example:
https://partner-site.com/movie-page#usheru-select

When a user arrives with that fragment, the page will jump to the selector as soon as it loads.

Optional offset for sticky headers:
If your site has a fixed/sticky header, you can provide a scrollOffset (in pixels) in the GTM configuration so the widget isn’t hidden under the header. The injector will scroll to the widget and then adjust upward by this offset.

Supported GTM config fields for this feature:

  • elementId (string, optional) — The anchor id applied to the widget root. Must be a valid HTML id. Defaults to "usheru-select".

  • scrollOffset (number, optional) — Extra top offset in pixels applied after scrolling. Defaults to 0.

Example GTM configuration:

window.__usheruSelectCfg = {
  targetSelector: ".buy-tickets",
  insertPosition: "after",
  scriptValue: "wc-prod",
  movieId: "tt1234567",
  language: "es",
  elementId: "usheru-select",
  scrollOffset: 110
};

With this setup, any link ending in #usheru-select will reliably drive users directly to the Usheru Select widget once it loads.

Troubleshooting

The GTM tag fires but nothing appears

Most common causes:

  • the selector doesn’t match any element

  • the element appears after the 5s SPA retry window

  • the selector is blocked (e.g., body)

  • invalid movieId

  • scriptValue resolves outside the allowed CDN path

What to check:

  1. Confirm the selector exists in DOM (right element, right page state).

  2. Inspect window.__usheruSelectCfg to ensure correct values.

  3. Look for an existing <where-to-watch> for that movieId (dedupe may have prevented re-insert).

  4. Verify injector and client script are loading in Network.


The script loads but the widget doesn’t render

Common causes:

  • the widget inserted to an unexpected location

  • client script error

  • upstream availability doesn’t recognize the movieId

What to check:

  • Find <where-to-watch> in DOM and validate placement.

  • Check browser console for errors.

  • Reconfirm the movieId.


The widget appears twice

The injector dedupes per movieId. Duplicates usually mean:

  • multiple injector tags firing with different movie IDs, or

  • movie ID changing during SPA navigation

What to check:

  • ensure only one injector tag per page type

  • confirm movieId variable is stable during route changes


Versioning & releases

We recommend hosting the injector at a versioned URL, for example:
usheru-select-injector.v1.4.0.js

Rules:

  • Versioned files must never be modified in place.

  • Changes ship as a new versioned file.

  • Clients should be pinned to a known version unless upgraded intentionally.


Change log (fill per release)

vX.Y.Z — YYYY-MM-DD

  • Added:

  • Changed:

  • Fixed:

  • Security:

  • Notes / migration:

Example:

v1.0.1 — 2025-12-04

  • Added SPA retry polling (5s cap)

  • Added support for full script tag inputs

  • Enforced strict CDN allow-listing for scriptValue


Quick Troubleshooting (Internal Support Sidebar)

When a client says “the widget doesn’t show”:

  1. Check config on the page

    • In console, confirm the global exists and looks right:
      window.__usheruSelectCfg

    • Verify:

      • targetSelector is correct for that page

      • insertPosition is one of: before, after, inside_first, inside_last

      • scriptValue points to Usheru CDN (or base name)

      • movieId is valid (tt + digits)

      • language (if present) is 2 letters

      • elementId (if present) is a safe id

  2. Confirm the target selector exists

    • Inspect DOM to see if targetSelector matches an element.

    • If it’s an SPA, the element may appear late:

      • Injection retries ~5s only.

      • If target appears later than that, advise client to use an Element Visibility trigger.

  3. Check for dedupe blocking

    • If a widget already exists for the same movie, injector won’t insert again.

    • Search DOM for:
      where-to-watch[movie="<movieId>"]

  4. Check scripts are loading

    • Network tab should show:

      • usheru-select-injector.js

      • the resolved client script under
        https://cdnstatic.usheru.com/js/

    • If client script is missing:

      • Their scriptValue likely resolves outside the allowed CDN path.

      • Fix input or confirm client’s script name.

  5. Look for runtime errors

    • Console errors from the client script often explain missing render (bad movieId, upstream availability, etc.).


Fast diagnosis by symptom

Tag fires, nothing inserted

  • Wrong selector

  • Selector blocked (e.g., body, head)

  • Target appears after retry window

Script loads, widget element exists, UI empty

  • Client script error

  • Bad/unrecognized movieId

  • Placement hidden by CSS/layout

Widget appears twice

  • Two tags firing with different movieIds

  • movieId variable changing on SPA navigation


Escalate to Engineering if

  • Config is valid, selector exists early, scripts load, and still no render

  • Multiple clients affected after a new injector release

  • You suspect a CDN/versioning regression

Include in escalation: hostname, config, selector screenshot, timing (SPA), network + console evidence.