spatie/craft-ray
Send debug output from Craft CMS to Ray, Spatie’s desktop debugging app. Inspect arrays, HTML, queries, and more with a consistent API, measure performance, and pause execution. Great for fast feedback across PHP and other languages.
Install the Package
composer require spatie/craft-ray
Add to your composer.json under require-dev if needed.
Configure Ray
php craft ray:install
.env with your Ray API key (from myray.app).
RAY_API_KEY=your_api_key_here
First Debug Output
Use ray() helper in your templates or PHP files:
// In a controller or service
ray('Debugging this value:', $someVariable);
// In a Twig template
{{ ray('Template variable:', entry) }}
Start Ray Launch the Ray desktop app and ensure it’s connected to your Craft project.
ray() calls in your plugin’s init() or service methods.Craft::$app->getDb()->enableProfiling).{{ dump(entry) }} with {{ ray(entry) }} for persistent, interactive output.{% set filteredEntries = craft.entries()
.section('blog')
.limit(5)
.all()
%}
{{ ray('Filtered entries:', filteredEntries) }}
config/ray.php:
'log_queries' => true,
ray() with Craft::$app->getDb()->createCommand():
$query = Craft::$app->getDb()->createCommand('SELECT * FROM {{%entries}} WHERE ...');
ray('SQL Query:', $query->rawSql);
ray() in environment checks (e.g., APP_DEBUG):
if (Craft::$app->getConfig()->getGeneral()->devMode) {
ray('Dev-only data:', $devData);
}
onBeforeSave or onAfterSave:
Event::on(
Entry::class,
Entry::EVENT_AFTER_SAVE,
function (Event $event) {
ray('Saved entry:', $event->sender);
}
);
ray('## User Data', [
'name' => $user->name,
'permissions' => $user->getPermissions(),
], 'markdown');
Ray with Craft’s debug():
Redirect Craft::debug() output to Ray by extending the package or using a wrapper:
function craftRayDebug($var, $label = null) {
if (Craft::$app->getConfig()->getGeneral()->devMode) {
ray($label ?? 'Debug:', $var);
}
}
Ray in CLI Commands:
Use ray() in craft console commands for real-time debugging:
public function actionTest()
{
$data = $this->someLogic();
ray('CLI Data:', $data);
}
Ray Themes:
Customize Ray’s appearance in config/ray.php:
'theme' => 'dark', // or 'light', 'custom'
API Key Leaks:
.env or config/ray.php with the API key to version control.Performance Overhead:
ray() in production by wrapping calls in APP_DEBUG checks.Query Logging:
log_queries can slow down Craft. Use sparingly in development.Ray App Connection:
Twig Caching:
{{ ray() }} may not appear until the cache is cleared. Test in dev mode (craft config/dev-mode true).Missing Output?
storage/logs/craft.log for errors (e.g., invalid API key).Slow Ray Responses:
ray()->ignore() for specific properties:
ray($user)->ignore(['passwordHash', 'apiTokens']);
SQL Queries Not Showing:
log_queries is true in config/ray.php and that you’re using ray() with query objects, not raw SQL strings.Custom Data Types:
Element, Category) by default. Extend the package or cast to arrays:
ray('Element data:', (array) $entry);
Custom Ray Handlers:
// In a service provider
Ray::extend(function ($ray) {
$ray->macro('craftElement', function ($element) {
return $ray->ray((array) $element);
});
});
Usage:
ray()->craftElement($entry);
Ray Middleware:
public function handle($request, Closure $next)
{
$response = $next($request);
ray('Request:', $request->all());
ray('Response:', $response->getContent());
return $response;
}
Ray in Tests:
$this->mock(Ray::class)->shouldReceive('ray')->once();
Ray for AI Integration:
ray('AI Response:', $aiOutput, 'markdown', ['mcp' => true]);
How can I help you explore Laravel packages today?