Git Product home page Git Product logo

workers-og's Introduction

Cloudflare Workers OG Image Generator

Using Vercel's Satori engine, and many credits to @vercel/og for the inspiration.

An og:image (social card) generator that is fast, browser-less (no Puppeteer), and capable of running on the edge.

This package is designed to be used with Cloudflare Workers (but may be used elsewhere), with the simple API inspired by @vercel/og.

Difference from @vercel/og

@vercel/og is designed to run on Vercel’s edge runtime, and workers-og on Cloudflare Workers.

Although Vercel’s edge runtime runs on Cloudflare Workers, the way WASM is bundled is different and causes an error when using @vercel/og on a Worker.

Another unique feature: while satori (used in both @vercel/og and workers-og) accepts React element as the input, workers-og adds a feature which allows you to write a simple HTML, which will here be parsed into React element-like object. The parsing is handled by HTMLRewriter, which is part of Cloudflare Worker’s runtime API.

Getting started

Install the package on your Worker project:

npm i workers-og

Then, import it to your project. The API mimics @vercel/og closely.

import { ImageResponse } from "workers-og";

Example Usage on a Worker:

import { ImageResponse } from "workers-og";

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    const params = new URLSearchParams(new URL(request.url).search);
    const title = params.get("title") || "Lorem ipsum";

    const html = `
    <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; width: 100vw; font-family: sans-serif; background: #160f29">
      <div style="display: flex; width: 100vw; padding: 40px; color: white;">
        <h1 style="font-size: 60px; font-weight: 600; margin: 0; font-family: 'Bitter'; font-weight: 500">${title}</h1>
      </div>
    </div>
   `;

    return new ImageResponse(html, {
      width: 1200,
      height: 630,
    });
  },
};

workers-og's People

Contributors

kvnang avatar zayturner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

workers-og's Issues

Unknown file extension ".wasm" for /Users/me/project/node_modules/workers-og/dist/yoga-ZMNYPE6Z.wasm

Getting this error

at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async ModuleLoader.load (node:internal/modules/esm/loader:403:7)
at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:285:45

while using this with Remix Vite

Unnecessary Escaping of '&' Character in sanitizeJSON Function

Thank you for great project!

I've encountered an issue with the sanitizeJSON function, where it unnecessarily escapes the & character. This behavior seems to be causing issues when parsing JSON strings.

export const sanitizeJSON = (unsanitized: string) => {
  return unsanitized
    .replace(/\\/g, "\\\\")
    .replace(/\n/g, "\\n")
    .replace(/\r/g, "\\r")
    .replace(/\t/g, "\\t")
    .replace(/\f/g, "\\f")
    .replace(/"/g, '\\"')
    .replace(/\&/g, "\\&"); // this line
};
スクリーンショット 2024-01-11 1 53 15

If I've misunderstood something, I apologize 🙇

having trouble displaying images

its working fine locally, i used img tags to display two images, both are on same domain as the worker, its working perfectly when i test it locally but after deployment i get image format invalid error.

Wrangler unable to find .wasm files

Deploying this on cloudflare workers, using it as it says in the readme. Gives this error:
✘ [ERROR] Build failed with 2 errors: node_modules/esbuild/lib/main.js:1360:21: ERROR: [plugin: wrangler-module-collector] ENOENT: no such file or directory, open '/app/.output/server/chunks/resvg-LFIOYO65.wasm' node_modules/esbuild/lib/main.js:1360:21: ERROR: [plugin: wrangler-module-collector] ENOENT: no such file or directory, open '/app/.output/server/chunks/yoga-ZMNYPE6Z.wasm'

Using:
"wrangler": "3.28.2",
"nuxt": "^3.10.2",

Having trouble using external fonts & `display:block`.

Thanks for this project!
I'm exploring this worker as a way to some default OG images for our site, I'm able to get the font's arrayBuffer, but everytime I try to use it in the ImageResponse, I get in the console:

A promise rejection was handled asynchronously. This warning occurs when attaching a catch handler to a promise after it rejected. (rejection #2)
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '263')
Uncaught (in response) TypeError: Cannot read properties of undefined (reading '263')

and the page turns blank.

Now if I try to use a display:block in my template (I'm trying to use lineClamp), I also get a blank screen with this in the console

A promise rejection was handled asynchronously. This warning occurs when attaching a catch handler to a promise after it rejected. (rejection #2)
Uncaught (in promise) Error: Invalid value for CSS property "display". Allowed values: "flex" | "none". Received: "block".
Uncaught (in response) Error: Invalid value for CSS property "display". Allowed values: "flex" | "none". Received: "block".

Is there anything else I could try, or have you run into this problem?
Thanks and have a good day

Error: Already initialized. The `initWasm()` function can be used only once.

Currently, when a worker already initialized the wasm modules, the initialization throws the error: Error: Already initialized. The initWasm() function can be used only once..

This package already uses try ... catch around the initialization functions, and does a console.error when this happens, even though this indicates that it's safe to continue using the module. I would love this error not to show up when this happens, since this clutters our logs.

In my opinion, we should actually throw the error once it's not the Already initialized error, and prevent initializing twice.

Suggested approach

  • Store in global context / variable that a specific wasm module is already initialized or not.
  • Prevent re-initializing by checking this
  • Actually throw the error instead of try ... catch to make the system aware of actual errors other than Already initialized occurring and we can catch it with e.g. error tracking software.

I'm willing to open a PR if this approach sounds good!

Difference vs Cloudflare Pages Plugin vercel-og?

Hi, great library! Was just wondering if there is a difference between this and the Cloudflare Pages Plugin that supports vercel-og. The reason why I ask is because the README states that the main difference is edge compatibility, but I believe the CF Pages Plugin version of vercel-og is edge compatible. Thank you again for the great tool :)

Exception "Promise will never complete." in Pages Function

Hi there!
I'm trying to use workers-og in a Pages Function, but my Worker keeps throwing Error: Promise will never complete. This only occurs when deployed to CF, running this locally in wrangler works fine. I've managed to figure out that the exception occurs when either you try and read the contents (such as let out = new ImageResponse(...); await out.arrayBuffer()) or return the new ImageResponse straight back.
Is there any way to fix this? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.