Skip to content

feat: allow a full origin in domain so the launcher can load from a bundled extension - #115

Open
mattbodle wants to merge 1 commit into
developmentfrom
feat/launcher-origin-scheme
Open

feat: allow a full origin in domain so the launcher can load from a bundled extension#115
mattbodle wants to merge 1 commit into
developmentfrom
feat/launcher-origin-scheme

Conversation

@mattbodle

Copy link
Copy Markdown
Collaborator

Background

Inside an MV3 browser extension, all executable code must ship inside the extension package — fetching JS from a remote host at runtime ("remote hosted code") is forbidden. The Rokt self-contained extension bundle (app.js = mParticle Web SDK + this Kit) exists precisely to satisfy that policy: launcher.js, the controller, etc. are all bundled into the extension under /rokt/wsdk/….

However, when the Kit needs the launcher it builds the URL via generateBaseUrl(domain), which assumes domain is a bare host and always prepends https://. So the Kit can only load launcher.js (and the thank-you element) from a remote https://<domain> origin — which is remote hosted code, and there's no way to point it at the extension's own bundled copy. mp.Rokt.domain and launcherOptions are the only inputs, and neither can express a chrome-extension:// (or otherwise full) origin.

What Has Changed

  • generateBaseUrl now treats a domain that already carries a scheme as a full origin and uses it verbatim (trailing slashes trimmed so path joins stay clean); a bare host keeps the https:// default. This mirrors the existing generateReportingUrl handling for configuredUrl.
  • With this, an extension can set window.mParticle.Rokt.domain = chrome.runtime.getURL('rokt').replace(/\/$/, ''), and the Kit loads launcher.js from chrome-extension://<id>/rokt/wsdk/integrations/launcher.js — entirely in-package, MV3-compliant. http:// origins also now work for local development.
  • The ad-block measurement probe is skipped for scheme-bearing origins, where the previously https://-prefixed URL would be malformed and the probe meaningless.
  • Added unit tests for generateLauncherScript / generateThankYouElementScript covering chrome-extension:// origins, trailing-slash trimming, and http:// origins. Bare-host (CNAME) behaviour is unchanged.

Testing

  • npm run lint — clean
  • npm test — 232 passed (4 new)
  • npm run build — succeeds

🤖 Generated with Claude Code

@mattbodle
mattbodle force-pushed the feat/launcher-origin-scheme branch from 4d2cd3a to cc3bdb2 Compare August 13, 2026 23:34
…undled extension

generateBaseUrl assumed domain was a bare host and always prepended https://,
so the Kit could only fetch launcher.js (and the thank-you element) from a
remote https host. Inside an MV3 browser extension that is remote hosted code,
which the platform forbids — the extension must load the launcher from its own
package.

Treat a domain that already carries a scheme as a full origin and use it
verbatim (trailing slashes trimmed), mirroring the existing generateReportingUrl
handling. Extensions can now set mp.Rokt.domain to chrome-extension://<id>/rokt
and the Kit loads launcher.js from the bundle; http:// origins also work for
local development. Bare hosts (CNAMEs) keep the https:// default. The ad-block
probe is skipped for scheme-bearing origins where it would be malformed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mattbodle
mattbodle force-pushed the feat/launcher-origin-scheme branch from cc3bdb2 to aa72d25 Compare August 13, 2026 23:38
@mattbodle
mattbodle changed the base branch from main to development August 13, 2026 23:38
Comment thread src/Rokt-Kit.ts
function generateBaseUrl(domain: string | undefined) {
const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;

if (resolvedDomain.includes('://')) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about keeping reporting on the API domain for non-HTTP schemes, or separating the asset and reporting base URLs? Because generateReportingUrl also calls generateBaseUrl. maybe something like:

const hasNonHttpScheme = domain?.includes('://') && !/^https?:\/\//i.test(domain);
const reportingDomain = hasNonHttpScheme ? undefined : domain;

return generateBaseUrl(reportingDomain) + endpoint;

This keeps bare CNAME and HTTP(S) reporting behavior while falling back to the default API domain for extension schemes.

Comment thread src/Rokt-Kit.ts
return;
}

if (domain && domain.includes('://')) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why we skip this probe for every scheme-bearing domain. What do you think about skipping only extension or local schemes and covering both HTTPS and extension origins in tests?

if (domain && domain.includes('://') && !/^https:\/\//i.test(domain)) {
  return;
}

const existingBaseUrl = domain ? generateBaseUrl(domain) : 'https://apps.rokt.com';
createAutoRemovedIframe(existingBaseUrl + '/v1/wsdk-init/index.html?' + params);

I would also add one test proving a full HTTPS origin still creates the probes and another proving a chrome-extension:// origin does not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants