Nuxt

OG images in
Nuxt

useSeoMeta on the server, image fetched inside useAsyncData.

Where it plugs in

Nuxt renders meta tags server-side, so you can fetch the image URL alongside the post itself. The key stays in runtimeConfig, which the client never sees.

pages/blog/[slug].vue

<script setup lang="ts">
const route = useRoute();
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`);

// $fetch runs on the server - the key stays inside runtimeConfig.
const { data: og } = await useAsyncData(`og-${route.params.slug}`, () =>
  $fetch('https://imageapi.dev/v1/images?wait=true', {
    method: 'POST',
    headers: { Authorization: `Bearer ${useRuntimeConfig().imageApiKey}` },
    body: {
      template: 'blog-og',
      modifications: {
        title: post.value.title,
        author: post.value.author,
        site: 'yourblog.com',
      },
    },
  }),
);

useSeoMeta({
  title: () => post.value.title,
  ogImage: () => og.value?.url,
  twitterCard: 'summary_large_image',
});
</script>
The trap

Put the key in `runtimeConfig` WITHOUT the `public` prefix — anything under `public` is bundled and shipped to the browser.

What comes back

With ?wait=true the finished image arrives on the same connection — usually in about a second.

{
    "id": "img_01m08s3ez1zcv28h335g9923bw",
    "status": "completed",
    "url": "https://cdn.imageapi.dev/renders/img_01m08s3ez1zcv28h335g9923bw.png",
    "duration_ms": 912
}

What it costs

A hundred images a month free, then $9 for two thousand. The same post rendered twice returns the existing URL and uses no quota — so rebuilding your site costs nothing.

Other frameworks