Getting Started
This page covers how to connect to a Chrome browser instance and configure the Webview client.
See also: Home | DOM-Queries | Actions | Console-Monitoring | Angular-Testing
Prerequisites
You need a running Chrome or Chromium instance with remote debugging enabled. Launch it from the command line:
# Headless (no visible window)
google-chrome --remote-debugging-port=9222 --headless
# With visible window (useful during development)
google-chrome --remote-debugging-port=9222
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# Chromium
chromium --remote-debugging-port=9222
The --remote-debugging-port flag starts an HTTP server on the specified port that exposes the DevTools Protocol. The library connects to this endpoint, discovers available page targets, and opens a WebSocket connection to the first available page.
Installation
go get forge.lthn.ai/core/go-webview
Creating a Webview
The New constructor accepts functional options and returns a configured *Webview:
wv, err := webview.New(
webview.WithDebugURL("http://localhost:9222"),
)
if err != nil {
log.Fatal(err)
}
defer wv.Close()
WithDebugURL is required. It connects to the Chrome DevTools HTTP endpoint, queries /json for available page targets, and establishes a WebSocket connection to the first page target found. If no page target exists, it creates one via /json/new.
Configuration Options
WithDebugURL
Sets the Chrome DevTools HTTP endpoint. This is the only required option.
webview.WithDebugURL("http://localhost:9222")
WithTimeout
Sets the default timeout for all operations. Defaults to 30 seconds.
webview.WithTimeout(10 * time.Second)
Every method on Webview creates a child context from the instance context with this timeout. If an operation (navigation, DOM query, screenshot, etc.) exceeds the timeout, it returns a context deadline error.
WithConsoleLimit
Sets the maximum number of console messages retained in the built-in buffer. Defaults to 1000. When the limit is reached, the oldest messages are pruned.
webview.WithConsoleLimit(5000)
Connection Lifecycle
When New is called:
WithDebugURLsendsGET /jsonto discover page targets- The first target of type
"page"with a WebSocket URL is selected - If no page targets are found,
GET /json/newcreates a fresh tab - A WebSocket connection is established using
gorilla/websocket - A background goroutine (
readLoop) begins reading CDP messages - The
Runtime,Page, andDOMdomains are enabled - A console event handler is registered on
Runtime.consoleAPICalled
When Close is called:
- The instance context is cancelled
- The read loop exits
- The WebSocket connection is closed
Low-Level CDPClient
The CDPClient is the WebSocket transport layer. You normally do not use it directly, but it is available for advanced use cases.
// Create a standalone CDP client
client, err := webview.NewCDPClient("http://localhost:9222")
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Send a CDP command
ctx := context.Background()
result, err := client.Call(ctx, "Page.navigate", map[string]any{
"url": "https://example.com",
})
// Subscribe to events
client.OnEvent("Page.loadEventFired", func(params map[string]any) {
log.Println("Page loaded")
})
// Fire-and-forget message (no response)
client.Send("Runtime.enable", nil)
CDPClient Utilities
// List all targets (pages, workers, service workers, etc.)
targets, err := webview.ListTargets("http://localhost:9222")
// Get Chrome version information
version, err := webview.GetVersion("http://localhost:9222")
// Create a new tab
newClient, err := client.NewTab("https://example.com")
defer newClient.Close()
// Close the current tab
err = client.CloseTab()
Error Handling
All methods return errors with context. A typical pattern:
wv, err := webview.New(webview.WithDebugURL("http://localhost:9222"))
if err != nil {
// Connection failed -- Chrome may not be running
log.Fatalf("failed to connect: %v", err)
}
defer wv.Close()
if err := wv.Navigate("https://example.com"); err != nil {
// Navigation failed or timed out
log.Printf("navigation error: %v", err)
}
Errors are wrapped with fmt.Errorf and preserve the underlying cause, so you can use errors.Is and errors.As for inspection.
Next Steps
- DOM-Queries -- Find and inspect elements on the page
- Actions -- Interact with elements (click, type, drag, etc.)
- Console-Monitoring -- Monitor browser console output
- Angular-Testing -- Automate Angular applications