---
title: "Embedding OG Images · Nuxt OG Image · Nuxt SEO"
canonical_url: "https://nuxtseo.com/docs/og-image/guides/resolve-og-images"
last_updated: "2026-08-16T09:55:34.184Z"
meta:
  description: "Render another page's OG image in an <img> tag without reconstructing its URL."
  "og:description": "Render another page's OG image in an <img> tag without reconstructing its URL."
  "og:title": "Embedding OG Images · Nuxt OG Image · Nuxt SEO"
---

Nuxt SEO on GitHub

**OG Image v6** is here. Looking for an older version? [~~View v5 docs ~~](https://nuxtseo.com/docs/og-image/v5/getting-started/introduction).

](https://nuxtseo.com/docs/og-image/getting-started/introduction)

](https://nuxtseo.com/docs/og-image/api/define-og-image)

](https://nuxtseo.com/docs/og-image/releases/v6)

Switch to OG Image](https://nuxtseo.com/docs/og-image/getting-started/introduction)Switch to Nuxt SEO](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)Switch to Robots](https://nuxtseo.com/docs/robots/getting-started/introduction)Switch to Sitemap](https://nuxtseo.com/docs/sitemap/getting-started/introduction)Switch to Schema.org](https://nuxtseo.com/docs/schema-org/getting-started/introduction)Switch to Link Checker](https://nuxtseo.com/docs/link-checker/getting-started/introduction)Switch to SEO Utils](https://nuxtseo.com/docs/seo-utils/getting-started/introduction)Switch to Site Config](https://nuxtseo.com/docs/site-config/getting-started/introduction)Switch to Skew Protection](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)Switch to AI Ready](https://nuxtseo.com/docs/ai-ready/getting-started/introduction)

**Core Concepts**

# **Embedding OG Images**

The generated URL for an OG image depends on the options passed to `**defineOgImage()**`, including the component hash and any props. These URLs change when you edit a template, so hardcoding them in a blog index or listing page breaks on every deploy.

The `**/_og/r/**` endpoint solves this. Point it at any page path and it fetches the page, reads the `**og:image**` meta tag, and redirects (302) to the current image URL.

pages/blog/index.vue

```vue
<template>
  <article v-for="post in posts" :key="post.path">
    <NuxtLink :to="post.path">
      <img :src="`/_og/r${post.path}`" :alt="post.title">
      <h3>{{ post.title }}</h3>
    </NuxtLink>
  </article>
</template>
```

Browsers follow the 302 transparently, so the image renders exactly as it would on the original page.

## Using The Current Page's URL

If you're showing the OG image on the same page that declares it, skip the resolver entirely. `**defineOgImage()**` returns the generated URLs:

```vue
<script lang="ts" setup>
const [ogImageUrl] = defineOgImage('NuxtSeo', { title: 'Hello' })
</script>

<template>
  <img :src="ogImageUrl" alt="Preview">
</template>
```

The return type is `**string[]**` with one URL per variant. See [`**defineOgImage()**`](https://nuxtseo.com/docs/og-image/api/define-og-image) for details.

## Selecting `**twitter:image**`

By default the resolver follows `**og:image**`. Pass `**_og_key=twitter**` to follow `**twitter:image**` instead:

```html
<img src="/_og/r/blog/hello-world?_og_key=twitter">
```

## Dynamic Pages

Query parameters on the resolver URL (other than `**_og_***`) are forwarded to the target page fetch, so dynamic routes render against the right props:

```html
<img src="/_og/r/products?id=42">
```

This fetches `**/products?id=42**`, then redirects to whatever `**og:image**` that page produced.

## Image Extension Suffix

Some tools refuse to treat a URL as an image unless it ends in an image extension. The resolver strips a trailing `**.png**`, `**.jpg**`, `**.jpeg**`, `**.webp**`, or `**.svg**` before resolving:

```html
<img src="/_og/r/blog/hello-world.png">
```

The extension is cosmetic. The redirect target is whatever the page declares.

## Caching

The resolver emits `**Cache-Control: public, max-age=<ttl>, s-maxage=<ttl>, immutable**` using your module's `**cacheMaxAgeSeconds**`, so CDNs cache the redirect without revalidation for the configured TTL.

To override the default, set your own headers via route rules:

nuxt.config.ts

```ts
export default defineNuxtConfig({
  routeRules: {
    '/_og/r/**': { headers: { 'cache-control': 'public, max-age=3600' } }
  }
})
```

## Security

The resolver respects the same settings as the image handlers. See the [**~~security guide~~**](https://nuxtseo.com/docs/og-image/guides/security) for configuration.

| **Protection** | **Behavior** |
| --- | --- |
| `**security.restrictRuntimeImagesToOrigin**` | Blocks requests from unknown hosts |
| `**security.maxQueryParamSize**` | Caps the forwarded query string |
| Internal route guard | Rejects paths starting with `**/_**` |
| Scheme and protocol-relative guard | Rejects `**//evil.com**` and `**http://**` paths |
| Path length cap | Rejects paths over 2048 characters |

The redirect target is whatever the page's own `**og:image**` declares. The resolver does not validate the destination, so its trust boundary is the set of pages on your site that call `**defineOgImage()**` or set `**og:image**` via `**useSeoMeta()**`.

**Was this page helpful?**

### **Related **

[**defineOgImage()**](https://nuxtseo.com/docs/og-image/api/define-og-image)

[**Security**](https://nuxtseo.com/docs/og-image/guides/security)

[**Route Rules**](https://nuxtseo.com/docs/og-image/guides/route-rules)

[**Route Rules** Learn how to use route rules to customize your OG Image.](https://nuxtseo.com/docs/og-image/guides/route-rules) [**Custom Fonts** Using custom fonts in your OG Images.](https://nuxtseo.com/docs/og-image/guides/custom-fonts)