Service that dynamically generates Open Graph images for Railway starters that looks something like
Use the generated image URL in the <head> of your HTML document as the og:image meta property
<meta property="og:image" content="https://og.railway.app/api/image?fileType=png&layoutName=Simple&Text=Hello+World" />Whenever this image is requested (e.g. in link previews) the image will be generated on demand.
Images are generated through the /api/image route. When you hit this route the following happens
- Query params are parsed
- Layout is looked up in list of layouts using the
layoutNamequery param layout.Componentis rendered with all query params asconfigprop- SVG is created from the component using Satori
- Optionally, a PNG is created from the SVG with resvg-js
This service can generate images using multiple layouts. A layout is defined as a
- Collection of properties that are user configurable. The UI for these properties is auto genearted
- Function that takes in layout config and returns CSS needed to render
- A React component that takes in layout config as a prop
For example, the "Simple" layout on og.railway.app is defined as
import React from "react"; import { z } from "zod"; import { ILayout } from "./types"; const simpleLayoutConfig = z.object({ text: z.string(), }); export type SimpleLayoutConfig = z.infer<typeof simpleLayoutConfig>; const Component: React.FC<{ config: SimpleLayoutConfig }> = ({ config }) => { return ( <div tw="flex items-center justify-center text-center px-4 w-full h-full text-8xl text-white font-bold" style={{ background: "linear-gradient(to bottom right, tomato, deeppink)", }} > {config.text} </div> ); }; export const simpleLayout: ILayout<typeof simpleLayoutConfig> = { name: "simple", config: simpleLayoutConfig, properties: [ { type: "text", name: "text", default: "Hello, world!", placeholder: "Text to display", }, ], Component, };This will render as
You can fork this repo or deploy to Railway to make it your own, customize, and use in your own projects.
The frontend is a NextJS site and the image generation happens in an API route.
# Start local development server yarn dev # Build for production yarn build # Start in production yarn start 