Skip to content

Commit 053c5e8

Browse files
authored
fix: replacing .png inside the component params (#493)
1 parent 3941248 commit 053c5e8

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

src/runtime/server/og-image/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export async function resolveContext(e: H3Event): Promise<H3Error | OgImageRende
5757
// Parse encoded params from URL path (Cloudinary-style)
5858
// URL format: /_og/d/w_1200,title_Hello.png
5959
// Hash mode: /_og/d/o_<hash>.png (for long URLs)
60-
const encodedSegment = (path.split('/').pop() as string).replace(`.${extension}`, '')
60+
const encodedSegment = (path.split('/').pop() as string).replace(new RegExp(`\\.${extension}$`), '')
6161

6262
// Check for hash mode (o_<hash>)
6363
const hashMatch = encodedSegment.match(/^o_([a-z0-9]+)$/i)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { createResolver } from '@nuxt/kit'
2+
import { $fetch, setup } from '@nuxt/test-utils/e2e'
3+
import { describe, expect, it } from 'vitest'
4+
import { encodeOgImageParams } from '../../src/runtime/shared/urlEncoding'
5+
6+
const { resolve } = createResolver(import.meta.url)
7+
8+
describe.skipIf(!import.meta.env?.TEST_DEV)('prop values containing file extensions', async () => {
9+
await setup({
10+
rootDir: resolve('../fixtures/basic'),
11+
dev: true,
12+
})
13+
14+
// Regression: context.ts used String.replace(`.${extension}`, '') which replaces
15+
// the FIRST occurrence. When a prop value contains the same extension as the
16+
// output format AND there are other params after it, the extension inside the
17+
// prop gets stripped instead of the trailing one.
18+
it('preserves .html in prop value when output format is also .html', async () => {
19+
const encoded = encodeOgImageParams({
20+
component: 'PropTest.satori',
21+
props: { logo: 'https://example.com/page.html', title: 'test' },
22+
_path: '/satori',
23+
})
24+
const html = await $fetch(`/_og/d/${encoded}.html`) as string
25+
expect(html).toContain('https://example.com/page.html')
26+
}, 60000)
27+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
withDefaults(defineProps<{
3+
logo?: string
4+
}>(), {
5+
logo: '',
6+
})
7+
</script>
8+
9+
<template>
10+
<div class="w-full h-full flex items-center justify-center bg-white">
11+
<p class="text-2xl">
12+
{{ logo }}
13+
</p>
14+
</div>
15+
</template>

0 commit comments

Comments
 (0)