Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/l-xiaoshen/handstage/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through your first Handstage script. By the end you’ll have a working program that launches Chrome, opens a page, interacts with an element, captures a screenshot, and shuts down cleanly.
Handstage requires Chrome or Chromium to be installed on your system. On most macOS, Linux, and Windows machines, V3.connectLocal() finds Chrome automatically. See connecting to Chrome if you need to specify a custom path or port.
1

Install the package

Add @handstage/core to your project using your preferred package manager:
npm install @handstage/core
2

Launch Chrome

Call V3.connectLocal() to start a Chrome process and connect to it over CDP. You get back a V3 instance that represents the running browser.
import { V3 } from "@handstage/core"

const browser = await V3.connectLocal()
If Chrome is already running with remote debugging enabled, V3.connectLocal() can attach to it instead of launching a new process. See connecting to Chrome for details.
3

Open a page

Access the default browser context with browser.context, then call newPage() with the URL you want to open. This creates a new tab and waits for the page to load.
const page = await browser.context.newPage("https://example.com")
You can open multiple pages from the same context. For fully isolated sessions — separate cookies and storage — create an isolated context with browser.create() first.
4

Interact with an element

Use page.locator(selector) to target an element by CSS selector or XPath, then call an action on the returned Locator.
// Fill a text input
await page.locator("input[name='q']").fill("handstage browser automation")

// Click a button
await page.locator("button[type='submit']").click()
Other available locator actions include .type(text) for character-by-character input and .hover() to trigger hover states.
5

Take a screenshot

Call page.screenshot() to capture the current viewport as a PNG buffer.
import fs from "fs"

const buffer = await page.screenshot()
fs.writeFileSync("screenshot.png", buffer)
6

Close the browser

Call browser.close() when you’re done. This terminates the Chrome process and cleans up any temporary profile data.
await browser.close()

Complete example

Here’s the full script putting all the steps together:
import fs from "fs"
import { V3 } from "@handstage/core"

const browser = await V3.connectLocal()

try {
  const page = await browser.context.newPage("https://example.com")

  await page.locator("input[name='q']").fill("handstage browser automation")
  await page.locator("button[type='submit']").click()

  const buffer = await page.screenshot()
  fs.writeFileSync("screenshot.png", buffer)

  console.log("Screenshot saved to screenshot.png")
} finally {
  await browser.close()
}
This example uses top-level await, which requires "type": "module" in your package.json and "module": "ESNext" (or "NodeNext") in your tsconfig.json. See installation for the full TypeScript configuration.

Next steps

Installation

Full setup instructions including TypeScript configuration and environment variables.

Core concepts

Learn how browsers, contexts, pages, and locators relate to each other.

API reference

Complete API reference for the V3 class.

AI agent integration

Give an LLM browser control using @handstage/agent.

Build docs developers (and LLMs) love