@ 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",
},
);
}