@cf-wasm/og

中文文档
0.5.0发布于 2026/08/01MITTypeScriptES Module构建来源已验证近 30 天下载 29.8万

在没有浏览器的情况下从 HTML/CSS 动态生成 Open Graph 图像 .

中文使用文档
文档目录15 节
  1. 安装
  2. 使用量
  3. 文档
  4. 使用 ImageResponse.async
  5. 云花板工人/页
  6. 字体装入器
  7. 默认字体
  8. SVG 格式
  9. 渲染 HTML
  10. render 函数
  11. 尾风 CSS
  12. 实例
  13. 云花岗工人
  14. Next.js (App路由器) (英语)
  15. Next.js (页路由器)

@ cf-wasm/ og

在没有浏览器的情况下从 HTML/CSS 动态生成 Open Graph 图像 .

电源 佐佐丽 财务报告和审定财务报表 (原始内容存档于2018-09-21) (英语). resvg-js。 。 。 .

[尖叫声] 中断修改可以不遵循语义版本而引入.
请注意,这个软件包可能会在版本之间发生断裂变化,而不会严格遵守语义版本(SemVer). 虽然将努力将中断减到最小,但建议在升级为新版本之前仔细审查发行说明. 我们为可能造成的不便道歉,并感谢你的理解.

安装

npm install @cf-wasm/og       # npm
yarn add @cf-wasm/og          # yarn
pnpm add @cf-wasm/og          # pnpm

使用量

因为 package.json 包括: node, (中文(简体) ), workerd,以及 edge-light,通常可以直接从 @cf-wasm/og 让运行时间选择正确的入站点 :

import { ImageResponse } from "@cf-wasm/og";

如果您想要明确, 请从子模块导入 :

  • Cloudflare Workers / Pages (Wrangler): 云花工/页面(英语:

    import { ImageResponse } from "@cf-wasm/og/workerd";
    
  • Next.js Edge 运行时间 :

    import { ImageResponse } from "@cf-wasm/og/edge-light";
    
  • 节点.js(内含):

    import { ImageResponse } from "@cf-wasm/og/node";
    

文档

使用 ImageResponse.async

建议使用 ImageResponse.async() 作为静态方法代替 new ImageResponse() 构造器 :

import React from "react";
import { ImageResponse } from "@cf-wasm/og/node";

// this is recommended
await ImageResponse.async(<>Hello World!</>);

// instead of
new ImageResponse(<>Hello World!</>);

云花板工人/页

如果您使用Cloudflare Workers/Pages,您必须设置执行上下文如下:

import React from "react";
import { ImageResponse, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    // Set execution context
    cache.setExecutionContext(ctx);

    return await ImageResponse.async(<>Hello World!</>);
  },
} satisfies ExportedHandler;

字体装入器

您可以轻松地装入 Google 字体和自定义字体 GoogleFont 财务报告和审定财务报表 CustomFont 分别是:

import React from "react";
import {
  ImageResponse,
  GoogleFont,
  CustomFont,
  cache,
} from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    return await ImageResponse.async(
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          justifyContent: "center",
          width: "100%",
          height: "100%",
        }}
      >
        <p>Text with Default font</p>
        <p style={{ fontFamily: "Inclusive Sans" }}>Text with Google font</p>
        <p style={{ fontFamily: "JetBrains Mono" }}>Text with Custom font</p>
      </div>,
      {
        fonts: [
          // Using Google font loader
          new GoogleFont("Inclusive Sans"),
          // Using Custom font loader
          new CustomFont("JetBrains Mono", () =>
            fetch(
              "https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-Regular.ttf",
            ).then((res) => res.arrayBuffer()),
          ),
        ],
      },
    );
  },
} satisfies ExportedHandler;

默认字体

您可以使用 GoogleFont 或者说 CustomFont 类 :

import React from "react";
import {
  ImageResponse,
  CustomFont,
  GoogleFont,
  defaultFont,
  cache,
} from "@cf-wasm/og/workerd";

// By using Google font loader
defaultFont.set(new GoogleFont("Merriweather"));

// or
// By using Custom font loader
defaultFont.set(
  new CustomFont("JetBrains Mono", () =>
    fetch(
      "https://github.com/JetBrains/JetBrainsMono/raw/master/fonts/ttf/JetBrainsMono-Regular.ttf",
    ).then((res) => res.arrayBuffer()),
  ),
);

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    // It should render with JetBrains Mono font
    return await ImageResponse.async(<>Hello World!</>);
  },
} satisfies ExportedHandler;

您也可以使用 defaultFont 选项 :

import React from "react";
import { ImageResponse, GoogleFont, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    return await ImageResponse.async(<>Hello World!</>, {
      // Set default font
      defaultFont: new GoogleFont("Merriweather"),
    });
  },
} satisfies ExportedHandler;

SVG 格式

默认 ImageResponse 改为: PNG 不过你可以用 format 选项 SVG数字 :

import React from "react";
import { ImageResponse, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    return await ImageResponse.async(<>Hello World!</>, {
      // Set format
      format: "svg",
    });
  },
} satisfies ExportedHandler;

渲染 HTML

这个 @cf-wasm/og/html-to-react 子模块提供函数 t 用于将 html 转换为 ReactElement 因此,还可以将html:

import { ImageResponse, cache } from "@cf-wasm/og/workerd";
import { t } from "@cf-wasm/og/html-to-react";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    const html = `<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%;">
        <p>Renders HTML</p>
        <p>Hello World!</p>
      </div>`;

    return await ImageResponse.async(t(html));
  },
} satisfies ExportedHandler;

render 函数

您还可以使用 render 函数代替 ImageResponse 用于获取错误或其他用途的情况:

import React from "react";
import { render, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    try {
      const { image } = await render(<>Hello World!</>).asPng();

      return new Response(image, {
        headers: {
          "Content-Type": "image/png",
        },
      });
    } catch {
      return new Response("Not found", {
        status: 404,
      });
    }
  },
} satisfies ExportedHandler;

尾风 CSS

佐藤里对Tailwind CSS有实验性支持,通过Tailwind CSS课程可以使用到 tw 参考文献 ReactElement。 。 。 .

import React from "react";
import { ImageResponse, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    cache.setExecutionContext(ctx);

    return await ImageResponse.async(
      <div tw="flex w-full h-full items-center justify-center">
        Hello World!
      </div>,
    );
  },
} satisfies ExportedHandler;

实例

以下是使用此库的一些例子:

云花岗工人

使用Cloudflare Workers的,可以使用如下: 1

// src/index.tsx
import React from "react";
import { ImageResponse, GoogleFont, cache } from "@cf-wasm/og/workerd";

export default {
  async fetch(req, env, ctx) {
    // Make sure to set the execution context
    cache.setExecutionContext(ctx);

    const { searchParams } = new URL(req.url);
    const parameters = Object.fromEntries(searchParams.entries());

    return await ImageResponse.async(
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          width: "100%",
          height: "100%",
          alignItems: "center",
          justifyContent: "center",
          backgroundColor: "#6f90ab",
          fontSize: "2rem",
          color: "#fff",
        }}
      >
        <span>Noto Sans (Default Font)</span>
        <span
          style={{
            fontFamily: "JetBrains Mono",
          }}
        >
          JetBrains Mono (using GoogleFont class)
        </span>
        <span>These are emojis: 😎🌩️</span>
        <span
          style={{
            fontFamily: "JetBrains Mono",
          }}
        >
          Parameters: {JSON.stringify(parameters)}
        </span>
      </div>,
      {
        fonts: [new GoogleFont("JetBrains Mono")],
        emoji: "fluent",
      },
    );
  },
} satisfies ExportedHandler;

[尖叫声] 使用时 @cf-wasm/og 打开 Cloudflare Workers/Pages,你可能会打 CPU 时限, (中文(简体) ), 128 MB 内存限制 或者说 3 MB 脚本尺寸限制( Workers Free Plan).
避免在内存中装入多字体和资产 .

Next.js (App路由器) (英语)

如果您正在使用 Next.js (App 路由器) 的边缘运行时间,您可以使用如下:

// (src/)app/api/og/route.tsx
import React from "react";
import { type NextRequest } from "next/server";
import { ImageResponse, GoogleFont } from "@cf-wasm/og/edge-light";

export const runtime = "edge";

export async function GET(req: NextRequest) {
  const { searchParams } = req.nextUrl;
  const parameters = Object.fromEntries(searchParams.entries());

  return await ImageResponse.async(
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        width: "100%",
        height: "100%",
        alignItems: "center",
        justifyContent: "center",
        backgroundColor: "#6f90ab",
        fontSize: "2rem",
        color: "#fff",
      }}
    >
      <span>Noto Sans (Default Font)</span>
      <span
        style={{
          fontFamily: "JetBrains Mono",
        }}
      >
        JetBrains Mono (using GoogleFont class)
      </span>
      <span>These are emojis: 😎🌩️</span>
      <span
        style={{
          fontFamily: "JetBrains Mono",
        }}
      >
        Parameters: {JSON.stringify(parameters)}
      </span>
    </div>,
    {
      fonts: [new GoogleFont("JetBrains Mono")],
      emoji: "fluent",
    },
  );
}

Next.js (页路由器)

如果您正在使用 Next.js (Pages 路由器) 的边缘运行时间,您可以使用如下:

// (src/)pages/api/og.tsx
import React from "react";
import { type NextRequest } from "next/server";
import { ImageResponse, GoogleFont } from "@cf-wasm/og/edge-light";

export const config = {
  runtime: "edge",
};

export default async function handler(req: NextRequest) {
  const { searchParams } = req.nextUrl;
  const parameters = Object.fromEntries(searchParams.entries());

  return await ImageResponse.async(
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        width: "100%",
        height: "100%",
        alignItems: "center",
        justifyContent: "center",
        backgroundColor: "#6f90ab",
        fontSize: "2rem",
        color: "#fff",
      }}
    >
      <span>Noto Sans (Default Font)</span>
      <span
        style={{
          fontFamily: "JetBrains Mono",
        }}
      >
        JetBrains Mono (using GoogleFont class)
      </span>
      <span>These are emojis: 😎🌩️</span>
      <span
        style={{
          fontFamily: "JetBrains Mono",
        }}
      >
        Parameters: {JSON.stringify(parameters)}
      </span>
    </div>,
    {
      fonts: [new GoogleFont("JetBrains Mono")],
      emoji: "fluent",
    },
  );
}

版本与发布记录

@cf-wasm/og 共发布 48 个版本,首次发布于 2024/03/31;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.5.0latest2026/08/013 个月前
0.4.12026/07/143 个月前
0.4.02026/06/164 个月前
0.3.82026/05/046 个月前
0.3.72026/02/118 个月前
0.3.62026/02/108 个月前

关于 @cf-wasm/og 的常见问题

@cf-wasm/og 是什么?

在没有浏览器的情况下从 HTML/CSS 动态生成 Open Graph 图像 .

如何安装 @cf-wasm/og?

在项目目录运行 npm install @cf-wasm/og,或使用 pnpm add / yarn add / bun add。

@cf-wasm/og 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cf-wasm/og 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cf-wasm/og 可以商用吗?

@cf-wasm/og 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cf-wasm/og 的下载量有多少?

根据 npm 官方下载统计,@cf-wasm/og 在 2026/10/10 – 2026/11/08 这 30 天内被下载 298,048 次,日均约 9,935 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cf-wasm/og 还在维护吗?

最新版本 0.5.0 发布于 2026/08/01(3 个月前);至今共发布 48 个版本,其中过去 12 个月发布了 15 个;首次发布于 2024/03/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。