ScreenshotNeo

BlogHow-to

How to Get a Page Title in Puppeteer

Use Puppeteer’s `page.title()` to get a page title as a string. See runnable examples, alternatives, common errors, and a no-browser API option.

By the ScreenshotNeo team4 October 20265 min read

After navigating to the page, call await page.title(). It returns the document title as a string.

const title = await page.title();
console.log(title);

page.title() is Puppeteer’s dedicated method for this task. Its API signature is title(): Promise<string>, and it is a shortcut for page.mainFrame().title(). Puppeteer Page.title() API reference.

1. Complete runnable example

Install Puppeteer in a Node.js project, then save this as title.mjs and run it with node title.mjs. The first run may download the browser used by Puppeteer.

npm install puppeteer
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');

  const title = await page.title();
  console.log(title);
} finally {
  await browser.close();
}

The navigation happens before the title read, so the method reads the destination page rather than the initial blank page. Puppeteer’s getting-started guide documents the launch, page creation, and navigation pattern; it also describes importing puppeteer-core when using that package. Puppeteer getting started.

2. Read the title from an existing page

If another part of your script already created and navigated page, you only need:

const title = await page.title();

Because the method returns a Promise, await it inside an async function or use top-level await in an ES module. Without await, the variable holds a Promise rather than the title string.

3. Alternatives and when to use them

Evaluate document.title

Use page evaluation if title reading is part of a larger calculation that needs to run in the page context:

const title = await page.evaluate(() => document.title);

page.evaluate() runs the function in the page context and returns its result. It also awaits a Promise returned by that function. For the title alone, page.title() states the intent more directly. Puppeteer Page.evaluate() API reference.

Select the <title> element

If you specifically need to select the title element, use $eval():

const titleText = await page.$eval('title', element => element.textContent);

$eval() selects the first matching element and passes it to the callback. It throws if the selector has no match, so handle that failure if using this method on pages that may not contain a title element. For the document title as a string, prefer page.title(). Puppeteer Page.$eval() API reference.

Method Use it when Behavior to know
page.title() You want the document title. Returns a Promise that resolves to a string.
page.evaluate(() => document.title) Title retrieval belongs in a broader page-context computation. Runs the function in the page context.
page.$eval('title', ...) You need selector-based access to the title element. Throws when the selector has no match.

4. Navigation and timing considerations

Call the title method after navigating to the intended URL. Puppeteer’s navigation call can be awaited before reading the title:

await page.goto('https://example.com');
const title = await page.title();

If you are reading a title that a site changes after its initial response, the value depends on when you read it. Wait for the page condition your task requires, then call page.title(). For example, when you know the page updates the title after a particular element appears:

await page.goto('https://example.com');
await page.waitForSelector('#app-ready');
const title = await page.title();

Choose a condition tied to the page’s behavior rather than adding an arbitrary delay. A delay can waste time on fast pages and still be too short on slow ones.

5. Troubleshooting

Symptom Likely cause Fix
You see a Promise instead of a title. The asynchronous method was not awaited. Use const title = await page.title() inside an async function or an ES module.
The result is empty or not the expected page’s title. The title was read before navigating, or before the site updated it. Await navigation first; if the site updates later, wait for a relevant page condition before reading.
$eval('title', ...) throws. No matching title element was found by that selector. Use page.title() for document-title retrieval, or handle the missing-selector case when selector access is required.
The script exits with the browser still running after an error. Browser cleanup was skipped on the error path. Put work inside try and call browser.close() in finally.

6. Performance, reliability, and cost

Reading the title is a small browser operation. In an automated workflow, navigation and page behavior are usually the parts that determine how long the whole job takes. Reuse an existing page when it fits your workflow, and close the browser in a cleanup path so failures do not leave browser processes running.

Puppeteer runs a browser, so your environment needs the appropriate browser installation and resources. Puppeteer’s standard package and puppeteer-core have different setup roles; consult the official getting-started guide for package details. This method has no per-title API charge, though the browser and the infrastructure running it have their own resource costs.

7. Or skip the browser setup

If you need a page screenshot as well as its visible content, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request captures a URL as an image or PDF; its API is documented at ScreenshotNeo docs.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.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(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. ScreenshotNeo is at screenshotneo.com. Sign up for 1,000 free screenshots a month with no card.

8. FAQ

Does page.title() return a string?

Yes. Its Promise resolves to a string.

Is page.title() the same as page.mainFrame().title()?

The Puppeteer API describes page.title() as a shortcut for page.mainFrame().title().

Can I get a title without using page.title()?

Yes. Evaluate document.title in the page context. Use $eval() when selecting the title element itself is part of your task.