A script tag that fails does not throw an error you can search for. The page loads, the form never appears, and you find out when a week of launch traffic produced zero signups. The embed script is built to fail quietly so it never breaks your site, which is also why you have to check that it works on purpose.

These four checks take about two minutes and cover every point where the install can break: the tag itself, the config request, the page view, and the widget.

Check 1: OperatorStack exists in the Console. Check 2: the /config request returns 200. Check 3: a page view reaches the dashboard. Check 4: your widget container renders. Add data-dev="true" to the script tag to see each step logged.

Check 1: The Script Loaded and Found Your Project Key

Open your live page (not the editor preview), open DevTools, and type this in the Console:

OperatorStack;

If it returns an object with methods like joinWaitlist and trackEvent, the script ran. The script puts the SDK on window immediately, before it finishes initializing.

If it returns ReferenceError: OperatorStack is not defined, the file never executed. The usual causes:

  • The tag was pasted into a preview-only or draft environment, not the published page.
  • A content security policy blocks the script host. The Console shows a red CSP violation.
  • An ad blocker stripped it. Test in a private window with extensions disabled.

If the object exists but you see [OperatorStack] No data-project attribute found on script tag, the tag is missing its key. The script looks for script[data-project], so the attribute name must match exactly:

<script src="https://operatorstack.dev/os.js" data-project="pk_abc123"></script>

Check 2: The Config Request Returns 200

Open the Network tab, reload, and filter for config. You are looking for one request to:

/v1/projects/pk_abc123/config

A 200 means the script reached the API, your project key is valid, and your settings loaded. Everything after this point depends on that response. If it fails, the script aborts without rendering anything.

StatusMeaningFix
200Config loadedMove to check 3
404Project key not foundCopy the key again from the project page
Failed / CORS errorYour domain is not allowedCheck the landing page URL set on the project
No request at allScript never ranBack to check 1

The script caches config for five minutes. After you change a setting in the dashboard, hard-reload or wait before concluding the change did not apply.

Check 3: A Page View Reaches the Dashboard

Visit the page in a normal tab, then open the project's Analytics view. Your visit should appear within a minute or so. In the Network tab you will also see a POST to /events/batch, which carries the queued events.

If the config returned 200 but no page view arrives, the script skipped tracking on purpose. Three silent causes:

  1. Do Not Track is on. The script checks navigator.doNotTrack and tracks nothing when it equals "1". This is the most common reason a founder cannot see their own visits, because privacy-minded builders often have it enabled.
  2. The path is excluded. If you added excluded path prefixes in project settings, any URL starting with one is skipped.
  3. Analytics is switched off for the project.

Do not trust a missing page view from your own browser as proof of a broken install. Test once from a phone on mobile data or a fresh profile with Do Not Track off.

Check 4: The Widget Renders

The script only draws a widget when two things are true: the page has a container, and that feature is enabled in the project. A missing container produces no error.

<div data-os-widget="waitlist"></div>

For forms the attribute is data-os-form instead. In the Console, confirm the container exists:

document.querySelectorAll("[data-os-widget]").length;

0 means the div never made it into the published HTML. Page builders and React apps often strip or defer unknown attributes, so view the page source of the deployed URL and search for it. If the count is 1 or more and nothing renders, open the project's Waitlist settings and confirm the waitlist is enabled.

Once it renders, submit a test email and confirm it appears in the dashboard. The full end-to-end test lives in the pre-launch waitlist test.

Turn On Dev Mode to See Every Step

When the four checks do not explain it, add one attribute:

<script src="https://operatorstack.dev/os.js" data-project="pk_abc123" data-dev="true"></script>

The Console then prints lines prefixed [OperatorStack]: the project key it initialized with, whether config loaded, "Page view tracked" or the reason it was skipped ("DNT enabled, skipping tracking", "Page excluded from tracking"), and each event flush. The line you are missing tells you which stage broke.

Remove data-dev="true" before launch. It is harmless to visitors but fills their Console with your debug output.

Frequently Asked Questions

How do I know if my OperatorStack script tag is working?

Type OperatorStack in the Console and confirm it returns an object, then check the Network tab for a 200 on the /config request. A page view in the dashboard confirms the full path.

Why does the widget not show up even though the script loaded?

The widget needs a [data-os-widget] container on the page and the feature enabled in project settings. A loaded script with a disabled waitlist renders nothing and logs no error unless dev mode is on.

Why are my page views not showing in the dashboard?

Check Do Not Track in your own browser, excluded paths in project settings, and whether analytics is enabled. The script skips tracking silently in all three cases.

How do I turn on debug logging?

Add data-dev="true" to the script tag. Each step logs to the Console with an [OperatorStack] prefix. Remove it before launch.