@ogify/core 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -393
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Zero-config dynamic Open Graph images for Next.js, Nuxt, Remix, and more. Just copy & paste the production-ready templates.
|
|
8
8
|
|
|
9
|
-

|
|
10
10
|
|
|
11
11
|
## ⚡ Why OGify?
|
|
12
12
|
|
|
@@ -17,399 +17,11 @@ Zero-config dynamic Open Graph images for Next.js, Nuxt, Remix, and more. Just c
|
|
|
17
17
|
- ⚡ **Smart caching**: Automatically caches fonts, emojis, and generated images - no configuration required.
|
|
18
18
|
- 🌍 **RTL Support**: Built-in support for Right-to-Left languages like Arabic, Hebrew, and Persian.
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## 📚 Documentation
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
or
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm install @ogify/core @ogify/templates
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
or
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
yarn add @ogify/core @ogify/templates
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## 🚀 Quick Start
|
|
39
|
-
|
|
40
|
-
### 1. Choose a Template
|
|
41
|
-
|
|
42
|
-
OGify comes with a collection of beautiful, production-ready templates. Check out [our gallery](https://ogify.dev/templates) for more.
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
import template from '@ogify/templates/basic';
|
|
46
|
-
import type { TemplateParams } from '@ogify/templates/basic';
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 2. Create a Renderer
|
|
50
|
-
|
|
51
|
-
Create a renderer instance and register your template:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { createRenderer } from '@ogify/core';
|
|
55
|
-
import template from '@ogify/templates/basic';
|
|
56
|
-
import type { TemplateParams } from '@ogify/templates/basic';
|
|
57
|
-
|
|
58
|
-
const renderer = createRenderer<{ basic: TemplateParams }>({
|
|
59
|
-
templates: { basic: template },
|
|
60
|
-
sharedParams: {
|
|
61
|
-
brandLogo: 'https://ogify.dev/logo.svg',
|
|
62
|
-
brandName: 'OGify',
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 3. Generate an Image
|
|
68
|
-
|
|
69
|
-
Render the template to a PNG buffer:
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// Basic usage (1200x630)
|
|
73
|
-
const imageBuffer = await renderer.renderToImage('basic', {
|
|
74
|
-
title: 'Hello World',
|
|
75
|
-
subtitle: 'My first OG image',
|
|
76
|
-
layout: 'centered', // aligned | centered | split
|
|
77
|
-
cta: 'Read More',
|
|
78
|
-
primaryColor: '#000000',
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Custom dimensions for Twitter (1200x675)
|
|
82
|
-
const twitterImage = await renderer.renderToImage('basic', {
|
|
83
|
-
title: 'Hello World',
|
|
84
|
-
subtitle: 'My first OG image',
|
|
85
|
-
layout: 'split',
|
|
86
|
-
}, {
|
|
87
|
-
width: 1200,
|
|
88
|
-
height: 675
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// RTL Support (Arabic/Hebrew/Persian)
|
|
92
|
-
const rtlImage = await renderer.renderToImage('basic', {
|
|
93
|
-
title: 'مرحبا بالعالم',
|
|
94
|
-
subtitle: 'هذه أول صورة OG لي',
|
|
95
|
-
layout: 'aligned',
|
|
96
|
-
}, {
|
|
97
|
-
isRTL: true
|
|
98
|
-
});
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**That's it!** You're ready for production. No font files to download, no build configuration, no asset pipeline.
|
|
102
|
-
|
|
103
|
-
## 🚀 Time-Saving Features
|
|
104
|
-
|
|
105
|
-
### **Rich Templates**
|
|
106
|
-
|
|
107
|
-
Access a growing library of beautiful, production-ready templates. [Browse Templates](https://ogify.dev/templates)
|
|
108
|
-
|
|
109
|
-
**Time saved**: Hours of design and implementation time
|
|
110
|
-
|
|
111
|
-
### **Zero-Config Google Fonts**
|
|
112
|
-
|
|
113
|
-
Traditional approach (manual setup):
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
// ❌ Manual: Download fonts, manage files, configure paths
|
|
117
|
-
import fs from 'fs';
|
|
118
|
-
|
|
119
|
-
const fontData = fs.readFileSync('./fonts/Inter-Regular.ttf');
|
|
120
|
-
const font2Data = fs.readFileSync('./fonts/Inter-Bold.ttf');
|
|
121
|
-
|
|
122
|
-
const fonts = [
|
|
123
|
-
{ name: 'Inter', data: fontData, weight: 400 },
|
|
124
|
-
{ name: 'Inter', data: font2Data, weight: 700 }
|
|
125
|
-
];
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
OGify approach (zero-config):
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
// ✅ OGify: Just specify the font name - we handle the rest
|
|
132
|
-
const template = defineTemplate({
|
|
133
|
-
fonts: [
|
|
134
|
-
{ name: 'Inter', weight: 400 }, // Automatically loaded from Google Fonts
|
|
135
|
-
{ name: 'Inter', weight: 700 }
|
|
136
|
-
],
|
|
137
|
-
// ...
|
|
138
|
-
});
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Time saved**: ~15 minutes per font family
|
|
142
|
-
|
|
143
|
-
### **Automatic Caching**
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
// First render: Downloads fonts from Google (~500ms)
|
|
147
|
-
await renderer.renderToImage('basic', { title: 'Post 1', subtitle: '...' });
|
|
148
|
-
|
|
149
|
-
// Second render: Uses cached fonts (~50ms) - 10x faster! ⚡
|
|
150
|
-
await renderer.renderToImage('basic', { title: 'Post 2', subtitle: '...' });
|
|
151
|
-
|
|
152
|
-
// All subsequent renders: Lightning fast
|
|
153
|
-
await renderer.renderToImage('basic', { title: 'Post 3', subtitle: '...' });
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Performance**: 10x faster after first render, no configuration needed
|
|
157
|
-
|
|
158
|
-
### **Dynamic Emoji Loading**
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
// ✅ Emojis just work - loaded dynamically from CDN
|
|
162
|
-
renderer: ({ params }) => `
|
|
163
|
-
<div>
|
|
164
|
-
<h1>${params.title}</h1>
|
|
165
|
-
<div>👋 😄 🎉 🚀</div> <!-- Automatically rendered -->
|
|
166
|
-
</div>
|
|
167
|
-
`
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
**Time saved**: No emoji sprite sheets, no asset management, no build step
|
|
171
|
-
|
|
172
|
-
## 🛠️ Creating Custom Templates
|
|
173
|
-
|
|
174
|
-
If you want to build your own templates from scratch, you can use `defineTemplate`.
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
import { defineTemplate, OgTemplateOptions } from '@ogify/core';
|
|
178
|
-
|
|
179
|
-
const blogTemplate = defineTemplate({
|
|
180
|
-
fonts: [
|
|
181
|
-
{ name: 'Inter', weight: 400 },
|
|
182
|
-
{ name: 'Inter', weight: 700 }
|
|
183
|
-
],
|
|
184
|
-
renderer: ({ params }: OgTemplateOptions) => {
|
|
185
|
-
return `
|
|
186
|
-
<div style="display: flex; flex-direction: column; width: 100%; height: 100%; background: white; padding: 40px;">
|
|
187
|
-
<h1 style="font-size: 60px; font-weight: 700; color: #000;">
|
|
188
|
-
${params.title}
|
|
189
|
-
</h1>
|
|
190
|
-
<p style="font-size: 30px; color: #666;">
|
|
191
|
-
${params.description}
|
|
192
|
-
</p>
|
|
193
|
-
</div>
|
|
194
|
-
`;
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## 📚 Advanced Usage
|
|
200
|
-
|
|
201
|
-
### Custom Fonts
|
|
202
|
-
|
|
203
|
-
Load fonts from Google Fonts, custom URLs, or embedded data:
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
const template = defineTemplate({
|
|
207
|
-
fonts: [
|
|
208
|
-
// Google Fonts (automatic)
|
|
209
|
-
{ name: 'Roboto', weight: 400 },
|
|
210
|
-
|
|
211
|
-
// Custom URL
|
|
212
|
-
{ name: 'MyFont', url: 'https://example.com/font.woff2', weight: 700 },
|
|
213
|
-
|
|
214
|
-
// Embedded data
|
|
215
|
-
{ name: 'EmbeddedFont', data: fontBuffer, weight: 400 }
|
|
216
|
-
],
|
|
217
|
-
renderer: ({ params }) => `<div>${params.title}</div>`
|
|
218
|
-
});
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Emoji Support
|
|
222
|
-
|
|
223
|
-
Choose from multiple emoji providers:
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
const template = defineTemplate({
|
|
227
|
-
fonts: [{ name: 'Inter', weight: 400 }],
|
|
228
|
-
emojiProvider: 'twemoji', // 'fluent' | 'fluentFlat' | 'noto' | 'blobmoji' | 'openmoji'
|
|
229
|
-
renderer: ({ params }) => `
|
|
230
|
-
<div>
|
|
231
|
-
<h1>${params.title}</h1>
|
|
232
|
-
<div>👋 😄 🎉</div>
|
|
233
|
-
</div>
|
|
234
|
-
`
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Lifecycle Hooks
|
|
239
|
-
|
|
240
|
-
Add custom logic before and after rendering:
|
|
241
|
-
|
|
242
|
-
```typescript
|
|
243
|
-
const renderer = createRenderer({
|
|
244
|
-
templates: { 'blog-post': blogTemplate },
|
|
245
|
-
beforeRender: async (templateId, params) => {
|
|
246
|
-
console.log(`Rendering ${templateId}`, params);
|
|
247
|
-
// Log analytics, validate params, etc.
|
|
248
|
-
},
|
|
249
|
-
afterRender: async (templateId, params, imageBuffer) => {
|
|
250
|
-
console.log(`Rendered ${templateId} successfully`);
|
|
251
|
-
// Cache image, send notifications, etc.
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### Caching Configuration
|
|
257
|
-
|
|
258
|
-
Configure caching strategy for fonts and emojis/icons:
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
// Memory Cache (default)
|
|
262
|
-
const memoryRenderer = createRenderer({
|
|
263
|
-
templates: { 'blog-post': blogTemplate },
|
|
264
|
-
cache: {
|
|
265
|
-
type: 'memory',
|
|
266
|
-
ttl: 3600000, // 1 hour
|
|
267
|
-
max: 100 // max items
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// Filesystem Cache
|
|
272
|
-
const fsRenderer = createRenderer({
|
|
273
|
-
templates: { 'blog-post': blogTemplate },
|
|
274
|
-
cache: {
|
|
275
|
-
type: 'filesystem',
|
|
276
|
-
dir: './.ogify-cache', // cache directory
|
|
277
|
-
ttl: 3600000, // 1 hour
|
|
278
|
-
max: 100 // max items
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
### Platform-Specific Dimensions
|
|
284
|
-
|
|
285
|
-
Generate images for different platforms:
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
// Facebook/LinkedIn (1200x630)
|
|
289
|
-
const facebookImage = await renderer.renderToImage('basic', {
|
|
290
|
-
title: 'Hello World',
|
|
291
|
-
subtitle: 'My first OG image',
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
// Twitter (1200x675)
|
|
295
|
-
const twitterImage = await renderer.renderToImage('basic', {
|
|
296
|
-
title: 'Hello World',
|
|
297
|
-
subtitle: 'My first OG image',
|
|
298
|
-
}, {
|
|
299
|
-
width: 1200,
|
|
300
|
-
height: 675
|
|
301
|
-
});
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## 🎨 Template Features
|
|
305
|
-
|
|
306
|
-
### Supported CSS Properties
|
|
307
|
-
|
|
308
|
-
Templates support a subset of CSS properties via Satori. See [Satori CSS](https://github.com/vercel/satori?tab=readme-ov-file#css) for more details.
|
|
309
|
-
|
|
310
|
-
- **Layout**: `display: flex`, `flexDirection`, `alignItems`, `justifyContent`
|
|
311
|
-
- **Spacing**: `padding`, `margin`, `gap`
|
|
312
|
-
- **Typography**: `fontSize`, `fontWeight`, `color`, `lineHeight`, `textAlign`
|
|
313
|
-
- **Background**: `backgroundColor`, `backgroundImage`
|
|
314
|
-
- **Border**: `border`, `borderRadius`
|
|
315
|
-
- **Size**: `width`, `height`, `maxWidth`, `maxHeight`
|
|
316
|
-
- ...
|
|
317
|
-
|
|
318
|
-
### Tailwind-like Utilities
|
|
319
|
-
|
|
320
|
-
You can use Tailwind-like class names:
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
renderer: ({ params }) => `
|
|
324
|
-
<div class="flex flex-col items-center justify-center w-full h-full bg-white p-4">
|
|
325
|
-
<h1 class="text-[60px] font-bold text-black">${params.title}</h1>
|
|
326
|
-
<p class="text-[30px] text-gray-600">${params.description}</p>
|
|
327
|
-
</div>
|
|
328
|
-
`
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
## 📖 API Reference
|
|
332
|
-
|
|
333
|
-
### `defineTemplate(config)`
|
|
334
|
-
|
|
335
|
-
Defines a new OG template.
|
|
336
|
-
|
|
337
|
-
**Parameters:**
|
|
338
|
-
|
|
339
|
-
- `renderer` (function): Function that returns HTML string
|
|
340
|
-
- `fonts` (array): Array of font configurations
|
|
341
|
-
- `emojiProvider` (optional): Emoji provider to use
|
|
342
|
-
|
|
343
|
-
**Returns:** `OgTemplate`
|
|
344
|
-
|
|
345
|
-
### `createRenderer(config)`
|
|
346
|
-
|
|
347
|
-
Creates a new template renderer instance.
|
|
348
|
-
|
|
349
|
-
**Parameters:**
|
|
350
|
-
|
|
351
|
-
- `templates` (object): Map of template definitions keyed by ID
|
|
352
|
-
- `sharedParams` (optional): Default parameters for all templates
|
|
353
|
-
- `cache` (optional): Cache configuration object
|
|
354
|
-
- `beforeRender` (optional): Hook called before rendering
|
|
355
|
-
- `afterRender` (optional): Hook called after rendering
|
|
356
|
-
|
|
357
|
-
**Returns:** `TemplateRenderer`
|
|
358
|
-
|
|
359
|
-
### `renderer.renderToImage(templateId, params, options?)`
|
|
360
|
-
|
|
361
|
-
Renders a template to a PNG buffer.
|
|
362
|
-
|
|
363
|
-
**Parameters:**
|
|
364
|
-
|
|
365
|
-
- `templateId` (string): ID of the template to render
|
|
366
|
-
- `params` (object | function): Parameters (or function returning params) to pass to the template
|
|
367
|
-
- `options` (optional): Rendering options
|
|
368
|
-
- `width` (number): Image width (default: 1200)
|
|
369
|
-
- `height` (number): Image height (default: 630)
|
|
370
|
-
- `isRTL` (boolean): Enable Right-to-Left text direction (default: false)
|
|
371
|
-
|
|
372
|
-
**Returns:** `Promise<Buffer>`
|
|
373
|
-
|
|
374
|
-
### RTL Support
|
|
375
|
-
|
|
376
|
-
OGify supports Right-to-Left (RTL) languages via the `isRTL` option.
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
const image = await renderer.renderToImage('basic', {
|
|
380
|
-
title: 'مرحبا بالعالم', // Arabic: Hello World
|
|
381
|
-
subtitle: 'هذه أول صورة OG لي',
|
|
382
|
-
}, {
|
|
383
|
-
isRTL: true
|
|
384
|
-
});
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### `renderer.getTemplate(id)`
|
|
388
|
-
|
|
389
|
-
Retrieves a template by ID.
|
|
390
|
-
|
|
391
|
-
**Returns:** `OgTemplate | undefined`
|
|
392
|
-
|
|
393
|
-
## ⚡ Performance & Production
|
|
394
|
-
|
|
395
|
-
### **Automatic Caching (Zero Config)**
|
|
396
|
-
|
|
397
|
-
OGify automatically caches fonts, emojis, and generated images in memory - no configuration required
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
// First render: Downloads fonts from Google Fonts (~500ms)
|
|
401
|
-
await renderer.renderToImage('basic', { title: 'Post 1', subtitle: '...' });
|
|
402
|
-
|
|
403
|
-
// Second render: Uses cached fonts (~50ms) - 10x faster! ⚡
|
|
404
|
-
await renderer.renderToImage('basic', { title: 'Post 2', subtitle: '...' });
|
|
405
|
-
|
|
406
|
-
// Third+ renders: Lightning fast from cache
|
|
407
|
-
await renderer.renderToImage('basic', { title: 'Post 3', subtitle: '...' });
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
## 📋 Changelog
|
|
411
|
-
|
|
412
|
-
See [CHANGELOG.md](CHANGELOG.md) for a complete history of changes and releases.
|
|
22
|
+
- 🌐 **[Website](https://ogify.dev)** - Official website
|
|
23
|
+
- 🎨 **[Template Gallery](https://ogify.dev/templates)** - Browse all available templates
|
|
24
|
+
- 📖 **[Documentation](/docs/README.md)** - Complete guides and API reference
|
|
413
25
|
|
|
414
26
|
## 🤝 Contributing
|
|
415
27
|
|
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED