How to Use Puppeteer’s Known Devices for Emulation
Import Puppeteer’s KnownDevices, apply a named device profile before navigation, and learn what its viewport and user-agent emulation does—and does not—configure.
KnownDevices is Puppeteer’s collection of named device profiles. Import it from puppeteer, select a profile by its documented key, and pass it to page.emulate() before navigating. The profile sets a user agent and viewport; it does not promise to reproduce every behavior of a physical phone or tablet.
Use a named device profile
import puppeteer, {KnownDevices} from 'puppeteer';
const device = KnownDevices['iPhone 17 Pro'];
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.emulate(device);
await page.goto('https://example.com', {waitUntil: 'networkidle2'});
console.log('Viewport:', await page.evaluate(() => ({
width: window.innerWidth,
height: window.innerHeight,
devicePixelRatio: window.devicePixelRatio,
userAgent: navigator.userAgent,
})));
} finally {
await browser.close();
}
Install Puppeteer in your project with npm install puppeteer. The package downloads a compatible browser by default. The example uses ES modules; save it as .mjs or use a project configured with "type": "module". Puppeteer documents KnownDevices as named Device profiles and demonstrates selecting one by key. See the KnownDevices API reference, Page.emulate() reference, and Device interface.
What each line is doing
KnownDevices['iPhone 17 Pro']looks up the profile by its exact string key.page.emulate(device)applies its viewport and user agent to the page.page.goto()runs afterward so the site loads with the emulated settings in place.- The evaluation reads the resulting browser-side values, which can help confirm that the intended profile took effect.
Page.emulate() is documented as a shortcut for Page.setUserAgent() and Page.setViewport(). Puppeteer also notes that the method resizes the page and recommends emulating before navigation, because many sites do not expect phones to change size after loading.
Choose and verify a profile
Use the profile name exactly as it appears in the API reference. Examples in the documentation include iPhone 17 Pro, iPhone 17 Pro landscape, iPad, iPad landscape, Galaxy S9+, and Pixel 5. Names and available profiles can vary by Puppeteer release, so consult the reference and installed package types for the version your project uses.
import puppeteer, {KnownDevices} from 'puppeteer';
const profileName = 'iPad landscape';
const device = KnownDevices[profileName];
if (!device) {
throw new Error(`Unknown Puppeteer device profile: ${profileName}`);
}
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.emulate(device);
await page.goto('https://example.com');
// Run responsive checks here.
} finally {
await browser.close();
}
Looking up a missing key yields no usable profile. Checking it before launching the browser gives a clearer failure than passing an invalid value into the emulation call.
Portrait and landscape
Many devices have separate portrait and landscape profile keys. Choose the orientation needed for the check rather than assuming that rotating a physical device is simulated. To compare layouts, run the same page once per profile:
import puppeteer, {KnownDevices} from 'puppeteer';
const profiles = ['iPhone 17 Pro', 'iPhone 17 Pro landscape'];
const browser = await puppeteer.launch();
try {
for (const name of profiles) {
const device = KnownDevices[name];
if (!device) throw new Error(`Unknown profile: ${name}`);
const page = await browser.newPage();
await page.emulate(device);
await page.goto('https://example.com', {waitUntil: 'domcontentloaded'});
console.log(name, await page.evaluate(() => ({
width: innerWidth,
height: innerHeight,
userAgent: navigator.userAgent,
})));
await page.close();
}
} finally {
await browser.close();
}
For repeatable checks, record the Puppeteer version, exact profile key, target URL, and relevant observed values with the result. That makes it easier to distinguish a layout change from a profile or dependency change.
What KnownDevices emulates
A Device profile contains userAgent and viewport properties. Puppeteer’s page.emulate() applies those through the page’s user-agent and viewport methods. This is browser-side device-profile emulation. The API reference does not claim full hardware, operating-system, or physical-device simulation.
| Profile setting | What it affects | What not to assume |
|---|---|---|
| User agent | The user-agent string exposed by the browser page and sent in browser requests. | It does not turn the host machine into that device or guarantee device-specific server behavior. |
| Viewport | The page’s emulated dimensions; Puppeteer notes that emulation resizes the page. | It does not guarantee identical rendering, hardware characteristics, or operating-system behavior. |
Use these profiles for responsive layout checks and browser automation where the configured user agent and viewport are the relevant inputs. If a result depends on actual hardware, an operating-system feature, or a browser not represented by the profile, validate it separately in that environment. That is a practical testing recommendation, not a guarantee made by Puppeteer.
Options and configuration choices
- Profile key: use an exact available key from the version installed in the project.
- Orientation: select a portrait or landscape key when both are present.
- Navigation timing: use the
waitUntiloption appropriate to the page.domcontentloadedwaits for initial document parsing;networkidle2can be useful for pages that settle, but pages with ongoing requests may not reach network idle. - Checks: inspect layout, take a screenshot, or evaluate page values after navigation. The emulation call itself does not define what your test should assert.
- Version: keep the Puppeteer package version controlled by your lockfile, and check that version’s profile keys and types when upgrading.
If you need custom dimensions or user-agent settings instead of a bundled profile, Puppeteer exposes the underlying page.setViewport() and page.setUserAgent() methods. The device profile is convenient when its documented values fit the test; manually configured values make the chosen settings explicit in your own code.
Or skip the browser setup
If your goal is to capture a page rather than run browser automation, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns an image or PDF, and its device options include presets and custom viewports. Read the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(({writeFile}) =>
writeFile('shot.webp', Buffer.from(await res.arrayBuffer()))
);
Cookie and consent banners are accepted like a visitor and removed before the shot, along with known newsletter popups and chat widgets; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month, with no card required.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
KnownDevices is not exported or import fails. |
The project’s installed Puppeteer version or import style differs from the example. | Check the installed package version and its documentation. Use the documented named import with an ES module, or adapt the import to the project’s module configuration. |
The selected profile is undefined. |
The key is misspelled, differs in capitalization, or is absent in this installed release. | Copy the exact profile name from the API reference for the relevant version and guard the lookup before launching. |
| The page initially looks desktop-sized, then changes. | Emulation was applied after navigation. | Call and await page.emulate(device) before page.goto(). |
| The site still behaves differently from a real phone. | The profile configures a user agent and viewport, not complete physical hardware or OS behavior. | Use profile emulation for checks it covers; reproduce hardware- or OS-dependent cases on the actual environment. |
| Navigation hangs waiting for network idle. | The site may keep requests open or continually poll. | Choose a less restrictive waitUntil condition such as domcontentloaded, then wait for a specific selector or application-ready condition. |
| Browser launch fails in a container or CI worker. | The environment may lack the libraries or permissions required by the bundled browser. | Review Puppeteer’s installation and troubleshooting guidance for that environment, install required system dependencies, and use the launch configuration supported by the runner. |
Performance, reliability, and cost
- Reuse the browser: for multiple profiles or URLs in one job, launch one browser and create/close pages per case. Always close the browser in a
finallyblock so failures do not leave processes running. - Choose waits deliberately: waiting for every network request to settle can be slow or never complete on active sites. Wait for the page state your check actually needs.
- Control test inputs: keep the Puppeteer version, profile key, URL, and navigation condition fixed when comparing captures.
- Cost: Puppeteer is an open-source browser automation library; this workflow has no per-capture ScreenshotNeo charge. Account for the compute and browser runtime in the environment where it runs. For hosted one-call captures instead, ScreenshotNeo’s pricing is 1,000 free monthly shots, then plans from $5 for 3,000; yearly billing gives two months free.
- Reliability boundary: a successful emulation call confirms that Puppeteer applied the profile settings, not that the target site rendered correctly or that a physical device would match. Assert the page state your workflow requires.
FAQ
Can I use any device name from an older Puppeteer example?
Only if that key exists in the Puppeteer release installed by your project. Check the current reference and package types rather than relying on a list copied from another version.
Does page.emulate() set the profile before every new navigation?
It applies settings to the page. Apply it to each page you intend to use, before that page’s navigation.
Does this prove my site works on an iPhone or iPad?
No. It checks behavior under a documented user-agent and viewport profile. Physical-device and OS-dependent behavior needs validation in the relevant environment.


