Connect to a remote browser
Connect to a remote browser over a wsEndpoint.
This example connects to a Playwright browser server that is already running and exposes a wsEndpoint.
Use it with Run a browser server. The endpoint must come from launchServer()->wsEndpoint(). It is not a Chrome DevTools Protocol URL.
Run it
In terminal 1, start the server:
php content/examples/launch-server.php
Copy the printed endpoint.
In terminal 2, connect to it:
REMOTE_WS_ENDPOINT='ws://127.0.0.1:PORT/PATH' php content/examples/connect-remote-browser.php
Expected output:
Attempting to connect to remote browser at: ws://127.0.0.1:...
Successfully connected to remote browser!
Page title: Example Domain
URL: https://example.com/
Browser connection closed.
What it demonstrates
connect()attaches to an existing Playwright browser server.- The client can create a new context and page after connecting.
- Closing the client connection does not require you to document the server as part of the same script.
If the endpoint is missing, the script prints setup instructions and exits with a non-zero status.
Common pitfalls
- Passing a CDP endpoint such as
http://127.0.0.1:9222; this example expects a PlaywrightwsEndpoint. - Copying only the host and port without the endpoint path.
- Stopping the server before running the client.
Go next
- Start the server: Run a browser server
- Compare CDP: Connect to an external browser
- Learn transport boundaries: Transport
Source
connect-remote-browser.php<?php
declare(strict_types=1);
/*
* This file is part of the community-maintained Playwright PHP project.
* It is not affiliated with or endorsed by Microsoft.
*
* (c) 2025-Present - Playwright PHP - https://github.com/playwright-php
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.'/../../vendor/autoload.php';
use Playwright\PlaywrightFactory;
// Connect to an external Playwright browser-server instance started elsewhere.
// This expects a Playwright WebSocket endpoint, not a Chrome DevTools (CDP) URL.
// launchServer() starts a browser process and exposes wsEndpoint() for connect().
$playwright = PlaywrightFactory::create();
// Provide the wsEndpoint() emitted by a process that called launchServer().
$remoteWsEndpoint = getenv('REMOTE_WS_ENDPOINT');
if (false === $remoteWsEndpoint || '' === $remoteWsEndpoint) {
echo "REMOTE_WS_ENDPOINT is not set.\n";
echo "This example needs the exact wsEndpoint() value from launchServer().\n";
echo "\nQuick setup:\n";
echo "1. In another PHP process, run:\n";
echo " \$server = \$playwright->launchServer('chromium', ['headless' => true]);\n";
echo " echo \$server->wsEndpoint();\n";
echo " while (true) { sleep(1); }\n";
echo "2. Run this example with:\n";
echo " REMOTE_WS_ENDPOINT='ws://127.0.0.1:PORT/ID' php content/examples/connect-remote-browser.php\n";
$playwright->close();
exit(1);
}
echo "Attempting to connect to remote browser at: {$remoteWsEndpoint}\n";
try {
$browser = $playwright->chromium()->connect($remoteWsEndpoint);
echo "Successfully connected to remote browser!\n";
$context = $browser->newContext();
$page = $context->newPage();
$page->goto('https://example.com');
echo "Page title: {$page->title()}\n";
echo "URL: {$page->url()}\n";
// Keep remote servers alive for other clients; only close this client connection.
$browser->close();
echo "Browser connection closed.\n";
} catch (Exception $e) {
echo "Failed to connect: {$e->getMessage()}\n";
echo "Tip: REMOTE_WS_ENDPOINT must be the full wsEndpoint() value, including path.\n";
echo "\nTo set up an external Playwright browser-server instance:\n";
echo "1. Start any PHP process with:\n";
echo " \$server = \$playwright->launchServer('chromium', ['headless' => true]);\n";
echo " echo \$server->wsEndpoint();\n";
echo " while (true) { sleep(1); }\n";
echo "2. Copy its wsEndpoint() value (ws://...)\n";
echo "3. Set REMOTE_WS_ENDPOINT to that value and run this script again\n";
}
$playwright->close();