Recipes

Copy/paste patterns for common workflows.
Docs updated: 2026-03-24

Status banner (detect + allow-list)

<div id="rtoStatus"></div>

<script src="../RTO_helpers/RTO_form_api.js"></script>
<script src="../RTO_helpers/RTO_connector.js"></script>
<script src="../RTO_helpers/RTO_domainList.js"></script>
<script>
RTOconnectOnce(1500).then(function(connected){
  var host = location.hostname;
  var box = document.getElementById("rtoStatus");

  if(!connected){
    box.textContent = "RTO extension not detected.";
    return;
  }

  return RTOAllowlist.has(host).then(function(allowed){
    box.textContent = allowed
      ? "RTO ready on " + host
      : "RTO detected, but " + host + " is not allow-listed yet.";
  });
});
</script>

Open or focus a tab

// Open-or-focus pattern
async function openOrFocus(tabKey, url){
  return RTOForm.openTab(
    { "tabKey": tabKey, "url": url, "focus": true, "newTab": true },
    { "timeoutMs": 20000 }
  );
}

openOrFocus("billing", "https://example.com/billing");

In 7.13.0, reusing the same tabKey is the normal path. The background serializes openTab per key to avoid duplicate tabs.

List open controlled tabs (UI)

This uses RTO_openTabsListing.js to fill a table body.

<table class="table table-sm">
  <thead><tr><th>tabKey</th><th>URL</th></tr></thead>
  <tbody id="openTabsBody"></tbody>
</table>

<script src="../RTO_helpers/RTO_form_api.js"></script>
<script src="../RTO_helpers/RTO_connector.js"></script>
<script src="../RTO_helpers/RTO_tabsList.js"></script>
<script src="../RTO_helpers/RTO_openTabsListing.js"></script>

Edit remote HTML with a local textarea

Wire buttons with RTO_DOM_actions.js:

<textarea id="localHtml" data-rto-mark-dirty="1" style="width:100%;min-height:140px"></textarea>

<button data-rto-action="read-block"  data-rto-tabKey="app" data-rto-selector="#content" data-rto-target="#localHtml">
  Read remote HTML
</button>

<button data-rto-action="write-block" data-rto-tabKey="app" data-rto-selector="#content" data-rto-target="#localHtml">
  Write remote HTML
</button>

<script src="../RTO_helpers/RTO_form_api.js"></script>
<script src="../RTO_helpers/RTO_DOM_actions.js"></script>

Allow-list needed banner

Show this when you catch DOMAIN_NOT_ALLOWED from an RTO call:

<script src="../RTO_helpers/RTO_form_api.js"></script>
<script src="../RTO_helpers/RTO_domainList.js"></script>

<script>
// Minimal "allow-list needed" banner
function showAllowBanner(host){
  const el = document.createElement("div");
  el.style.cssText = "position:fixed;bottom:12px;left:12px;right:12px;padding:12px;background:#111;color:#fff;border-radius:12px;z-index:9999;";
  el.innerHTML = `
    <div style="display:flex;gap:10px;align-items:center;justify-content:space-between;flex-wrap:wrap">
      <div>
        <b>RTO:</b> This host is not allow-listed: <code>${host}</code>
      </div>
      <button id="allowBtn" style="padding:6px 10px;border-radius:10px;border:1px solid rgba(255,255,255,.25);background:#222;color:#fff">
        Allow host
      </button>
    </div>`;
  document.body.appendChild(el);

  el.querySelector("#allowBtn").addEventListener("click", async function(){
    try{
      const ok = await RTOAllowlist.add(host, 130000);
      el.remove();
      alert(ok ? "Allowed after master-tab confirmation ✓" : "Not added (cancelled or not approved).");
    }catch(_){
      el.remove();
    }
  });
}
</script>

Keep the wording explicit for beginners: the page asks here, but the approval is visible on the master tab.

Next