Remote Tab Opener · Site docs: 7.10.1 · Install the extension, then reload to show installed version

Remote Tab Opener – Multi-Tab, Cross-Domain Tab Automation

Control one or multiple tabs securely from your own admin page. No server. No proxy. LAN/localhost available via opt-in.

Firefox ✓ · Chrome (MV3) in progress
MIT · No data collection

What It Is

Remote Tab Opener lets a secure page you control open, navigate and focus one or more tabs through a browser extension acting as a safe bridge. Your page emits commands; a content script executes them inside the target tab(s) on allow-listed hosts. It’s a lightweight Firefox browser extension built for cross-domain tab automation with window.postMessageno backend required.

How It Works (3 steps)

  1. Your admin page sends a window.postMessage() command (or the ask() helper with requestId + timeout).
  2. The extension validates the request (allow-listed domain, named action, HTTPS-only, optional LAN/localhost flags) and routes it to a controlled tab.
  3. The content script performs the action in the controlled tab (open, navigate, focus, read URL, fill form, submit…).

This does not bypass SOP: the extension runs in the target tab with explicit host permissions.

See our full working L

This does not bypass SOP: the extension runs in the target tab with explicit host permissions.

See our full L

This does not bypass SOP: the extension runs in the target tab with explicit host permissions.

Key Features

  • Open a new tab from any secure admin page.
  • Navigate and focus the remote tab across domains.
  • Read the current URL or title in real time.
  • Predefined safe DOM actions on allow-listed hosts (fill, click, submit, wait).
  • Multi-tab targeting via tabKey or tabId (listTabs, adoptTab, releaseTab).
  • LAN/localhost support (opt-in flags + allowlist).
  • Favorites & local history.
  • Firefox support now; Chrome (MV3) coming soon.

Remote Tab Opener cover

Capabilities at a Glance

Tab Control (background)
  • open / openTab – open a controlled tab by URL (optionally with tabKey);
  • navigate – change URL of a targeted tab (tabKey or tabId);
  • focus – bring the targeted tab to front;
  • getUrl – read the current URL or title;
  • listTabs, adoptTab, releaseTab — manage multiple tabs;
  • optional close – close a targeted tab (policy-dependent).

APIs used: tabs.create / update / sendMessage / query / get / (optional) remove.

DOM Actions (content script)
  • focusElement, setValue, click, submit
  • waitFor (SPA timing)
  • runJs – predefined routines only (no dynamic eval)

Runs inside the target page on allow-listed hosts.

Messaging & Events
  • Page A → Extension: window.postMessage({...}) or ask(action, args)
  • Background ↔ Content: runtime.sendMessage
  • Events back to A: tabStatus, tabPageChanged, RTOM_USER_NOTICE

Stable schemas + origin tagging to avoid cross-talk.

Safety & Admin
  • Domain allow-list (popup UI) + LAN/localhost flags (opt-in)
  • No data collection; no external requests; no eval()
  • Favorites & local history management
  • Debug logging toggle (off by default)

Respects SOP, executes via the extension layer.

Real-World Flows (aka E2E) — without the overhead

What this means: simulate a real user path end-to-end — open → type → click → navigate → verify — using your own admin page. No Selenium, no CI rig, no remote grid.

  • ✔️ Runs in your browser, locally, with a real tab.
  • ✔️ Uses requestId + timeout for robust request/response pairing.
  • ✔️ Safe by default: named DOM actions, HTTPS-only, allow-listed hosts.
  • 🚫 No arbitrary eval(), no SOP bypass, no data collection.
Minimal "flow" using the ask() helper (recommended)
<script type="module">
// Paste the ask() helper from the docs, then:
(async () => {
  const det = await ask('detect'); if (!det.ok) return console.warn(det.error);
  await ask('openTab',   { url: 'https://example.org', tabKey:'sales',   focus:true });
  await ask('domType',   { selector: '#q', value: 'rto demo', clear: true, tabKey:'sales' });
  await ask('domClick',  { selector: 'form button[type=submit]', tabKey:'sales' });
  const page = await ask('getCurrentUrl', { tabKey:'sales' });
  console.log('Now at:', page.ok ? page.data.url : '(unknown)');
})();
</script>

Prefer this contract over the legacy short messages. It gives typed responses and canonical error codes.

Remote Tab Opener cover

What it does / does not do
✅ You can
  • Drive one or several tabs using tabKey / tabId.
  • Wait for SPA elements and click/type safely.
  • Focus/close a targeted tab when needed.
🚫 You cannot
  • Bypass Same-Origin Policy or read cookies.
  • Execute arbitrary code on arbitrary sites.
  • Automate file uploads (<input type="file"> limitation).

See the live E2E demonstration examples NOW.

Security by design

  • Runs locally in your browser — no backend required.
  • Works only on domains you authorize (allow-list).
  • LAN/localhost require explicit opt-in in the popup and must be present in the allow-list (double barrier).
  • Predefined actions executed by the extension’s content script (no arbitrary code).
  • Respects browser security rules (no SOP bypass; clean messaging).

See the LAN/localhost page and full notes in the official documentation.

Security control banner (v7.10.1)

Controlled tabs can show a thin security banner at the very top. In v7.10.1, the banner is available on demand, can be minimized to a movable pill, and its position persists. When applicable it displays the current tabKey.

  • Visible only in the controlled tab (never in other tabs).
  • One-click minimize → compact, draggable chip.
  • Reappears after open, navigate, or reload.
  • If the target page blocks JS injection, the banner is absent (tab is not controlled).
Quick try:
  1. Open a remote tab from the master page (e.g. tabKey:"sales").
  2. Click Minimize on the banner.
  3. Drag the orange chip wherever you like.
  4. Reload the remote page → banner comes back.
This tab is controlled by RTOM — tabKey: sales
RTOM

Try it: Click Minimize to collapse the banner into an orange, draggable chip (with the animated red dot).

Drag the chip anywhere inside this box; click on the chip to restore the banner.

Browser Limits — What RTO Solves

Remote Tab Opener does not break browser security. It uses the extension layer to provide capabilities that ordinary pages don’t have, while still respecting Same-Origin Policy and user consent.

Native Limitation What RTO Enables (legit & local) What RTO Will Not Do
Page A cannot directly control a tab on another domain. Open / navigate / focus a remote tab via the extension bridge; execute predefined actions inside that tab (allow-listed host). No cross-origin script injection; no universal control of arbitrary sites.
No safe cross-tab messaging across unrelated origins. Use window.postMessage → background → content script to relay commands with origin tagging and request/response pairing. No hidden channels; no iframe hacks or postMessage to unknown pages.
Pages can’t reliably bring background tabs to front. focus brings the targeted tab to foreground (via extension APIs). No stealing focus randomly; only for known targeted tabs.
Direct DOM automation is scoped to same-origin only. DOM actions (waitFor, setValue, click, submit) and runJs run in the target tab via a content script on hosts you approved. No arbitrary eval(); no access to page scripts beyond selected actions.
Reading another tab’s URL/title is restricted. getUrl / getTitle return current state from the targeted tab (through the extension). No network interception; no cookie/session access.
SPAs render late; selectors are brittle. waitFor handles async rendering before acting; recommends stable id / data-* selectors. Does not bypass CSRF/auth flows; does not fill <input type="file"> programmatically.
Hard Guarantees
  • No SOP bypass. Actions run in the target tab with explicit host permission (allow-list).
  • No data collection. No cookies access, no webRequest interception, no remote servers.
  • Local-only. All logic lives in the browser (background/content scripts + postMessage).
  • User control. You choose which domains are controllable via the extension popup.

Quick Snippets (copy & run)

Modern contract (multi-tabs): open + type + submit
<script type="module">
// ask(action, args, { timeoutMs }) returns { ok, data } or { ok:false, error:{ code, message } }
(async () => {
  const det = await ask('detect'); if (!det.ok) return;

  // Control 2 tabs in parallel using tabKey
  await ask('openTab', { url:'https://example.org/login', tabKey:'auth', focus:true });
  await ask('openTab', { url:'https://status.example',    tabKey:'monitor', focus:false });

  // Work on "auth" tab
  await ask('domType',  { selector:'#email',    value:'user@example.org', tabKey:'auth' });
  await ask('domType',  { selector:'#password', value:'s3cret',           tabKey:'auth' });
  await ask('domClick', { selector:'form button[type=submit]',            tabKey:'auth' });

  // Read current URL from "monitor" tab
  const u = await ask('getCurrentUrl', { tabKey:'monitor' });
  console.log('Monitor at:', u.ok ? u.data.url : '(unknown)');

  // Optional: list/adopt/release by id
  const list = await ask('listTabs'); // -> { items:[{tabId, tabKey, url, title, focused}, ...] }
  if (list.ok && list.data.items.length) {
    await ask('adoptTab',   { tabId: list.data.items[0].tabId, tabKey:'ops' });
    await ask('navigate',   { url:'https://example.org/tools', tabKey:'ops' });
    await ask('releaseTab', { tabKey:'ops' });
  }
})();
</script>
Bring a tab to front (new in v7.10.1)
// Focus the "sales" tab by key
await ask('focus', { tabKey: 'sales' });

Tip: add your admin origin to the allow-list. To target intranet/localhost, enable the popup flags and keep hosts in the allow-list (double barrier).

Legacy quick messages (kept for compatibility)
<script>
/* open a new controlled tab (legacy) */
window.postMessage({ type:'open', url:'https://example.com', origin:'admin-page' }, '*');

/* navigate the controlled tab (legacy) */
window.postMessage({ type:'navigate', url:'https://example.com/next', origin:'admin-page' }, '*');

/* bring the controlled tab to front (legacy) */
window.postMessage({ type:'focus', origin:'admin-page' }, '*');
</script>
Need help writing safe flows?
Try the ChatGPT helper: Remote Tab Opener Copilot.

Use Cases

🔐
Moderate external content

Open a controlled tab to preview user content and move through submissions without leaving your dashboard.

🧪
QA navigation flows

Launch test sessions, navigate across cases, and monitor the active URL programmatically.

🧭
Guided support

Open the right help page, bring it to front when needed, and close it once the issue is resolved.

🚀
Admin workflows

Streamline repetitive navigation across domains from a single secure hub.

FAQ (short)

Does this bypass the Same-Origin Policy? No. The extension executes actions inside the target tab with explicit host permissions.

Do I need a server or proxy? No. Everything is local in the browser.

Chrome? Planned for MV3.

Is any data collected? No. The extension declares no data collection.

Where do I configure allowed domains? In the extension popup (allow-list). For LAN/localhost, enable the dedicated flags too.

How do I control 2 tabs? Use tabKey (e.g. "sales", "monitor") or a tabId from listTabs. See the snippets above.

Changelog (short)

  • 2025-10-31 — v7.10.1: MV3-ready; new focus handler; stronger background relay; per-host action queue; on-demand “Controlled by RTO” banner; sanitized reads; full demo update (Google→YouTube, DTI form); no data migration.
  • 2025-10-26 — v7.10.0: Multi-tab control with tabKey/tabId, new actions listTabs/adoptTab/releaseTab, security banner shows tabKey, LAN/localhost policy now opt-in (flags) + allow-list.
  • 2025-10-25 — v7.9.3: Admin demo finalized (Steps 1–10), state sync on reload, radio/checkbox mirroring, submit+focus fix.
  • 2025-10-21 — v7.9.2: Control banner (controlled tabs only), single controlled tab, stronger allowlist, new safe style actions (highlight / domSetStyle / selectSetValue).
  • 2025-10-19 — v7.9.1: Safe named DOM actions on whitelisted sites, search-engine allowlist seeding, manifest fix, UX polish.
  • 2025-10-18 — v7.9: Deny-by-default, interactive allowlist, focus control, optional request blocking (Firefox).
  • 2025-10-17 — v7.8: Bounded HTML extraction; security guards & robust re-injection.
  • 2025-10-04 — v7: Focus A→B added.
  • 2025-05-20 — v6: Favorites UI, domain allow-list.
  • 2025-02-12 — v5: Initial public release on AMO.
View the complete changelog

Honest comparison — RTO vs. alternatives

A visual, no-nonsense guide to when each tool shines.

TL;DR: Downloading HTML ≠ Reading the rendered DOM. RTO queries the live, post-JavaScript DOM of a real tab and orchestrates named tabs with tabKey — perfect for demos, teaching, and local tooling.
What RTO does best
  • ✅ Reads the rendered (post-JS) DOM from a live tab
  • Named tab control: open / focus / close / navigate
  • Teaching-friendly UX: highlights, safe previews, tiny snippets
  • Local & visible: no cloud relay, allow-listed actions
  • Low setup: browser extension + small scripts
When another tool is better
  • 🏭 Headless at scale (CI farms): Playwright / Puppeteer
  • 🧪 Heavy E2E UI testing: WebDriver / RPA suites
  • 📄 Pure SSR/static pages: fetch() / view-source suffices
  • 🧩 One-off tweaks: userscripts / bookmarklets

Competitors

RTO - Remote Tab Opener

Live DOM orchestration for real, visible tabs — great for demos and education.

Rendered DOM ✓ Tab keys ✓ Local & visible ✓ Low setup ✓
  • Use for: multi-tab demos, manual QA, teaching SPA realities
  • Avoid for: huge headless farms / heavy CI
Lightweight View-source / fetch()

Reads downloaded HTML only — great for SSR, blind to SPA hydration.

Rendered DOM ✗ Zero setup Static pages only
  • Use for: server-rendered pages, sitemap sweeps
  • Avoid for: YouTube-like SPAs (no hydrated anchors)
Headless Playwright / Puppeteer

Full-power browser automation, perfect for CI — not ideal for live teaching.

Rendered DOM ✓ Heavy setup No live visuals
  • Use for: scale, reliability, regression checks
  • Avoid for: human-visible demos / quick workshops
Enterprise WebDriver / RPA

Broad UI control across apps, but verbose and brittle for SPA scraping.

Rendered DOM ✓ Infra & maintenance Complex flows
  • Use for: enterprise E2E & legacy stacks
  • Avoid for: lightweight, local demos
Hobbyist Userscripts / Bookmarklets

Quick wins inside the current page; limited cross-tab control.

Rendered DOM (same tab) No tab orchestration Low friction
  • Use for: small tweaks, shortcuts, helpers
  • Avoid for: multi-tab workflows
Integrated ChatGPT Atlas (built-in)

Great at reading the current view; doesn’t orchestrate external tabs.

Rendered DOM (context) No cross-tab control Low setup
  • Use for: reading & assistance in the active window
  • Avoid for: named multi-tab flows
If you need to show learners the real, hydrated DOM and control named tabs in a way that’s safe, local, and easy to follow, RTO is the right hammer for the job.
© 2025 Remote Tab Opener — Home
Author: Francesco Ruffo de Bonneval