Skip to content

Telescope ​

Keep Telescope local-only. It records request, query, job, and mail details; use dummy credentials and data while debugging. Run commands in the Laravel application.

--dev alone does not make the provider registration safe for composer install --no-dev.

Install ​

bash
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate

Local-only Registration ​

Remove App\Providers\TelescopeServiceProvider::class from bootstrap/providers.php.

File: composer.json

Add laravel/telescope to the existing extra.laravel.dont-discover array; preserve other entries.

json
"dont-discover": [
    "laravel/telescope"
]

File: app/Providers/AppServiceProvider.php (inside the existing register() method)

php
if ($this->app->environment('local') && class_exists(\Laravel\Telescope\TelescopeServiceProvider::class)) {
    $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
    $this->app->register(\App\Providers\TelescopeServiceProvider::class);
}

Refresh package discovery and clear local config:

bash
composer dump-autoload
php artisan config:clear

Telescope is not automatically disabled in production. This registration guard keeps it out. For a deliberate non-local installation, use a regular dependency and configure the viewTelescope gate before exposing it; follow the official installation notes.

Configuration ​

File: .env

dotenv
TELESCOPE_ENABLED=true

Set this to false to stop collection locally. It is not a substitute for dashboard authorization.

File: config/telescope.php (existing watchers entry)

php
Watchers\QueryWatcher::class => [
    'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
    'slow' => 100,
],

Keep the generated Watchers import. slow marks queries over 100 ms; it does not filter out faster queries. Use the provider's Telescope::filter() callback or disable watchers to reduce what gets stored.

Do not assume local request payloads and headers are redacted. Review hideSensitiveRequestDetails() and the watcher settings before capturing real traffic.

Prune Entries ​

File: routes/console.php (merge)

Guard the schedule too, so it never calls a missing dev-only command:

php
use Illuminate\Support\Facades\Schedule;

if (app()->environment('local') && class_exists(\Laravel\Telescope\TelescopeServiceProvider::class)) {
    Schedule::command('telescope:prune --hours=48')->daily();
}

Run php artisan schedule:work locally if daily pruning is needed. Otherwise prune on demand with php artisan telescope:prune --hours=48.

Verify ​

bash
php artisan route:list --path=telescope
php artisan test --compact
  • Open /telescope, make a request, and check its queries and logs.
  • Confirm /telescope is absent in a non-local environment, including a deployment built with --no-dev.
  • After package updates, run php artisan telescope:publish locally to refresh assets.

References ​