A trait on the model, a queued job, the URL in the database.
In Laravel the queue is the natural home. The package adds a trait: saving a post dispatches a job, the job renders through the API and stores the URL, and a failed render retries itself. Until it is done, `<x-og-image :model="$post" />` prints a signed URL of the same image, so no page goes out without one.
app/Models/Post.php
// composer require shareglint/laravel
// .env: SHAREGLINT_KEY, SHAREGLINT_ACCOUNT_ID, SHAREGLINT_SIGNING_SECRET
use Shareglint\Laravel\Concerns\HasOgImage;
use Shareglint\Laravel\Contracts\OgImageable;
final class Post extends Model implements OgImageable
{
use HasOgImage;
// On create and on every change, a queued job (after commit) renders
// the image and stores its URL in the og_image column.
public function ogImageFields(): array
{
return [
'title' => $this->title,
'author' => $this->author->name,
'date' => $this->published_at,
'reading_time' => $this->reading_minutes,
'site' => config('app.domain'),
'locale' => 'en',
];
}
// Re-render only when these change (default: any attribute).
public function ogImageWatched(): ?array
{
return ['title', 'author_id', 'published_at'];
}
}
// resources/views/posts/show.blade.php, in <head> - the stored URL,
// or a signed URL of the same image until the job has run:
// <x-og-image :model="$post" />
The same thing as one plain HTTP call — no dependency to install.
app/Jobs/GenerateOgImage.php
final class GenerateOgImage implements ShouldQueue
{
use Queueable;
public int $tries = 3;
public function __construct(private readonly int $postId) {}
public function handle(): void
{
$post = Post::findOrFail($this->postId);
$response = Http::withToken(config('services.shareglint.key'))
->timeout(20)
->post('https://shareglint.com/v1/images?wait=true', [
'template' => 'blog-og',
'locale' => 'en',
'modifications' => [
'title' => $post->title,
'author' => $post->author->name,
'date' => $post->published_at->toDateString(),
'reading_time' => $post->reading_minutes,
'site' => config('app.domain'),
],
])
->throw();
$post->update(['og_image' => $response->json('url')]);
}
}
// Dispatch it on publish:
// GenerateOgImage::dispatch($post->id)->afterCommit();
Queue after the commit. The package dispatches with `afterCommit()`; if you write the job yourself and leave it out, the worker can start before the transaction that saved the post commits — and `findOrFail` blows up on a row that does not exist yet.
With ?wait=true the finished image arrives on the same connection — usually in about a second.
{
"id": "img_01m08s3ez1zcv28h335g9923bw",
"status": "completed",
"url": "https://cdn.shareglint.com/renders/img_01m08s3ez1zcv28h335g9923bw.png",
"duration_ms": 912
}
A hundred images a month free, then $9 for two thousand. The same post rendered twice returns the existing URL and uses no quota — so rebuilding your site costs nothing.