cloudflare / cloudflare/vinext

Metadata: og:image / twitter:image URLs are not percent-encoded

Open Beginner friendly
#3,066 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
8.8k
Forks
406
Avg merge
2d 6h
Merged PRs (30d)
120

Description

### What happened

vinext emits `og:image` / `twitter:image` URLs without percent-encoding, where Next.js encodes them. A URL containing a space is passed through verbatim.

```
Next.js 16.3.2
https://file.devfive.kr/file/2025_06_10/1749539238715_1732690349249_1728972833495_image%2016.webp

vinext
https://file.devfive.kr/file/2025_06_10/1749539238715_1732690349249_1728972833495_image 16.webp
```

Note `image%2016.webp` vs `image 16.webp`.

### Reproduction

Return a metadata image whose URL contains a character that must be percent-encoded:

```ts
export async function generateMetadata(): Promise {
return {
openGraph: {
images: ['https://example.com/path/my image.webp'],
},
}
}
```

- Next.js renders `content="https://example.com/path/my%20image.webp"`.
- vinext renders `content="https://example.com/path/my image.webp"`.

In our case the URL comes from a CMS field, so we do not control whether it contains spaces.

### Impact

A raw space inside a `content` URL is not a valid URI. Crawlers and preview generators (Open Graph consumers, chat clients) may fail to fetch the image, so link previews can silently break. Affected 2 of 25 captured URLs in our app — only those whose CMS image name contains a space.

### Expected

Match Next.js and normalize metadata image URLs (e.g. via `new URL(...).href` or equivalent encoding) before writing them into `og:image` / `twitter:image`.

### Environment

- vinext 1.0.0-beta.8, Vite 8.2.2
- Next.js 16.3.2 API surface, App Router, `generateMetadata`
- `--platform=node`, `output: 'standalone'`

Found by a golden-master diff of SSR HTML between the two runtimes on the same source and same API fixtures.

Contributor guide

Open the contributing guide

Research direction

Start at the metadata handling used by generateMetadata, focusing on how openGraph.images values become og:image and twitter:image content attributes. Reproduce the example with a space in the image URL, then verify the rendered URLs use percent-encoding and match the Next.js output.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.