Browser panes
Open websites beside a terminal, navigate with native controls, and keep links inside the project.
Zshell can put a built-in browser in any tab or split pane. It is useful for a local dev server, API documentation, an issue, or anything else you want beside the terminal that is using it.
Opening a browser
- Choose File → New Browser Tab for a blank tab.
- Open the command palette (Cmd+P) and run New Browser Tab or New Browser Pane.
- Command-right-click a detected URL in a terminal and choose New Browser Tab or New Browser Pane to open it without copying the address.
Browser tabs belong to the selected project and participate in its normal tab and pane layout. If no project is open, Zshell creates one to hold the browser.
Address and search
The field at the top accepts a full URL, a hostname, or search terms:
zshell.shbecomes an HTTPS address.localhost, local hostnames, IP addresses, and explicit ports use HTTP.- Everything else becomes a Google search.
Use Cmd+L to focus the field and Cmd+R to reload. The toolbar also has Back, Forward, Stop/Reload, Share, and Open in Default Browser controls. Trackpad back and forward gestures work too.
| Action | Shortcut |
|---|---|
| Focus address bar | Cmd+L |
| Reload page | Cmd+R |
Opening links where you want them
Right-click a link on a page for Open Link in New Tab or Open Link in New Pane. The new page stays in the same project workspace.
In a terminal, a plain Command-click opens a detected web URL in your default browser. Command-right-click is the version that offers a Zshell tab or pane. Local paths have a parallel workflow described under Paths and URLs.
What is preserved
Switching tabs or projects keeps the page as you left it, including history, scroll position, forms, and in-page state. When Zshell relaunches, it restores the current URL and layout, but not the full back/forward history.
Browser panes keep cookies, logins, and other site data across tabs and launches. This is not a private-browsing mode.
Let an agent test the page
Ask your coding agent to inspect the page already open in this project, fill a form, check a result, or capture its viewport. The agent uses the existing browser session and keeps focus in your terminal. It can also open a background browser pane for a local development URL.
For scripts, run these commands inside a Zshell terminal. Record the returned browser_id and replace BROWSER_ID below:
zshell +browser list
zshell +browser open http://localhost:3000 --wait
zshell +browser snapshot --browser BROWSER_ID
zshell +browser fill --browser BROWSER_ID --selector '#search' --text 'terminal'
zshell +browser click --browser BROWSER_ID --selector 'button[type="submit"]'
zshell +browser wait --browser BROWSER_ID --selector '#results' --timeout 10000
zshell +browser screenshot --browser BROWSER_ID --output /tmp/zshell-page.pngSnapshots return main-frame text, accessible labels, and element references. References expire after page changes or actions; take a new snapshot before reusing one. CSS selectors must match exactly one element. Use navigate, back, forward, reload, and stop for navigation.
Automation accepts explicit HTTP/HTTPS URLs and about:blank. Other protocols, downloads, file pickers, and native dialogs require your interaction. A page remains under this protocol restriction until you navigate manually with the address bar or toolbar. Commands stay inside the calling terminal’s project and window. --timeout is 100–30000 milliseconds. Snapshots are limited to 200 elements, 32768 text characters, and 256 KiB; password and file-input values are omitted. PNG viewport captures are limited to 512 KiB, work even before a pane has been shown, using a 1024 × 768 viewport without changing focus, and never overwrite files. Reduce --width for a smaller capture. See zshell +browser --help for complete syntax.
Page scripts and saved logins
zshell +browser eval --browser BROWSER_ID --script 'Promise.resolve({title: document.title})'
zshell +browser state save --browser BROWSER_ID --output /tmp/zshell-login.json
zshell +browser state load --browser BROWSER_ID --input /tmp/zshell-login.json
zshell +browser reload --browser BROWSER_ID --waiteval --script runs in the real main-frame page, awaits a returned Promise, and returns JSON in value; undefined becomes null. Use an async function expression for await. Scripts are limited to 64 KiB; results to 256 KiB, 10000 values, and 64 levels. Existing DOM references expire after evaluation. A timeout stops waiting but does not cancel the script. Inspect the page before retrying a mutation; synchronous endless code can stall the page and require closing it. Single expressions, including IIFEs, are injected as native global Scripts. Multi-statement strings still follow the page’s CSP; if string evaluation is blocked, wrap the statements in an IIFE.
state save writes Playwright storage-state JSON containing cookies applicable to the target host (including parent-domain and HttpOnly cookies) and the current origin’s localStorage. state load merges those cookies and replaces that origin’s localStorage; reload afterwards. localStorage origins must match scheme, host, and port exactly. Unrelated cookie domains, public suffixes, unsupported fields, and invalid types are rejected before changes. Secure cookies require HTTPS.
Use --format cookies on both commands for Netscape cookies.txt; that format omits localStorage and SameSite. State files are limited to 256 KiB, contain credentials, and must stay private and out of Git. Imports require an owner-only regular file, such as mode 0600; symlinks are rejected. Exports create a new private file and never overwrite an existing path. WebKit site data remains shared across browser panes. These commands retain the same project, window, and navigation restrictions.
Ads and trackers
Settings → Browser enables native WebKit content blocking by default, using EasyList and EasyPrivacy. Switch either list off independently, add custom HTTP/HTTPS ABP list URLs (one per line), and choose Apply Lists. Up to 8 lists of 8 MiB each are accepted. HTTP downloads are unencrypted.
Rules apply to future requests in all existing and new browser panes; reload open pages to update resources and hidden elements. Update Lists Now forces a refresh. Lists are cached locally; opening a browser after restarting checks lists older than four days. The settings show updates, converted/skipped filter counts, failures, and use of cached rules when a refresh fails. A failed replacement does not silently reuse a different selected list.
Supported filters include URL wildcards and anchors, common resource types, @@ network exceptions, simple positive/negative domain scopes, and CSS ##/#@# hiding rules. Domain scopes use the top-level page; party classification follows WebKit. Unsupported syntax is skipped conservatively, including scriptlets, procedural filters, redirects, regular expressions, document allowlisting, and scopes combining an included domain with excluded child domains. This does not provide full uBlock Origin compatibility.