spatie/laravel-og-image
Generate Open Graph images in Laravel from Blade-defined HTML. Automatically renders screenshots, serves them from a route, and caches files. Templates reuse your app’s CSS, fonts, and Vite assets—no external API required.
Installation:
composer require spatie/laravel-og-image
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\LaravelOgImage\OgImageServiceProvider"
First Use Case: Generate a basic OG image for a blog post:
use Spatie\LaravelOgImage\Facades\OgImage;
$ogImage = OgImage::create('blog-post')
->title('My Awesome Blog Post')
->description('A detailed description of the blog post')
->width(1200)
->height(630)
->saveToStorage('public/og-images');
Access the generated image via:
$ogImage->getPath(); // e.g., 'public/og-images/blog-post-1234567890.png'
Where to Look First:
config/og-image.php for default settings (e.g., storage paths, fonts).app/OgImage directory (if using custom templates) or vendor/spatie/laravel-og-image/src/OgImage for template logic.Define Templates:
Create a template file (e.g., resources/views/vendor/og-images/blog-post.blade.php) with placeholders like:
<div style="font-family: Arial; font-size: 24px; color: #333;">
{{ $title }}
</div>
<div style="font-size: 16px; color: #666;">
{{ $description }}
</div>
Register it in config/og-image.php:
'templates' => [
'blog-post' => 'vendor.og-images.blog-post',
],
Dynamic Generation: Use the facade or service container to generate images dynamically:
// In a controller or service
$ogImage = OgImage::create('blog-post')
->title($post->title)
->description($post->excerpt)
->colors(['background' => '#ffffff', 'text' => '#333333'])
->saveToStorage('public/og-images');
Reuse Templates:
Extend existing templates by overriding them in your resources/views directory. Example:
OgImage::create('blog-post')
->setTemplate('custom.blog-post') // Overrides default
->addImage('https://example.com/image.jpg', 300, 200, 'top-right')
->generate();
Cache Management: Leverage Laravel’s cache to avoid regenerating images unnecessarily:
$ogImage = OgImage::create('blog-post')
->cacheForMinutes(60) // Cache for 1 hour
->generate();
Blade Directives:
Use @ogImage in Blade templates to embed OG image URLs:
<meta property="og:image" content="{{ ogImage('blog-post', $post) }}">
Register the directive in AppServiceProvider@boot():
Blade::directive('ogImage', function ($expression) {
return "<?php echo Spatie\\LaravelOgImage\\Facades\\OgImage::url($expression); ?>";
});
API Responses: Return OG image URLs in API responses for social sharing:
return response()->json([
'title' => $post->title,
'og_image' => OgImage::url('blog-post', $post),
]);
Queue Jobs: Offload image generation to a queue for performance:
OgImage::create('blog-post', $post)
->onQueue('og-images')
->generate();
Template Paths:
resources/views/vendor/og-images will fall back to the default template, which may not match your design.templates array in config/og-image.php and ensure custom templates exist.Storage Permissions:
storage/app/public/og-images).php artisan storage:link and ensure the directory is writable:
chmod -R 755 storage/app/public/og-images
Dynamic Content in Templates:
@foreach) directly in OG templates may cause errors because the package renders templates outside the Laravel request lifecycle.$ogImage->setData(['items' => $post->relatedItems->take(3)]);
Caching Issues:
$ogImage->cacheForMinutes(0); // Disable caching for testing
Font Loading:
@font-face in your template or host fonts on a CDN:
@font-face {
font-family: 'MyFont';
src: url('https://example.com/fonts/MyFont.woff2') format('woff2');
}
Log Generation:
Enable debug mode in config/og-image.php to log template rendering:
'debug' => env('OG_IMAGE_DEBUG', false),
Check Laravel logs for errors during template compilation.
Image Validation:
Use browser dev tools to inspect the generated image’s <meta> tags. Tools like Facebook Sharing Debugger can validate OG tags.
Template Overrides: If a template isn’t being picked up, verify:
config/og-image.php.resources/views/vendor/og-images/blog-post.blade.php).Custom Drivers:
Extend the OgImage class to support additional storage backends (e.g., S3, remote URLs):
namespace App\Services;
use Spatie\LaravelOgImage\OgImage as BaseOgImage;
class CustomOgImage extends BaseOgImage {
public function saveToS3() {
// Custom logic
}
}
Template Helpers: Add reusable components to templates via a helper class:
// app/Services/OgImageHelper.php
class OgImageHelper {
public static function formatTitle(string $title): string {
return ucfirst(strtolower($title));
}
}
Use in template:
{{ OgImageHelper::formatTitle($title) }}
Event Listeners: Trigger actions after image generation (e.g., notify a service):
OgImage::create('blog-post')
->afterGenerate(function ($path) {
Log::info("OG image generated at: $path");
// Dispatch an event or call an external API
})
->generate();
Dynamic Templates: Generate templates dynamically based on data:
$template = "blog-post-{$post->category->slug}";
OgImage::create($template)
->title($post->title)
->setTemplate("custom.$template")
->generate();
How can I help you explore Laravel packages today?