Files
inkreach-official-website/apps/website/.agents/skills/nuxt-seo/references/og-image.md
T
yeuimu 6c61a4e871 feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma
  binaryTargets for openssl 3.0
- nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal
  cron, http->https redirect
- prisma: add origin_goods.delisted migration, sync missing schema
  (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz
- api: CORS wildcard reflection, helmet CORP cross-origin, price
  backfill in persistProductDetail, categoryIcon ancestor fallback,
  mediaByColor per-color gallery in public goods detail
- admin: /admin base path (vite + router)
- import-data.mjs: udt_name casting, serial sequence advance fix
2026-08-26 14:23:09 +08:00

3.4 KiB

OG Image Generation

Dynamic Open Graph image generation using Vue components.

Quick Start

// Component-first (recommended)
defineOgImage('NuxtSeo', { title: 'My Page Title' })

// Object syntax
defineOgImage({ component: 'NuxtSeo', title: 'My Page Title' })

// Disable OG image
defineOgImage(false)

Built-in Template

The NuxtSeo template supports:

defineOgImage('NuxtSeo', {
  title: 'Hello World',
  description: 'My description',
  theme: '#3b82f6',
  colorMode: 'dark',
  icon: 'carbon:cloud',
  siteName: 'My Site',
  siteLogo: '/logo.png'
})

Multiple Images Per Page

Use key for platform-specific images:

// Default OG image (1200x600)
defineOgImage('NuxtSeo', { title: 'Default' })

// Square for WhatsApp (800x800)
defineOgImage('NuxtSeo', {
  title: 'Square',
  key: 'square',
  width: 800,
  height: 800
})

Custom Vue Components

Create in components/OgImage/:

<!-- components/OgImage/Blog.vue -->
<script setup lang="ts">
defineProps<{ title: string; author: string }>()
</script>

<template>
  <div class="w-full h-full flex flex-col justify-center items-center bg-gradient-to-br from-blue-500 to-purple-600 p-12">
    <h1 class="text-6xl font-bold text-white text-center">{{ title }}</h1>
    <p class="text-2xl text-white/80 mt-4">By {{ author }}</p>
  </div>
</template>

Use in pages:

defineOgImage('OgImageBlog', { title: 'My Post', author: 'John' })

Renderers

Renderer Speed CSS Support Edge Best For
satori Fast Partial Default, most templates
chromium Slow Full Complex designs, prerender
export default defineNuxtConfig({
  ogImage: {
    defaults: { renderer: 'satori' }
  }
})

Satori Limitations

  • No display: grid - use flex
  • No position: absolute without explicit dimensions
  • Fonts: use @nuxt/fonts with global: true for best results

Configuration

export default defineNuxtConfig({
  ogImage: {
    defaults: {
      component: 'NuxtSeo',
      width: 1200,
      height: 600,
      cacheMaxAgeSeconds: 60 * 60 * 24 * 3  // 3 days
    },
    // For static sites
    zeroRuntime: true
  }
})

Nuxt Content

Frontmatter:

---
ogImage:
  component: OgImageBlog
  props:
    author: John Doe
---

With asSeoCollection() (see main SKILL.md):

<script setup>
const { data: page } = await useAsyncData(() => queryCollection('posts').path(route.path).first())
if (page.value?.ogImage)
  defineOgImage(page.value.ogImage)
</script>

Debug

  • Preview: /__og-image__/image/[path]/og.png
  • Inspector: Enable ogImage: { debug: true } in config

Screenshots

Capture page as OG image (requires Chromium):

defineOgImageScreenshot({
  colorScheme: 'dark',
  mask: '.navigation, .footer',
  selector: '.article-content'
})

Route Rules

export default defineNuxtConfig({
  routeRules: {
    '/blog/**': { ogImage: { component: 'OgImageBlog' } },
    '/admin/**': { ogImage: false }
  }
})

Deployment

Community templates are dev-only. Before deploying, eject:

npx nuxt-og-image eject NuxtSeo