Skip to content
Scalpels home

Scalpels is officially launching on October 31, 2026. Special early adopter pricing is available now.

← All documentation

Documentation

Reel

Connecting your apps

Updated

Each Laravel application you want to record is an application in Reel. You connect it by installing the Reel client package in that application and enrolling it with a one-time code. Scalpels does not do this step for you: Reel is not attached through Attach to an existing app, because enrollment generates a signing key inside your application and nothing should hold that key on your behalf.

The application must run Laravel 13.

The enrollment code lives for 15 minutes, so do the slow work first: install the package, hide sensitive routes and add the recorder. Create the application in Reel last and enroll straight away.

1. Install the client

The client is artisan-build/reel-client. It lives in the packages/reel-client folder of the Reel repository and is not published on Packagist, so composer require cannot find it on its own. Copy it into your application's source tree and add it as a path repository with a relative URL:

# in the application you want to record
git clone --depth 1 https://github.com/artisan-build/reel.git /tmp/reel
mkdir -p vendor-src
cp -R /tmp/reel/packages/reel-client vendor-src/reel-client
rm -rf /tmp/reel vendor-src/reel-client/vendor vendor-src/reel-client/composer.lock

composer config repositories.reel-client \
  '{"type":"path","url":"vendor-src/reel-client","options":{"symlink":false}}'
composer require artisan-build/reel-client

Commit vendor-src/reel-client, composer.json and composer.lock together, and make sure vendor-src/ is not ignored by Git. Prove the build server will succeed with rm -rf vendor && composer install.

You can use the copy of the client in your own Reel fork instead of artisan-build/reel. Use the same version as your Reel deployment.

2. Hide sensitive routes

Before anything records, mark every route whose whole page must never be recorded. The exclusion is absolute for that response:

Route::get('/billing/payment-method', PaymentMethodController::class)->hiddenFromReel();

Route::hiddenFromReel()->group(function (): void {
    require __DIR__.'/auth.php';
});

Review authentication, password recovery, card entry, health data and privileged admin routes. See Privacy and capture for masking parts of a page.

3. Add the recorder to your layout

<x-reel::recorder />

The component loads the recorder scripts. It does not start recording, and it renders nothing on a hidden route.

4. Create the application in Reel and enroll

  1. In Reel, open Applications and select Create application.
  2. Enter a name, the Allowed origins (one HTTP or HTTPS origin per line, such as https://app.example.com, with no path, query string or fragment) and a sampling percent. Select Create application.
  3. Copy the enrollment code from the next screen. It is shown once and expires in 15 minutes. Reel stores only a hash of it.
  4. Straight away, in your application:
php artisan reel:install

It asks for the Reel URL, the application ID, the enrollment code and a Reel Context export mode (answer off unless you want the Nightwatch link described in Configuration). You can pass them as --url, --application, --enrollment-code and --context-export instead.

On success it prints Reel enrolled. The signing key remains local to this application. The command generates an RSA key pair inside your application, sends only the public key to Reel, and writes REEL_URL, REEL_APPLICATION_ID, REEL_PRIVATE_KEY and REEL_CONTEXT_EXPORT to the application's local .env file.

The application ID and the enrollment endpoint are also shown in the Connection section of the application's settings page.

5. Carry the values to your deployed application

reel:install writes only to the local .env file. Set the same four values wherever the deployed application keeps its environment (for Laravel Cloud, Environment → Variables). REEL_PRIVATE_KEY is a credential: store it as a secret and never commit it. If you need a key in another environment, use Rotate in Reel and run reel:install there rather than copying this key.

The client switches itself on only when REEL_URL and REEL_PRIVATE_KEY are both set.

6. Start recording after consent

Your application owns the consent decision. Call Reel.start() once the visitor has agreed:

document.querySelector('#accept-cookies').addEventListener('click', async () => {
    const status = await Reel.start({ consent: true, refuseOnGpc: true });
    console.log(status.state);
});

state is recording on success. See Privacy and capture for the other states and for Reel.stop() and Reel.status().

Verify the connection

  1. Locally, php artisan route:list | grep reel should show reel/session-grants and two reel/assets/... routes.
  2. On the deployed application, curl -sI https://<your-app-hostname>/reel/assets/reel-recorder-0.1.0.js | head -1 should return 200. A 404 means the client is switched off in that environment.
  3. In the application's Signing credentials, the credential should read Active rather than Pending enrollment.
  4. Start recording, click around, and open Sessions in Reel. The session appears with status Recording almost immediately. It becomes playable later; see Sessions and replay.

Removing the client

Stop calling Reel.start() and deploy that first. Then select Disable ingest on the application in Reel, remove the component and the package, and only then revoke the credential. Historical recordings are not deleted when you remove the client.