--- id: "4ad85403-78ef-4d62-9d82-8d3599c52473" name: "Lightning Setup Aloha iframe" micro_summary: "Lightning Setup can embed legacy Setup pages inside `force-aloha-page.shadowRoot.querySelector(\"iframe\")`; read/click inside that iframe, not the top-level document." status: "resolved" see_also: [] scope: "How to inspect and interact with Classic/Aloha Salesforce Setup pages embedded inside the Lightning Setup shell." warnings: "Top-level `document.querySelectorAll(\"iframe\")` may return 0; check custom elements/shadowRoots (especially `force-aloha-page.shadowRoot`) before concluding there is no iframe." --- ## Pattern Salesforce Lightning Setup can render legacy Setup pages inside a shadow DOM iframe: ```js const frame = document .querySelector("force-aloha-page") ?.shadowRoot ?.querySelector("iframe"); const doc = frame?.contentDocument; ``` Normal top-level page text reads only the Lightning shell. Actual Classic/Aloha page content is in `doc.body.innerText`, and controls live under `doc.querySelector(...)`. ## Minimal extraction ```js (function() { const f = document.querySelector("force-aloha-page")?.shadowRoot?.querySelector("iframe"); const d = f?.contentDocument; return JSON.stringify({ url: d?.URL, title: d?.title, text: (d?.body?.innerText || "").slice(0, 3000) }); })() ``` ## Minimal click ```js (function() { const d = document.querySelector("force-aloha-page")?.shadowRoot?.querySelector("iframe")?.contentDocument; const el = [...d.querySelectorAll("a,input,button")].find(e => (e.textContent || e.value || e.title || "").trim() === "TARGET TEXT" ); el?.click(); return JSON.stringify({ clicked: !!el, href: el?.href, value: el?.value }); })() ``` Use direct DOM `click()` inside the iframe for same-origin Salesforce Setup pages, or compute iframe-relative rects if a real mouse click is needed.