workers-og

repository·main·Indexed 43 days ago

https://github.com/kvnang/workers-og

A fast, browser-less OG image generator for Cloudflare Workers using the Satori engine. It allows developers to generate social media cards in real-time using either React elements or simple HTML strings, mimicking the @vercel/og API while ensuring compatibility with the Cloudflare Workers runtime.

Tokens
1.8K
Snippets
6
Records
8
Agent score
56%

What's inside workers-og

  1. How workers-og works and its differences from @vercel/og

    main

    workers-og is an og:image (social card) generator designed specifically for Cloudflare Workers. While it uses Vercel's Satori engine and mimics the @vercel/og API, it differs in two key ways:

    1. Runtime Compatibility: Unlike @vercel/og, which is optimized for Vercel's edge runtime and may fail on Cloudflare Workers due to WASM bundling differences, workers-og is built to run on Cloudflare Workers.
    2. HTML Input Support: While Satori typically requires React elements as input, workers-og allows you to pass simple HTML strings. It uses Cloudflare's native HTMLRewriter API to parse the HTML into a React element-like object, making it easier to design images using standard web markup.
  2. Example: Full Cloudflare Worker implementation

    main

    This example demonstrates a complete Cloudflare Worker that extracts a title from the URL search parameters and renders it inside a styled HTML template to generate a social card image.

    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,
        });
      },
    };
  3. Generate OG images using ImageResponse

    main

    You can generate images by instantiating ImageResponse. You can pass either a React element or a simple HTML string as the first argument. The second argument is an options object where you can specify the width and height of the output image.

    import { ImageResponse } from "workers-og";
    
    // Example using HTML string
    const html = `<div style="color: white;">Hello World</div>`;
    
    return new ImageResponse(html, {
      width: 1200,
      height: 630,
    });
  4. Configure ImageResponseOptions

    main

    When generating an image, you can provide an options object of type ImageResponseOptions. This type extends the standard Vercel OG options but allows you to specify the format, width, and height explicitly.

    Key properties:

    • format: The output image format. Supported values are "svg" or "png". Defaults to "png".
    • width: The width of the image in pixels. If not provided, the default is 1200.
    • height: The height of the image in pixels. If not provided, the default is 630.

    Note that width and height are omitted from the base Vercel options to allow for these specific default behaviors.

    const options: ImageResponseOptions = {
      width: 1200,
      height: 630,
      format: 'png'
    };
  5. Use the ImageResponse class for web responses

    main

    The ImageResponse class extends the standard Response object, making it ideal for use in Cloudflare Workers or other web-standard environments. It wraps the og() logic and automatically sets appropriate headers based on the requested format.

    Behavior:

    • Format svg: Returns a Response with Content-Type: image/svg+xml.
    • Format png (default): Returns a Response with Content-Type: image/png using a ReadableStream to deliver the buffer.

    Headers & Caching:

    • By default, it sets a long-lived cache header: public, immutable, no-transform, max-age=31536000.
    • If options.debug is set to true, it overrides the cache with no-cache, no-store.
    • You can provide custom headers via options.headers.

    Status Codes:

    • You can specify status and statusText in the options object (defaults to 200 OK).
    import { ImageResponse } from "workers-og";
    
    export class MyWorkerResponse extends ImageResponse {
      constructor() {
        super(
          "<div>Hello</div>",
          {
            width: 1200,
            height: 630,
            format: "png",
            debug: false
          }
        );
      }
    }
  6. Generate images with the og() function

    main

    The og() function is the core utility for converting React elements or HTML strings into image buffers (PNG) or SVG strings. It automatically handles WASM initialization for Satori, Yoga, and Resvg.

    Parameters:

    • element: A React.ReactNode or an HTML string. If a string is provided, it is parsed into a React element.
    • options: An ImageResponseOptions object defining dimensions, fonts, format, and assets.

    Returns:

    • A Uint8Array (PNG buffer) if the format is png (default).
    • A string (SVG) if the format is svg.

    Note on Fonts: If no fonts are provided in options.fonts, the function defaults to loading the 'Bitter' Google Font (weight 600).

    import { og } from "workers-og";
    
    const buffer = await og({
      element: (
        <div style={{ display: 'flex' }}>
          <h1>Hello World</h1>
        </div>
      ),
      options: {
        width: 1200,
        height: 630,
        format: "png"
      }
    });