Embedding OG Images · Nuxt OG Image · Nuxt SEO

-
-
-
-

[1.4K](https://github.com/harlan-zw/nuxt-seo)

[Nuxt SEO on GitHub](https://github.com/harlan-zw/nuxt-seo)

**OG Image v6** is here! Looking for an older version?

.

OG Image

-
-
-
-
-
-
-
-
-
-

Search…```k`` /`

v6 (latest)

- Playgrounds
- [Discord Support](https://discord.com/invite/275MBUBvgP)

### Getting Started

-
-
-
-

### Core Concepts

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

### Overview

-
-
-
-

### Integrations

-
-
-

Core Concepts

# Embedding OG Images

[Copy for LLMs](https://nuxtseo.com/docs/og-image/guides/resolve-og-images.md)

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

```
<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](#using-the-current-pages-url)

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

```
<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

 for details.

## [Selecting `twitter:image`](#selecting-twitterimage)

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

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

## [Dynamic Pages](#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:

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

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

## [Image Extension Suffix](#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:

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

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

## [Caching](#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

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

## [Security](#security)

The resolver respects the same settings as the image handlers. See the

 for configuration.

| Protection | Behaviour |
| --- | --- |
| `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()`.

[Edit this page](https://github.com/nuxt-modules/og-image/edit/main/docs/content/3.guides/4.resolve-og-images.md)

[Markdown For LLMs](https://nuxtseo.com/docs/og-image/guides/resolve-og-images.md)

Did this page help you?

On this page

- [Using The Current Page's URL](#using-the-current-pages-url)
- [Selecting twitter:image](#selecting-twitterimage)
- [Dynamic Pages](#dynamic-pages)
- [Image Extension Suffix](#image-extension-suffix)
- [Caching](#caching)
- [Security](#security)

[GitHub](https://github.com/harlan-zw/nuxt-seo) [ Discord](https://discord.com/invite/275MBUBvgP)

###

-
-

Modules

-
-
-
-
-
-
-
-
-

###

-
-
-

###

Nuxt

-
-
-
-
-

Vue

-
-
-
-
-
-
-
-

###

-
-
-
-
-
-
-
-
-
-

Copyright © 2023-2026 Harlan Wilton - [MIT License](https://github.com/harlan-zw/nuxt-seo/blob/main/license) · [mdream](https://mdream.dev)