Back to Knowledge Hub
Platform

Origin Trials and Experimental Web Platform Features

Evaluate origin trials with explicit enrollment, runtime detection, fallback, and rollback boundaries.

BotBrowser Team

Documentation

Want the structured docs for Platform?

This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.

Scoped origin enrollment leads to detection and a fallback

An origin trial is scoped enrollment, not universal browser support. A token can enable an experimental feature for a declared origin and period, while permissions, policy, accessibility, and application completion remain separate responsibilities. Treat the trial as a bounded experiment: identify the feature, token scope, browser channel, user task, fallback, and rollback trigger before shipping it. Never infer identity or device class from an experimental API. The useful question is not “does this browser support the feature?” but “under which declared conditions can this page safely offer the feature, and what happens when those conditions disappear?” A trial may be enabled only on stable or beta channels, may require a secure context, may be rejected in an iframe, and may stop working when its token expires. A token can also be valid while a permission prompt is denied or while an application endpoint is unavailable. Keep those observations separate in the release record. The record should name the origin, token scope, browser build, feature state, permission expectation, visible fallback, and owner of the next review. This prevents a successful experiment from becoming an accidental permanent dependency.

Enrollment scope

Read the Chrome origin-trials guidance and the relevant MDN API documentation. Record token owner, origin, expiry, browser channel, secure-context requirement, and expected exposure. A token for one origin does not prove behavior on a subdomain, an iframe, a local test host, or another browser family. Keep experimental and stable paths visibly separate. Before enabling a token, decide how it enters the page, who can rotate it, and how it is removed. Do not place a long-lived token in a public example or collect it in an analytics request. Test an expired token and a missing token as first-class branches. If the feature is exposed through an iframe, document the parent origin, allowlist, and permission policy. If the feature depends on a user gesture, make the gesture part of the fixture rather than calling the API during page load. These details are part of enrollment evidence because a trial is a deployment condition, not a browser identity label.

Runtime detection

Check the method or constructor immediately before use. A detected property means only that the page can attempt the feature. Handle missing methods, rejected promises, permission denial, policy blocks, and server errors as different states. Preserve user input and offer an accessible alternative. Do not parse user agents or collect unrelated browser properties. Use a small state machine for the experiment: unenrolled, available, denied, failed, and completed. unenrolled covers absent or expired tokens and should choose the stable path without a hidden retry. available permits one primary attempt. denied explains the permission result and keeps the alternative usable. failed records an exception or rejection and stops repeated prompts. completed requires the visible application acknowledgement, not merely a resolved browser promise. Keeping these states stable across browser builds makes a release comparison meaningful and keeps support reports from collapsing policy, permission, and service errors into one “unsupported” label.

Decision table

ObservationDecisionVisible resultBoundary
Token and method are validtry onceannounce progressenrolled browser context
Token missing or expireduse fallbackkeep task availableenrollment state
Permission denied or policy blocksexplain and fallbackpreserve controlruntime policy
Call rejectsclassify and stop hidden retriesshow recoverybrowser behavior
Call resolvesverify application acknowledgementconfirm visible completionbrowser plus application

Failure fixture

Create status and fallback nodes inside the fixture, exercise missing and rejected branches, assert visible text, and remove nodes in finally. The fixture is synthetic evidence, not a production outage claim.

async function runTrialFixture() {
  const host = document.createElement('div');
  host.innerHTML = '<p id="status"></p><button id="fallback" hidden>Use fallback</button>';
  document.body.append(host);
  const status = host.querySelector('#status');
  const fallback = host.querySelector('#fallback');
  try {
    const enabled = typeof navigator.share === 'function';
    const state = enabled
      ? await navigator
          .share({ title: 'Synthetic trial', url: '/fixture' })
          .then(() => 'completed')
          .catch(() => 'failed')
      : 'missing';
    status.textContent = state === 'completed' ? 'Completed' : 'Use fallback';
    if (state !== 'completed') fallback.hidden = false;
    console.assert(status.textContent && (state === 'completed' || !fallback.hidden));
    return state;
  } finally {
    host.remove();
  }
}

Rollout and rollback

Record token expiry, candidate builds, visible assertion, owner, and rollback trigger. A resolved browser promise is not server completion. Roll back for elevated exceptions, inaccessible fallback, trapped focus, or missing application acknowledgement. Keep the trial token out of public logs and rotate it when the experiment ends. Rollout evidence should include a baseline stable path and an experimental path. Compare the same synthetic task in a fresh context, then repeat the task with the permission state the product actually supports. Capture the first meaningful failure, preserve cleanup failures separately, and never turn an uncertain retry into a pass. A useful rollback trigger is observable: a status remains pending, the fallback loses entered data, keyboard focus disappears, or the application acknowledgement stops arriving. Avoid triggers based only on a browser version string. When the experiment ends, remove the token, keep the stable path, and retain the decision record long enough to explain customer reports from the trial period.

For teams operating several origins, keep enrollment records separate. A token issued for app.example is not evidence for admin.example, a local development host, or a customer-controlled embed. A trial can also have different behavior in top-level and embedded contexts because permission policy and user activation differ. Test each context that the product serves and state which contexts remain unsupported. Do not broaden an allowlist merely to make a synthetic check pass. The fallback should explain the limitation without exposing token details or encouraging a user to change security settings.

Experimental features often change shape before they stabilize. A renamed method, changed exception, or altered default can make an old fixture look like a browser regression when the real issue is an obsolete assumption. Pin the fixture revision, read the current specification or vendor note, and update the expected state deliberately. If a change is incompatible, keep both paths during migration and measure the visible result at the same application boundary. A release note and an origin-trial dashboard can guide investigation, but neither replaces a user-facing assertion. The team owns the meaning of “done.”

Accessibility and privacy remain release gates during an experiment. A permission prompt must have a labelled action and a way to cancel. A fallback must be keyboard reachable, announce its status, and preserve text or files already selected. Logs should contain the feature state and error category, not raw profile content, credentials, location, or unrelated fingerprint properties. A controlled browser context can make a branch repeatable while still leaving the application responsible for data retention, server cleanup, and accessible copy. Treat those boundaries as part of the experiment design instead of as follow-up work after the token expires.

Maintenance and BotBrowser

Recheck enrollment after browser updates, token changes, policy changes, and specification updates. BotBrowser can provide controlled contexts for authorized origin-trial journeys and repeatable fallback checks. It does not issue trial tokens, grant permissions, certify experiments, or prove upstream completion. Its isolation documentation supports repeatability, not universal compatibility.

For related guidance, read the browser API fallback guide and the WPT confidence guide. Keep standards evidence, runtime behavior, and application results as separate claims.

Review the experiment as a product change

An origin trial belongs in the same change review as the feature it enables. The reviewer should be able to identify the user task, the stable path, the experimental path, the token owner, and the removal date without opening a private dashboard. This is not bureaucracy around a browser flag. It is the minimum information needed to decide whether a page can remain useful when the trial is unavailable.

Write the task in user terms. “A share button completes” is more useful than “the API returned a promise.” “A report remains downloadable” is more useful than “the constructor exists.” The browser signal helps choose the next branch, while the visible application acknowledgement decides whether the task completed. Keep those statements next to one another in test output so a reviewer cannot accidentally promote a browser-only result.

Use a stable synthetic record for comparisons. It should contain only the values needed to exercise the feature and fallback, and it should be created by the test owner. Do not use a customer account to obtain a token or to check whether a private origin is enrolled. If a service result is needed, ask its owner for a documented synthetic endpoint and record the service result separately from the browser observation.

Plan token rotation as a normal maintenance event. Before expiry, verify that the fallback still preserves input and focus. Rotate through the approved owner, then run an enrolled and an unenrolled case. After expiry, remove the token from the environment and confirm that the stable route appears without a hidden retry. A stale token in a cache or copied fixture can make an expired experiment appear active, so make the enrollment source visible in the receipt.

Embedded contexts require their own acceptance case. A top-level page may have user activation and permission policy that an iframe does not. Test the parent origin, iframe origin, allowlist, and activation sequence that the product actually ships. When an embedded case is unsupported, show the same useful fallback rather than expanding permissions or allowing an untrusted origin merely to satisfy a test.

A feature can be available yet unsuitable. It may expose a permission prompt that is confusing, return a result too late for the task, or fail to preserve a selected file. Classify these as product outcomes, not as browser support data. The experiment owner can decide to keep the stable path even when the API technically works. A compatibility table cannot make an inaccessible or confusing interaction acceptable.

When comparing browser channels, hold the application build and token scope constant. Change only the channel or browser release, and record the resolved build. Compare the same visible assertion, fallback copy, focus order, and cleanup receipt. A difference in a version string is a clue for investigation, not a rollback trigger by itself. Conversely, a broken fallback is a rollback signal even when the API still reports as available.

Keep the test fixture intentionally small. One missing-token case, one expired-token case, one denied-permission case, and one rejected-call case usually identify the important boundaries. Add a separate case only when it maps to a supported user journey. More branches do not improve confidence if their outcomes are not observable or if they require collecting unrelated browser properties.

The decision record should answer five questions: what was enrolled, where, until when, what did the browser expose, and what did the user see? Add the owner, candidate build, fallback result, and cleanup status. If any answer is unavailable, mark the experiment incomplete instead of filling the gap with an inferred browser identity. This record supports both release review and customer support without retaining the token itself.

At retirement, remove the trial token from page configuration, test secrets, and deployment manifests according to the owners responsible for each location. Confirm that the stable route remains reachable and that old cached assets do not re-enable the experiment. Retain the short decision record and approved synthetic receipt for the support window, then expire artifacts under the normal policy. Retirement is complete when the product has a supported path without the token, not merely when the dashboard marks the trial closed.

Make enrollment observable

An enrollment check should identify the source of the token without exposing its value. A response header, build manifest identifier, or controlled configuration label can show which experiment a page received. Record the label and expiry separately from the browser result. If the label is missing, treat the page as unenrolled rather than guessing from a successful constructor. This makes a copied staging configuration fail safely when it reaches a production-like host.

The origin boundary deserves a concrete test. A top-level https://app.example page, an embedded frame, and a local test host are different enrollment conditions. Run the same synthetic action in each supported context and write the expected fallback for unsupported contexts. Do not broaden the token allowlist simply because an iframe test is convenient. An explicit unsupported result is more useful than a token that appears to work outside its approved scope.

Separate browser and application evidence

The browser can report that a method exists, a permission prompt appeared, or a promise resolved. The application must decide whether the resulting action is acceptable. For example, a share promise can resolve while the receiving surface is unavailable, and a file API can return an object while the application has not saved it. Use a visible acknowledgement, a documented status endpoint, or a service-owned receipt for the application fact. Keep the two observations in separate fields so a support engineer can identify which owner must investigate.

If the application acknowledgement is late, preserve the first attempt status before considering a retry. A second click may create a duplicate request or a second permission prompt. The fixture should either query an idempotent status or stop with an uncertain outcome. “Eventually completed” is not enough to claim that a trial was safe when the original attempt may still be active.

Review permission and accessibility changes

Permission behavior is part of the experiment contract. A browser channel can change whether a prompt appears, whether a user gesture is required, or whether an embedded frame is eligible. Test denial and cancellation as normal paths. The fallback action needs an accessible name, keyboard focus, a status announcement, and a way to return to entered data. A token that enables a feature but leaves a keyboard user without a usable alternative is not a successful rollout.

Record only the category of permission result in routine output. Do not copy account names, location values, device identifiers, or prompt text that is not needed to select the fallback. A short category such as denied, blocked-by-policy, or cancelled helps compare builds while limiting retention. If a service owner needs more detail, route the request through that service's evidence policy rather than expanding browser collection.

Keep trial updates reversible

Before changing a token or browser channel, preserve the stable path and its receipt. Deploy the experimental path behind the smallest supported audience and keep the fallback available in the same build. A rollback should remove enrollment or disable the experimental branch without deleting the stable implementation. Verify the user-visible task after rollback, because a page can stop calling the API while still losing a selected value or focus target.

When an origin trial expires, the absence of the feature is expected. The test should assert that the stable path appears, not that an error is hidden. If a token is renewed, compare the new expiry and owner with the prior record and run the missing-token case again. This catches deployments that accidentally retain a stale token in a cache or a copied test fixture.

Maintain a compact support record

For each experiment, retain feature name, origin category, token owner label, expiry, browser channel, application build, detection state, visible result, fallback result, and cleanup status. Add the decision owner and next review date. Exclude token values and personal content. This record is enough to explain why a customer saw a fallback without turning the support system into a browser-profile store.

Review the record when the API specification, vendor guidance, browser policy, or application route changes. A new specification note can change the expected permission or iframe boundary even when the browser binary is unchanged. Conversely, a browser update can preserve the API while changing the timing of a prompt. Re-run the bounded cases that map to the changed assumption and update the contract before changing the fallback.

Sources

#Origin Trials#Experimental Features#Web Platform#Feature Detection#Rollout

Take BotBrowser from research to production

The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.