useSeoMeta na serwerze, obrazek generowany w useAsyncData.
Nuxt renderuje meta tagi po stronie serwera, więc wystarczy pobrać adres obrazka razem z treścią wpisu. Klucz trzymasz w runtimeConfig, do którego klient nie ma dostępu.
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>
Klucz wpisz do `runtimeConfig` bez prefiksu `public` — wszystko pod `public` ląduje w bundlu wysyłanym do przeglądarki.
Z ?wait=true czekasz na gotowy obrazek w tym samym połączeniu — zwykle około sekundy.
{
"id": "img_01m08s3ez1zcv28h335g9923bw",
"status": "completed",
"url": "https://cdn.imageapi.dev/renders/img_01m08s3ez1zcv28h335g9923bw.png",
"duration_ms": 912
}
Sto obrazków miesięcznie za darmo, potem $9 za dwa tysiące. Ten sam wpis wyrenderowany drugi raz zwraca istniejący adres i nie zużywa limitu — więc przebudowanie strony nic nie kosztuje.