browser extensionsJavaScriptAIDOMweb pages

How AI Browser Extensions Handle JavaScript-Rendered Content

Most web pages today render their content with JavaScript after the initial HTML loads. Here's what that means for AI browser extensions trying to read and understand what's on your screen.

· By Browsy Team

Key takeaways

  • Modern web pages often render content via JavaScript after the initial HTML load, making the raw HTML source useless for tools that only parse it.
  • AI browser extensions that run as content scripts see the live DOM — the fully rendered page — not the raw HTML, which is why they work on React, Vue, and Angular sites out of the box.
  • Shadow DOM, lazy loading, and cross-origin iframes each create scenarios where content may not be accessible until user interaction or special API access.
  • Browsy reads the page's rendered text from the live DOM, so it works on single-page applications the same way it works on static sites.

If you open a modern web page’s source code (Ctrl+U in Chrome), what you see is often not what you get. A news article might appear as a nearly empty HTML shell containing a handful of <div> containers and a bundle of JavaScript file references. The actual article text — the content you want an AI to read — doesn’t exist in that source. It gets inserted into the page after JavaScript runs.

This is the core technical challenge for any AI tool that tries to read web content.

How JavaScript rendering works

The web’s original model was simple: a server sends HTML, the browser displays it. That model still works for simple sites. But starting around 2010, single-page application (SPA) frameworks like Angular, Backbone, and later React and Vue changed the pattern for most of the web.

In an SPA, the server sends a minimal HTML document — often just <div id="root"></div> and a few script tags. The JavaScript bundle downloads, executes, fetches data from an API, and builds the page content in memory. The browser then inserts that content into the DOM. From the user’s perspective, the page loads normally. From a traditional web scraper’s perspective, there is nothing there.

This is why tools that download a URL and parse the HTML — command-line utilities, simple scrapers, many browser extensions from the early extension era — often return empty or incomplete results on modern sites.

What a content script sees instead

Chrome browser extensions can run as content scripts — JavaScript files that execute inside the context of a tab, with access to the page’s live Document Object Model (DOM). The DOM is the browser’s internal representation of the page as it currently appears, after all JavaScript has run and all content has been rendered.

A content script running on a React-powered news site doesn’t see the raw HTML from the server. It sees the full rendered text of the article, comments, navigation, and everything else the page has built at that moment — the same content a user sees when they highlight text on screen.

This is the mechanism that makes Browsy work on sites that would stump a traditional scraper. It reads the page the way a user does, from inside the browser that has already rendered everything.

Edge cases that still create friction

Content script access to the live DOM solves most cases, but a few patterns still create friction:

Shadow DOM. Web components can encapsulate their markup in a shadow root — a subtree of the DOM that is intentionally isolated from the rest of the page. Standard DOM queries like document.querySelectorAll do not cross shadow boundaries. Extensions that need to reach inside them have to use chrome.dom.openOrClosedShadowRoot, which works only in the extension’s privileged context, not in an injected page-world script.

Lazy loading. Many long pages — news feeds, product listings, documentation — only load content as the user scrolls. A content script that reads the page at first load misses everything below the fold that hasn’t been fetched yet. Waiting briefly for lazy loaders to settle, or triggering a read after a scroll event, gets around this for most sites.

Cross-origin iframes. Content inside a cross-origin <iframe> is a separate document that the parent frame cannot access, by browser security policy. An extension can inject itself into each frame independently using "all_frames": true in the manifest, but frames from another origin are inaccessible regardless.

Content that appears only after interaction. Modals, accordions, tooltip popups, and dropdown menus often hold content that is only in the DOM when a specific element has been clicked. An AI reading the page before the user has opened a specific section will not see that content.

What this means in practice when you use Browsy

When you ask Browsy to summarize, explain, or help with a page, it reads the current state of the DOM — the live rendered version of whatever you’re looking at. In practice that means:

  • It works on React, Vue, Angular, Svelte, and other framework-built sites automatically, because they all produce a real DOM that a content script can read.
  • It captures the text currently visible on screen, not the server-sent HTML.
  • It may see less than you expect on pages that load more content only after scrolling or clicking.
  • It cannot reach inside cross-origin iframes, which covers most embedded third-party widgets.

For the vast majority of pages — articles, documentation, e-commerce listings, search results, social feeds — the DOM you’re already seeing is exactly what Browsy reads and sends to the AI.


The browser’s job is to turn HTML, CSS, and JavaScript into a visual document. Content scripts live inside that finished result. That positioning — inside the browser, after rendering — is what makes them fundamentally more capable than external tools trying to read a page from the outside.

Ready to try it?

Browsy is free — no account required

Add to Chrome — Free