Skip to content

Commit a7dc645

Browse files
Adebesin-Cellclaude
andcommitted
fix(brand): download correct PNG variant and remove hydration gap
- Fix on-light PNG downloading the on-dark asset (handler always used logo.src) - Fix Customize PNG export blocked by CSP — use data URL instead of blob URL - Render BrandCustomize in SSR (remove ClientOnly); canvas/download only runs on click Closes #2565 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 13ac6c2 commit a7dc645

2 files changed

Lines changed: 13 additions & 16 deletions

File tree

app/components/Brand/Customize.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ async function downloadCustomPng() {
7575
if (!svg) return
7676
pngLoading.value = true
7777
78-
const blob = new Blob([svg], { type: 'image/svg+xml' })
79-
const url = URL.createObjectURL(blob)
78+
const url = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`
8079
8180
try {
8281
await document.fonts.ready
@@ -108,7 +107,6 @@ async function downloadCustomPng() {
108107
}, 'image/png')
109108
})
110109
} finally {
111-
URL.revokeObjectURL(url)
112110
pngLoading.value = false
113111
}
114112
}

app/pages/brand.vue

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,16 @@ function handleSvgDownload(src: string) {
5757
}
5858
}
5959
60-
async function handlePngDownload(logo: (typeof logos)[number]) {
61-
if (pngLoading.value.has(logo.src)) return
62-
pngLoading.value.add(logo.src)
60+
async function handlePngDownload(logo: (typeof logos)[number], variant: 'dark' | 'light' = 'dark') {
61+
const src = variant === 'light' ? (logo.srcLight ?? logo.src) : logo.src
62+
if (pngLoading.value.has(src)) return
63+
pngLoading.value.add(src)
6364
try {
64-
const blob = await svgToPng(logo.src, logo.width, logo.height)
65-
const filename = logo.src.replace(/^\//, '').replace('.svg', '.png')
65+
const blob = await svgToPng(src, logo.width, logo.height)
66+
const filename = src.replace(/^\//, '').replace('.svg', '.png')
6667
downloadFile(blob, filename)
6768
} finally {
68-
pngLoading.value.delete(logo.src)
69+
pngLoading.value.delete(src)
6970
}
7071
}
7172
</script>
@@ -224,14 +225,14 @@ async function handlePngDownload(logo: (typeof logos)[number]) {
224225
name: `${logo.name()} (${$t('brand.logos.on_light')})`,
225226
})
226227
"
227-
:disabled="pngLoading.has(logo.src)"
228-
@click="handlePngDownload(logo)"
228+
:disabled="pngLoading.has(logo.srcLight ?? logo.src)"
229+
@click="handlePngDownload(logo, 'light')"
229230
>
230231
<span
231232
class="size-[1em]"
232233
aria-hidden="true"
233234
:class="
234-
pngLoading.has(logo.src)
235+
pngLoading.has(logo.srcLight ?? logo.src)
235236
? 'i-lucide:loader-circle animate-spin'
236237
: 'i-lucide:download'
237238
"
@@ -246,10 +247,8 @@ async function handlePngDownload(logo: (typeof logos)[number]) {
246247
</div>
247248
</section>
248249

249-
<!-- Customize Section (client-only: needs DOM for accent colors + canvas export) -->
250-
<ClientOnly>
251-
<BrandCustomize />
252-
</ClientOnly>
250+
<!-- Customize Section -->
251+
<BrandCustomize />
253252

254253
<!-- Typography Section -->
255254
<section aria-labelledby="brand-typography-heading">

0 commit comments

Comments
 (0)