How to Screenshot a Webpage with Playwright in Go
Install Playwright for Go, capture a viewport or full page, save the image, and fix common browser setup and loading issues.
Use the Go package github.com/mxschmitt/playwright-go to launch a browser, open a page, navigate to a URL, and call Screenshot with a file path. Install the Playwright driver and browser binaries as well as the Go dependency, and match the driver version to the package version in your go.mod. The complete example below captures the visible viewport and closes both browser and Playwright runtime.
1. Install Playwright for Go
From your Go module directory, add the dependency:
go get github.com/mxschmitt/playwright-go
Then install the Playwright driver and Chromium. Replace VERSION with the exact playwright-go version recorded in your go.mod; the project requires a corresponding driver version for each minor package version.
go run github.com/mxschmitt/playwright-go/cmd/playwright@VERSION install chromium
On Linux, if the machine is missing browser system libraries, install the required operating system dependencies too. The project documents an install command with --with-deps; it may need elevated system privileges. See the playwright-go installation and driver-version notes.
2. Capture a webpage to a PNG file
Create main.go. This version accepts the destination URL as a command-line argument, checks failures, and ensures cleanup runs even if navigation or screenshot creation fails.
package main
import (
"flag"
"fmt"
"log"
"github.com/mxschmitt/playwright-go"
)
func main() {
url := flag.String("url", "https://example.com", "webpage URL to capture")
out := flag.String("out", "screenshot.png", "output image path")
flag.Parse()
pw, err := playwright.Run()
if err != nil {
log.Fatalf("start Playwright: %v", err)
}
browser, err := pw.Chromium.Launch()
if err != nil {
_ = pw.Stop()
log.Fatalf("launch Chromium: %v", err)
}
defer func() {
if err := browser.Close(); err != nil {
log.Printf("close browser: %v", err)
}
if err := pw.Stop(); err != nil {
log.Printf("stop Playwright: %v", err)
}
}()
page, err := browser.NewPage()
if err != nil {
log.Fatalf("create page: %v", err)
}
if _, err := page.Goto(*url); err != nil {
log.Fatalf("navigate to %s: %v", *url, err)
}
if _, err := page.Screenshot(playwright.PageScreenshotOptions{
Path: playwright.String(*out),
}); err != nil {
log.Fatalf("save screenshot to %s: %v", *out, err)
}
fmt.Printf("Saved %s\n", *out)
}
Run it with the default URL or supply your own:
go run .
go run . -url https://stripe.com -out stripe.png
The Go example follows the maintained playwright-go screenshot example lifecycle: start Playwright, launch Chromium, create a page, navigate, save the screenshot, and close the browser and runtime.
3. Pick the capture scope and output
Viewport or full page
With FullPage unset, the image shows the current viewport. Set it to true to include the page’s full scrollable height, including content below the fold.
_, err := page.Screenshot(playwright.PageScreenshotOptions{
Path: playwright.String("full-page.png"),
FullPage: playwright.Bool(true),
})
A full-page image can be very tall on long pages. Use viewport capture when the goal is a consistent browser-sized image or visual regression sample. Use full-page capture when the reader needs the entire document in one file. The distinction matches the Playwright screenshot guide.
Capture one element
For a chart, card, or other component, use a locator screenshot instead of capturing the entire page. The Playwright guide documents locator-level capture; check the API signature provided by the exact playwright-go version in your module because Go method signatures can differ by release.
// Illustrative API shape; confirm the locator screenshot signature for your installed version.
locator := page.Locator("main article")
_, err := locator.Screenshot(playwright.LocatorScreenshotOptions{
Path: playwright.String("article.png"),
})
If that method or option type is unavailable in your installed release, consult its Go API reference. A locator screenshot is useful when the exact component matters and the rest of the page should be excluded.
Choose format and image size
The path extension normally determines whether the output is PNG or JPEG when the API supports that format. Screenshot options also cover format-specific quality, clipping to a rectangle, scale, animation handling, caret display, masks, and background behavior. The available Go option names and types depend on the installed package version; check the Page screenshot API alongside the Go API reference before adding version-specific fields.
- PNG: a lossless choice for interface snapshots and text-heavy pages.
- JPEG: useful when smaller lossy images are acceptable; quality is relevant to JPEG output.
- CSS-pixel scale: generally produces an image aligned to the page’s CSS dimensions.
- Device-pixel scale: can create a larger, sharper image and increase file size and memory use.
- Clip: limits the capture to a rectangle when a full locator capture is not suitable.
For bytes rather than a file, omit the path and use the screenshot method’s returned byte slice, according to the installed Go API. That is useful when uploading directly to object storage or passing the image to an image-processing function. Verify the concrete return type against your package version.
4. Make page readiness explicit
A successful navigation does not always mean a modern page has finished rendering its useful content. Some pages load data after the initial document, defer images until scrolling, or keep network connections open. The maintained example uses DOMContentLoaded as a navigation readiness point. For a dynamic site, wait for the specific content that must appear before taking the image rather than adding an arbitrary long sleep.
The exact Goto option structure is version-specific in playwright-go. Check the installed Go API for its navigation options, then choose a load state suited to the page. Where possible, wait for a stable selector that identifies the content you need. If images are lazy-loaded below the fold, a full-page screenshot alone may not trigger every site’s image loading; scroll through the page or otherwise cause the site to load those assets before capture when complete imagery is required.
For repeatable captures, control the conditions that affect rendering: viewport size, device scale, color scheme, locale, timezone, authentication state, and any relevant page data. Playwright supports browser contexts and emulation; the Go package exposes these browser automation capabilities. Keep each capture isolated when cookies or local storage from one page could affect another.
5. ScreenshotNeo one-call option
If the task is simply to get an image from a URL, ScreenshotNeo is a website screenshot API: one GET request returns an image or PDF without requiring you to install and operate browser binaries. Its options include full-page capture, element capture, device presets, custom viewport, wait conditions, and output formats. See the ScreenshotNeo API documentation for the request parameters.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
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 Bun.write('shot.webp', res);
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; 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 provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per 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 required.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Playwright cannot start or the driver is missing | The driver was not installed, or it does not match the library version. | Install the driver using the version in go.mod. Recheck the playwright-go README’s minor-version matching guidance. |
| Browser executable not found | The Go package is installed but Chromium was not downloaded. | Run the Playwright install command for Chromium using the matching driver version. |
| Browser fails to launch on Linux | Required operating system libraries may be absent. | Install browser dependencies for the host image. In CI or containers, use an environment that includes the required libraries. |
| Navigation times out or returns an error | The site is slow, unreachable, redirecting, or waiting for a load condition that never occurs. | Check the target URL and network access. Select an appropriate readiness condition and wait for the particular content you need. |
| Screenshot is blank or missing content | The capture happened before client-rendered content appeared, or the page showed an error or bot check. | Wait for a content-specific selector and inspect the loaded page. Confirm the site can be reached from the machine running Chromium. |
| Images below the fold are absent | The site lazy-loads images only when they approach the viewport. | Scroll through the page before capturing and allow the images to load; then take the full-page screenshot. |
| Output file cannot be written | The destination directory does not exist or the process lacks write access. | Create the directory first or choose a writable path. Check the screenshot error rather than assuming a file was created. |
| Image is too large | Full-page dimensions, device-pixel scaling, or a lossless format may create a large file. | Capture only the needed scope, use CSS-pixel scale where appropriate, or choose a supported lossy format and quality. |
| Browser processes accumulate | Early returns bypassed browser or runtime cleanup. | Close the browser and call pw.Stop() on every path. Use deferred cleanup after successful initialization. |
7. Performance, reliability, and cost
Playwright Go runs a browser process and its driver, so it needs more setup and runtime resources than a single HTTP request to a screenshot service. The advantage is direct control over browser behavior, page state, authentication, and custom interactions. Reuse a browser for multiple pages when appropriate, but keep contexts isolated when captures must not share cookies or storage. Close pages, contexts, browsers, and the Playwright runtime according to the lifecycle in your application.
Capture time depends on the site, its assets, the chosen readiness condition, and whether you request a tall full-page image. Avoid fixed waits longer than necessary; waiting for a meaningful selector improves both responsiveness and consistency. Bound navigation and job durations in production, limit concurrent browser instances to the resources available, and record errors so failed captures are distinguishable from valid image output.
The Playwright library and browser installation are the main operational cost of the self-hosted approach: your service must provide the runtime, browser binaries, dependencies, compute, and storage. ScreenshotNeo is a paid API after its free allowance: 1,000 screenshots a month are free with no card, then the listed plans start at $5 for 3,000. It bills only clean shots and reports verdict and billing headers. Choose based on whether you need browser-level control or prefer a managed URL-to-image request.
8. FAQ
How do I take a full page screenshot in Playwright Go?
Set FullPage: playwright.Bool(true) in playwright.PageScreenshotOptions when calling page.Screenshot.
How do I save the screenshot to a specific directory?
Set Path to the desired file path, and ensure the parent directory exists and is writable before capture.
Can I screenshot a page that requires login?
Yes. Use a browser context with the required authentication state or complete the login flow before capturing. Avoid sharing authenticated storage between unrelated jobs.
Which browser does the basic example use?
It launches Chromium. The Go library also supports Firefox and WebKit; install the corresponding browser and launch the matching browser type when you need them.
Can Playwright produce a PDF instead?
Playwright supports page-to-PDF workflows in supported browser contexts. For URL-to-PDF through ScreenshotNeo, use its capture_pdf MCP tool or the documented API options.


