@ogify/core
v0.1.4
Published
Core types and utilities for OGify Open Graph image generator
Downloads
374
Readme
OGify - Beautiful Dynamic OG Images in Seconds
Generate stunning Open Graph images in seconds, not hours. OGify eliminates the complexity of OG image generation with zero-config font loading, automatic caching, and production-ready templates.
⚡ Why OGify?
- 🔌 Zero-config: Works out of the box with Next.js, Remix, Astro, etc.
- 🎨 No font management: Just specify a Google Font name - no downloads, no font files, no hassle.
- 📦 No asset pipeline: Emojis load dynamically from CDNs.
- 🖼️ Rich templates: OGify provides a set of production-ready templates with zero configuration.
- ⚡ Smart caching: OGify automatically caches fonts, emojis, and generated images - no configuration required.
- 🛡️ Type-safe: Full TypeScript support catches errors before runtime.
📦 Installation
pnpm add @ogify/core🚀 Quick Start
1. Define a Template
Create a template using defineTemplate with an HTML renderer function:
import { defineTemplate, OgTemplateOptions } from '@ogify/core';
const blogTemplate = defineTemplate({
id: 'blog-post',
name: 'Blog Post',
description: 'Template for blog post OG images',
fonts: [
{ name: 'Inter', weight: 700 },
{ name: 'Inter', weight: 400 }
],
renderer: ({ params }: OgTemplateOptions) => {
return `
<div style="display: flex; flex-direction: column; width: 100%; height: 100%; background: white; padding: 40px;">
<h1 style="font-size: 60px; font-weight: 700; color: #000;">
${params.title}
</h1>
<p style="font-size: 30px; color: #666;">
${params.description}
</p>
</div>
`;
},
});2. Create a Renderer
Create a renderer instance and register your templates:
import { createTemplateRenderer } from '@ogify/core';
const renderer = createTemplateRenderer({
templates: [blogTemplate],
defaultParams: {
brand: 'My Company'
}
});3. Generate an Image
Render a template to a PNG buffer:
// Basic usage (1200x630)
const imageBuffer = await renderer.renderToImage('blog-post', {
title: 'Hello World',
description: 'My first OG image'
});
// Custom dimensions for Twitter (1200x675)
const twitterImage = await renderer.renderToImage('blog-post', {
title: 'Hello World'
}, {
width: 1200,
height: 675
});That's it! You're ready for production. No font files to download, no build configuration, no asset pipeline.
🚀 Time-Saving Features
Zero-Config Google Fonts
Traditional approach (manual setup):
// ❌ Manual: Download fonts, manage files, configure paths
import fs from 'fs';
const fontData = fs.readFileSync('./fonts/Inter-Bold.ttf');
const font2Data = fs.readFileSync('./fonts/Inter-Regular.ttf');
const fonts = [
{ name: 'Inter', data: fontData, weight: 700 },
{ name: 'Inter', data: font2Data, weight: 400 }
];OGify approach (zero config):
// ✅ OGify: Just specify the font name - we handle the rest
const template = defineTemplate({
fonts: [
{ name: 'Inter', weight: 700 }, // Automatically loaded from Google Fonts
{ name: 'Inter', weight: 400 }
],
// ...
});Time saved: ~15 minutes per font family
Automatic Caching
// First render: Downloads fonts from Google (~500ms)
await renderer.renderToImage('blog-post', { title: 'Post 1' });
// Second render: Uses cached fonts (~50ms) - 10x faster! ⚡
await renderer.renderToImage('blog-post', { title: 'Post 2' });
// All subsequent renders: Lightning fast
await renderer.renderToImage('blog-post', { title: 'Post 3' });Performance: 10x faster after first render, no configuration needed
Dynamic Emoji Loading
// ✅ Emojis just work - loaded dynamically from CDN
renderer: ({ params }) => `
<div>
<h1>${params.title}</h1>
<div>👋 😄 🎉 🚀</div> <!-- Automatically rendered -->
</div>
`Time saved: No emoji sprite sheets, no asset management, no build step
📚 Advanced Usage
Custom Fonts
Load fonts from Google Fonts, custom URLs, or embedded data:
const template = defineTemplate({
id: 'custom-fonts',
name: 'Custom Fonts Template',
description: 'Template with custom fonts',
fonts: [
// Google Fonts (automatic)
{ name: 'Roboto', weight: 400 },
// Custom URL
{ name: 'MyFont', url: 'https://example.com/font.woff2', weight: 700 },
// Embedded data
{ name: 'EmbeddedFont', data: fontBuffer, weight: 400 }
],
renderer: ({ params }) => `<div>${params.title}</div>`
});Emoji Support
Choose from multiple emoji providers:
const template = defineTemplate({
id: 'emoji-template',
name: 'Emoji Template',
description: 'Template with emoji support',
fonts: [{ name: 'Inter', weight: 400 }],
emojiProvider: 'twemoji', // or 'fluent', 'noto', 'openmoji', etc.
renderer: ({ params }) => `
<div>
<h1>${params.title}</h1>
<div>👋 😄 🎉</div>
</div>
`
});Lifecycle Hooks
Add custom logic before and after rendering:
const renderer = createTemplateRenderer({
templates: [blogTemplate],
beforeRender: async (templateId, params) => {
console.log(`Rendering ${templateId}`, params);
// Log analytics, validate params, etc.
},
afterRender: async (templateId, params, imageBuffer) => {
console.log(`Rendered ${templateId} successfully`);
// Cache image, send notifications, etc.
}
});Platform-Specific Dimensions
Generate images for different platforms:
// Facebook/LinkedIn (1200x630)
const facebookImage = await renderer.renderToImage('blog-post', params);
// Twitter (1200x675)
const twitterImage = await renderer.renderToImage('blog-post', params, {
width: 1200,
height: 675
});🎨 Template Features
Supported CSS Properties
Templates support a subset of CSS properties via Satori:
- Layout:
display: flex,flexDirection,alignItems,justifyContent - Spacing:
padding,margin,gap - Typography:
fontSize,fontWeight,color,lineHeight,textAlign - Background:
backgroundColor,backgroundImage - Border:
border,borderRadius - Size:
width,height,maxWidth,maxHeight
Tailwind-like Utilities
You can use Tailwind-like class names:
renderer: ({ params }) => `
<div class="flex flex-col items-center justify-center w-full h-full bg-white p-4">
<h1 class="text-[60px] font-bold text-black">${params.title}</h1>
<p class="text-[30px] text-gray-600">${params.description}</p>
</div>
`📖 API Reference
defineTemplate(config)
Defines a new OG template.
Parameters:
id(string): Unique identifiername(string): Human-readable namedescription(string): Template descriptionrenderer(function): Function that returns HTML stringfonts(array): Array of font configurationsemojiProvider(optional): Emoji provider to use
Returns: OgTemplate
createTemplateRenderer(config)
Creates a new template renderer instance.
Parameters:
templates(array): Array of template definitionsdefaultParams(optional): Default parameters for all templatesbeforeRender(optional): Hook called before renderingafterRender(optional): Hook called after rendering
Returns: TemplateRenderer
renderer.renderToImage(templateId, params, options?)
Renders a template to a PNG buffer.
Parameters:
templateId(string): ID of the template to renderparams(object): Parameters to pass to the templateoptions(optional): Rendering optionswidth(number): Image width (default: 1200)height(number): Image height (default: 630)
Returns: Promise<Buffer>
renderer.getTemplate(id)
Retrieves a template by ID.
Returns: OgTemplate | undefined
renderer.getTemplateIds()
Gets all registered template IDs.
Returns: string[]
⚡ Performance & Production
Automatic Caching (Zero Config)
OGify automatically caches fonts and emojis in memory - no configuration required:
// First render: Downloads fonts from Google Fonts (~500ms)
await renderer.renderToImage('blog-post', { title: 'Post 1' });
// Second render: Uses cached fonts (~50ms) - 10x faster! ⚡
await renderer.renderToImage('blog-post', { title: 'Post 2' });
// Third+ renders: Lightning fast from cache
await renderer.renderToImage('blog-post', { title: 'Post 3' });📋 Changelog
See CHANGELOG.md for a complete history of changes and releases.
🤝 Contributing
We welcome contributions! Please see our contributing guidelines.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Credits
Built on top of:
- satori - SVG generation
- satori-html - HTML to VDOM conversion
- resvg-js - PNG conversion
