为 Laravel 应用生成用于社交网站分享的 OG 图片
当你在 Twitter、Facebook 或 LinkedIn 上分享链接时,泽泻平台会显示预览图。要正确显示 Open Graph 图片,通常需要使用外部服务或设置独立的渲染管道。Spatie 有一个 laravel-og-image 包,这个包允许你直接在 Blade 视图中将 OG 图片定义为 HTML。该软件包会截取 HTML 的屏幕截图并将其作为 OG 图片提供。无需外部 API,所有操作都在你自己的服务器上进行。
接下来,我将为你详细介绍该软件包的功能。
开始
Composer 安装
composer require spatie/laravel-og-image该软件包底层使用了 spatie/laravel-screenshot,这需要服务器上安装 Node.js 和 Chrome/Chromium 浏览器。如果你不想安装这些,可以使用 Cloudflare 的浏览器渲染 API(稍后会详细介绍)。
该软件包会自动在 web 分组中注册中间件,因此无需手动配置。只需将 Blade 组件添加到视图中即可:
<x-og-image>
<div class="w-full h-full bg-blue-900 text-white flex items-center justify-center">
<h1 class="text-6xl font-bold">{{ $post->title }}</h1>
</div>
</x-og-image>这就是全部所需。该组件会在页面主体中输出一个隐藏的 <template> 标签,中间件会将 og:image、twitter:image 和 twitter:card 元标签注入到 <head> 标签中:
<head>
<!-- your existing head content -->
<meta property="og:image" content="https://yourapp.com/og-image/a1b2c3d4e5f6.jpeg">
<meta name="twitter:image" content="https://yourapp.com/og-image/a1b2c3d4e5f6.jpeg">
<meta name="twitter:card" content="summary_large_image">
</head>图片 URL 包含 HTML 内容的哈希值。当你更改模板时,哈希值也会随之改变,因此爬虫程序会自动抓取新图片。
工作原理
巧妙之处在于,你的原始图像模板就位于实际页面上,因此它会继承页面现有的 CSS、字体和 Vite 资源。无需单独配置样式表。
以下是爬虫请求图像时发生的情况:
- 请求于
/og-image/{hash}.jpeg命中包控制器 - 该控制器从缓存中查找原始页面 URL(渲染时由 Blade 组件存储)
- Chrome 追加了
?ogimage访问页面 - 中间件监测到
?ogimage参数,并使用最小 HTML 页面替换响应:只有<head>标签(保留所有 CSS 和字体)及 1200x630像素的模板内容 - Chrome 截屏并保存到磁盘中
- 图片会通过
Cache-Control标头返回给爬虫程序。、
后续请求直接从磁盘提供图像。此路由无需会话、CSRF 或 Cookie,并且内容哈希 URL 可与 Cloudflare 等 CDN 完美兼容。
你可以通过在页面 URL 后附加 ?ogimage 来预览任何 OG 图像。这在设计模板时非常有用。
使用 Blade 视图
除了直接编写 HTML 代码外,你还可以引用单独的 Blade 视图:
<x-og-image
view="og-image.post"
:data="['title' => $post->title, 'author' => $post->author->name]"
/>该视图接收数据数组作为变量:
{{-- resources/views/og-image/post.blade.php --}}
<div class="w-full h-full bg-blue-900 text-white flex items-center justify-center p-16">
<div>
<h1 class="text-6xl font-bold">{{ $title }}</h1>
<p class="text-2xl mt-4">by {{ $author }}</p>
</div>
</div>当你需要在多个页面中重复使用相同的布局,或者模板变得足够复杂以至于你希望将其放在单独的文件中时,这将非常方便。
备用图像
默认情况下,未使用 <x-og-image> 组件的页面不会获得任何 OG 图片元标签。你可以在 AppServiceProvider 中注册一个回退方案:
use Illuminate\Http\Request;
use Spatie\OgImage\Facades\OgImage;
public function boot(): void
{
OgImage::fallbackUsing(function (Request $request) {
return view('og-image.fallback', [
'title' => config('app.name'),
'url' => $request->url(),
]);
});
}闭包接收完整的 Request 对象,因此你可以使用路由参数和模型绑定来自定义图像。返回 null 可跳过特定请求的回退。已显式包含 <x-og-image> 组件的页面永远不会受到回退的影响。
自定义屏幕截图
你可以通过 AppServiceProvider 中的 OgImage facade 配置图像大小、格式、质量和存储磁盘:
use Spatie\OgImage\Facades\OgImage;
OgImage::format('webp')
->size(1200, 630)
->disk('s3', 'og-images');默认情况下,图像以 1200x630 像素的尺寸生成,设备缩放因子为 2,从而生成清晰的 2400x1260 像素图像。你还可以单独设置每个组件的尺寸:
<x-og-image :width="800" :height="400">
<div>Custom size OG image</div>
</x-og-image>如果你不想在服务器上安装 Node.js 和 Chrome,可以使用 Cloudflare 的浏览器渲染 API 来代替:
OgImage::useCloudflare(
apiToken: env('CLOUDFLARE_API_TOKEN'),
accountId: env('CLOUDFLARE_ACCOUNT_ID'),
);预生成图片
默认情况下,图片会在爬虫首次请求时延迟生成。如希望提前准备好图片,可以使用 artisan 命令预先生成它们:
php artisan og-image:generate https://yourapp.com/page1 https://yourapp.com/page2或者通过编程方式生成图像,这对于在发布内容后立即生成图像非常有用:
use Spatie\OgImage\Facades\OgImage;
class PublishPostAction
{
public function execute(Post $post): void
{
// ... publish logic ...
dispatch(function () use ($post) {
OgImage::generateForUrl($post->url);
});
}
}小结
使用此包,你的 OG 图片实际上就是 Blade 视图。你可以使用与应用程序其他部分相同的 Tailwind 类、字体和资源来设计它们。无需单独的渲染设置、外部 API 或手动元标签管理。
你可以在文档网站上找到完整的文档,并在 GitHub 上找到源代码。
使用 <template> 标签在页面 CSS 中定义 OG 图片的方法灵感来自 Peter Suhm 的 OGKit。如果您不想自行托管 OG 图片的生成,强烈建议了解一下 OGKit。