编程

为 Laravel 应用生成用于社交网站分享的 OG 图片

4 2026-05-28 14:36:00

当你在 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:imagetwitter:imagetwitter: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 资源。无需单独配置样式表。

以下是爬虫请求图像时发生的情况:

  1. 请求于 /og-image/{hash}.jpeg 命中包控制器
  2. 该控制器从缓存中查找原始页面 URL(渲染时由 Blade 组件存储)
  3. Chrome 追加了 ?ogimage 访问页面
  4. 中间件监测到 ?ogimage 参数,并使用最小 HTML 页面替换响应:只有 <head> 标签(保留所有 CSS 和字体)及 1200x630像素的模板内容
  5. Chrome 截屏并保存到磁盘中
  6. 图片会通过 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。