ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Nitro + Takumi 实战:用一条服务器路由动态生成 Open Graph 社交分享图

Nitro + Takumi 实战:用一条服务器路由动态生成 Open Graph 社交分享图 Nitro Takumi 实战用一条服务器路由动态生成 Open Graph 社交分享图【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro本文基于 Nitro 仓库中的官方示例 examples/takumi 展开完整讲解如何借助 Takumitakumi-js在 Nitro 路由中按请求实时渲染 1200×630 的 Open Graph 图片并把生成的图片接入og:image元信息、提供浏览器端的边输入边出图实时预览。读完本文你将掌握从路由处理器编写、响应头上报渲染耗时到页面侧引用与性能优化的完整链路。示例概览一条路由产出动态分享图在社交平台微信、X/Twitter、Facebook 等中链接被分享时会抓取页面head里的og:image元信息来生成预览卡片。静态图片无法随链接参数变化而动态生成则可以让每一条分享链接都带上独一无二的卡片。本示例的核心思路是在 Nitro 的routes/目录下创建一条路由og.png.ts它对应的 URL 路径是/og.png路由处理器从 URL 的title、description查询参数读取文案用 Takumi 的container/text帮助函数搭出节点树用ImageResponse把这棵节点树渲染成 PNG 图片并直接返回Nitro 处理器可以返回ResponseImageResponse本身就是Response的子类index.html通过og:image元信息指向该路由抓取器每次访问都会拿到一张实时渲染的预览图页面自身还实现了输入即出图的实时预览交互。示例文件结构仓库中该示例的完整目录如下examples/takumi/ ├── README.md # 示例说明本文主体内容来源 ├── index.html # 演示页面OG 元信息 实时预览 ├── nitro.config.ts # Nitro 配置扫描 ./ 目录下的路由 ├── package.json # 依赖与 dev/build/preview 脚本 ├── tsconfig.json ├── vite.config.ts # Vite 与 Nitro 的衔接配置 ├── routes/ │ └── og.png.ts # 核心动态生成 OG 图片的路由处理器 └── src/ └── styles.css # 演示页面样式含暗色模式与徽标动画服务端路由routes/og.png.ts 逐步拆解核心代码位于 examples/takumi/routes/og.png.ts完整内容如下import { defineHandler } from nitro; import { container, text } from takumi-js/helpers; import ImageResponse from takumi-js/response; export default defineHandler(async ({ url }) { const title url.searchParams.get(title) ?? Takumi Nitro; const description url.searchParams.get(description) ?? Render OG images from a Nitro route.; const start performance.now(); const response new ImageResponse( container({ style: { width: 100%, height: 100%, display: flex, flexDirection: column, justifyContent: center, padding: 64px, backgroundImage: linear-gradient(to bottom right, #fff1f2, #fecdd3), }, children: [ text(title, { fontSize: 72, fontWeight: 700, color: #111827 }), text(description, { fontSize: 42, fontWeight: 500, color: #4b5563 }), ], }), { width: 1200, height: 630 } ); await response.ready; response.headers.set(Server-Timing, render;dur${(performance.now() - start).toFixed(1)}); return response; });路由如何被识别文件系统路由与serverDir根据 Nitro 的路由机制详见 docs/1.docs/5.routing.mdroutes/目录下的文件会被自动映射为路由文件名即路径。og.png.ts的文件名里自带.png扩展名因此映射出的路径就是/og.png返回的是一张 PNG 图片而非 HTML 页面。文件系统路由的前提是在配置中声明扫描目录。本示例的 examples/takumi/nitro.config.ts 非常简单import { defineConfig } from nitro; export default defineConfig({ serverDir: ./, });serverDir: ./表示以示例目录为服务端根目录进行扫描于是routes/og.png.ts被识别为路由、src/styles.css等静态资源照常由 Vite 托管。注意根据路由文档serverDir或scanDirs默认不会自动扫描任何目录这一步是必需的。用 defineHandler 获得更好的类型推断处理器使用了从nitro导入的defineHandler。相比裸函数defineHandler在开发体验上的优势是更好的类型推断见 docs/1.docs/5.routing.md 的对比示例。这里通过解构拿到url即可读取查询参数const title url.searchParams.get(title) ?? Takumi Nitro; const description url.searchParams.get(description) ?? Render OG images from a Nitro route.;??兜底保证了即使不带任何查询参数路由也能渲染出默认文案不会返回空图。用 Takumi helpers 搭节点树免去 JSX 配置Takumi 提供container/text等帮助函数来自takumi-js/helpers以纯函数方式声明式地构建图片节点树无需任何 JSX 或构建期转换配置container定义一个块级容器通过style控制布局width/height撑满画布、display: flexflexDirection: columnjustifyContent: center让内容垂直居中、padding: 64px留出边距、backgroundImage使用从#fff1f2到#fecdd3的粉色调渐变背景text定义文本节点children中依次放入标题与描述两行文本并通过fontSize、fontWeight、color控制字体样式72px 加粗深色标题 42px 中等字重的灰色描述形成清晰的层级对比。构造 ImageResponse 并等待渲染完成ImageResponse来自takumi-js/response接收两参第一参是根节点树第二参是输出画布尺寸new ImageResponse(nodeTree, { width: 1200, height: 630 })1200×630 正是社交平台分享卡片的标准横图比例与 index.html 中og:image:width/og:image:height的声明一一对应。构造完成后立即await response.ready等待图像实际渲染完毕随后再向响应头写入Server-Timingresponse.headers.set(Server-Timing, render;dur${(performance.now() - start).toFixed(1)});Server-Timing是标准化的性能上报响应头调用方演示页面或curl可以从中解析出本次渲染耗时。由于 Nitro 处理器可以直接返回ResponseImageResponse无需任何包装即可作为路由返回值。渲染后端Node 原生绑定与 Edge WASM 的自动选择README 明确说明Takumi 会根据部署目标自动选择渲染后端——Node preset 下使用原生绑定Edge preset 下使用 WebAssembly全程无需配置。仓库的 docs/pnpm-lock.yaml 可以佐证这一点依赖树中同时存在takumi-rs/core按平台分发的darwin-arm64、linux-x64-gnu、win32-x64-msvc等原生二进制包与takumi-rs/wasmWebAssembly 版本这正是同一套 API、多后端自动切换的实现基础。对开发者而言这意味着同一份og.png.ts代码既能跑在 Node 服务器上也能无改动地部署到 Cloudflare Workers、Deno Deploy 等边缘运行时。依赖与运行脚本examples/takumi/package.json 内容如下{ type: module, scripts: { dev: vite dev, build: vite build, preview: node .output/server/index.mjs }, devDependencies: { nitro: latest, takumi-js: ^2.1.1, vite: latest } }nitro提供路由、构建与部署能力takumi-js提供图片渲染能力vite驱动开发服务器与构建项目以 ESM 运行type: module脚本约定dev启动开发服务器build产出.output/preview用 Node 直接运行构建产物。页面侧引用OG 元信息、预加载与防布局偏移演示页面 examples/takumi/index.html 在head中把 Open Graph 标签指向动态路由让抓取器拿到实时渲染的预览meta propertyog:type contentwebsite / meta propertyog:title contentTakumi Nitro / meta propertyog:description contentRender OG images from a Nitro route. / meta propertyog:image content/og.png?titleTakumi%20%2B%20NitrodescriptionRender%20OG%20images%20from%20a%20Nitro%20route. / meta propertyog:image:width content1200 / meta propertyog:image:height content630 / meta nametwitter:card contentsummary_large_image / meta nametwitter:image content/og.png /要点解读og:image指向/og.png?title...description...把标题与描述编码进查询参数空格编码为%20、编码为%2B抓取器访问时即触发一次实时渲染显式声明og:image:width/og:image:height帮助抓取器在图片下载完成前就知道卡片尺寸同时提供twitter:card为summary_large_image兼容 X/Twitter 的大图卡片head中还有一条preloadlink relpreload asimage href/og.png?titleTakumi%20%2B%20NitrodescriptionRender%20OG%20images%20from%20a%20Nitro%20route. /preload让浏览器在解析 HTML 的同时就并行发起首次图片请求提前开始渲染缩短首屏等待。页面主体中的img则通过width1200 height630属性与 CSS 中的aspect-ratio: 1200 / 630见 examples/takumi/src/styles.css预先占位避免图片加载过程中的布局抖动CLS。实时预览前端如何边输入边出图index.html底部内联脚本实现了完整的交互闭环页面加载时立即调用loadPreview(preview.src)拉取初始图片标题/描述两个输入框监听input事件经300ms 防抖refreshDebounced后触发refresh()refresh()用URLSearchParams重新拼接/og.png?title...description...同步更新右上角原始端点链接endpointLink.href再调用loadPreviewloadPreview通过fetch获取图片为Blob用URL.createObjectURL写入img并从响应的Server-Timing头中用正则/dur([\d.])/解析出渲染毫秒数显示在预览图右下角的徽标里渲染中显示 Generating…完成显示 N ms通过requestId递增标记 if (id ! requestId) return丢弃过期响应防止快速连续输入时旧请求覆盖新结果替换blob:地址前还会URL.revokeObjectURL释放旧对象避免内存泄漏。徽标在 styles.css 中通过[data-pending]属性切换黄色脉冲动画让正在生成的状态一目了然。运行与验证在仓库根目录或示例目录执行# 安装依赖 pnpm install # 启动开发服务器 pnpm dev # 生产构建并本地预览 pnpm build pnpm preview开发模式下访问http://localhost:3000/即可看到演示页面与实时预览。直接用命令行验证渲染端点与性能头curl -i http://localhost:3000/og.png?titleHellodescriptionFrom%20Nitro响应应包含Content-Type: image/png、Server-Timing: render;dur...等头部配合-o保存后即可得到一张 1200×630 的 PNG 图片。README 还提示标题旁的链接图标始终指向当前预览对应的原始端点方便随时复制分享。扩展思路与注意事项文案自由度路由把title/description作为查询参数这意味着任何链接分享场景都能携带自定义文案也可以在此基础上升级为读取event.context.params的动态路由或结合runtimeConfig提供站点级默认值样式扩展text/container的style支持常规 CSS 属性字号、字重、颜色、渐变背景等示例本身已用渐变背景 双文本层级展示了常见卡片风格演示页 styles.css 还提供了完整的浅色/暗色双主题参考性能可观测Server-Timing头让渲染耗时对调用方透明可直接接入链路追踪或监控告警部署无差别同一份处理器代码在 Node preset 走原生绑定、在 Edge preset 走 WebAssembly无需为部署目标改代码——这正是把图片生成这类计算任务放进服务器路由的价值所在。本示例的完整说明与页面代码可在 examples/takumi 中查看其镜像文档收录于 docs/4.examples/takumi.md路由机制的整体说明参见 docs/1.docs/5.routing.md。【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表