Puppeteer Frame.addScriptTag Options Explained
Learn all five Frame.addScriptTag options, how to target a specific frame, and how to choose between inline, local, and external scripts.
frame.addScriptTag(options) inserts a script element into a Puppeteer frame and resolves to a handle for that HTMLScriptElement. The five documented optional properties are content, id, path, type, and url. Use content for JavaScript held in a string, path for a local JavaScript file, and url for an external script. A relative Node.js path resolves from process.cwd().
See the Puppeteer Frame.addScriptTag API reference and options interface.
What Frame.addScriptTag does
A Puppeteer Frame represents a browser DOM frame, such as the main document or an iframe. Calling frame.addScriptTag(options) adds a script to that particular frame. The call resolves to an ElementHandle<HTMLScriptElement>, which you can retain if you need to inspect or otherwise work with the inserted element.
The corresponding page-level method, page.addScriptTag(options), is a shortcut for page.mainFrame().addScriptTag(options). Choose the frame method when the target is a particular iframe. Code running in one frame does not automatically affect its nested frames.
The five options
| Option | Purpose | Use it when |
|---|---|---|
content |
JavaScript source to inject into the frame. | Your script source is already available as a string. |
id |
Sets the inserted script element’s id attribute. |
You want to identify the element in the frame’s DOM. |
path |
Specifies a JavaScript file path. | The source is in a local file available to the Node.js process. |
type |
Sets the script element’s type. |
For an ES2015 module, set it to 'module'. |
url |
Specifies the URL of the script to add. | The source is served from an external URL. |
All five properties are optional. The API reference does not establish a precedence rule or mutual-exclusion behavior for supplying multiple source properties together. Keep each call clear by choosing the source form you intend to use and adding id or type when needed.
Runnable Node.js examples
Install Puppeteer in your project with npm install puppeteer. The following examples assume a local Puppeteer installation and an accessible target page. Each example demonstrates a distinct source option.
Inject a string with content
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
const scriptHandle = await page.mainFrame().addScriptTag({
content: 'window.exampleFlag = true;',
id: 'example-inline-script',
});
console.log(await page.evaluate(() => window.exampleFlag));
console.log(await scriptHandle.evaluate((script) => script.id));
} finally {
await browser.close();
}
})();
content is the JavaScript source string. The returned handle refers to the generated script element.
Load a local file with path
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.mainFrame().addScriptTag({
path: './scripts/helper.js',
id: 'helper-script',
});
} finally {
await browser.close();
}
})();
In Node.js, a relative path is resolved from the process working directory, process.cwd(). That directory may differ from the directory containing this source file. Use an absolute path if your launch context varies.
Load an external script with url
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.mainFrame().addScriptTag({
url: 'https://example.com/library.js',
id: 'external-library',
});
} finally {
await browser.close();
}
})();
The URL identifies the script resource. The page’s browser context must be able to reach that URL for it to load.
Set the script type to module
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.mainFrame().addScriptTag({
path: './scripts/module.js',
type: 'module',
id: 'example-module',
});
} finally {
await browser.close();
}
})();
The documented module indication is type: 'module'. This example uses it with a local file; the type property sets the script element’s type.
Targeting a particular frame
Use page.mainFrame() when the script belongs in the top-level page. For a child frame, locate the intended frame and call the method on it. Frame selection is separate from script source selection.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com/page-with-iframe');
const targetFrame = page.frames().find((frame) =>
frame.url().includes('/embedded-content')
);
if (!targetFrame) {
throw new Error('The expected iframe was not found');
}
await targetFrame.addScriptTag({
content: 'window.frameFlag = true;',
id: 'frame-script',
});
} finally {
await browser.close();
}
})();
Choose a frame using a condition that distinguishes it in your page. A frame can navigate or disappear while automation is running, so locate it after navigation and handle the case where it is absent.
Choosing a source option
| Source | Good fit | Detail to check |
|---|---|---|
content |
Short generated code or a source string built by your program. | Pass JavaScript text as a string. |
path |
A script checked into the project or generated as a file. | Relative paths use process.cwd(). |
url |
A script hosted at a URL accessible from the browser. | Use a reachable URL and account for the page’s network environment. |
Add id when you need a stable DOM identifier. Add type: 'module' for an ES2015 module. The options reference does not specify what happens if several source properties are combined, so do not rely on an undocumented precedence rule.
Errors and troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| The script file cannot be found. | A relative path was resolved from a different working directory than expected. |
Print process.cwd(), verify the file exists relative to it, or pass an absolute path. |
| The script does not appear in the expected document. | The method was called on the main frame or a different iframe. | Inspect the selected frame’s URL and call addScriptTag on the intended frame. |
| An external script does not load. | The browser cannot retrieve the provided URL, or the URL is wrong. | Check the URL and whether it is accessible from the browser environment. The API reference does not specify detailed failure behavior for unreachable URLs. |
| Module behavior is not as expected. | The inserted script element was not given the module type. | For an ES2015 module, set type: 'module'. |
| Automation cannot find the target iframe. | The frame has not appeared yet, has navigated, or does not match the selection condition. | Wait for the page state that creates the frame, then inspect page.frames() and its URLs before selecting it. |
These checks follow the documented option and frame behavior; they are diagnostic guidance, not claims about undocumented error messages or option combinations.
Performance, reliability, and cost
addScriptTag itself does not define a browser launch strategy or a cost model. In an automation workflow, keep the browser lifecycle intentional: reuse a browser for related work where appropriate, close it in a finally block, and avoid repeatedly injecting the same script when one injection per frame is enough. External script loading depends on network access, while local files depend on the process filesystem and working directory.
For repeatable runs, make frame selection explicit, use stable script paths or URLs, and surface missing-frame conditions instead of silently skipping them. The cited API documentation provides no benchmark, reliability guarantee, or Puppeteer usage price to report.
Or skip the browser setup
If your goal is a screenshot rather than browser-side scripting, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. Its capture flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, with the page verdict and billing status in response headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request details. Free includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card.
FAQ
Does addScriptTag return the script element?
It resolves to an ElementHandle<HTMLScriptElement> for the inserted script.
Does Page.addScriptTag target every frame?
No. It is the shortcut for adding the script to the page’s main frame. Call addScriptTag on a specific Frame to target that frame.
What is the base directory for a relative path?
In Node.js, relative paths resolve from process.cwd().
Can I combine content and url?
The cited options reference does not document source-option precedence or combination behavior. Use one source option per call unless you have verified the behavior against the Puppeteer version you use.


