mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
vercel.json currently allow-lists SVG-only hosts (img.shields.io, shields.io, badgen.net, flat.badgen.net) while dangerouslyAllowSVG: false rejects every SVG source. Those two settings are incompatible, and every badge in every README on production is returning 400 INVALID_IMAGE_OPTIMIZE_REQUEST (e.g. the license badge on /plugins/@opik/opik-openclaw). Switch to the pattern Vercel documents for safely serving SVGs in their NEXTJS_SAFE_SVG_IMAGES conformance rule: - dangerouslyAllowSVG: true — lets the optimizer accept SVG inputs - contentDispositionType: attachment — forces download instead of inline document rendering if someone navigates directly to the /_vercel/image URL (the only context where SVG scripts would run) - contentSecurityPolicy: script-src 'none'; sandbox; — blocks script execution in the response Defense in depth: browsers already sandbox SVGs loaded through <img> so scripts don't run there anyway; the CSP + attachment header cover the edge case of someone opening the optimizer URL directly. Net security is equivalent to rejecting SVGs, but badges actually render. Docs: https://vercel.com/docs/conformance/rules/NEXTJS_SAFE_SVG_IMAGES Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
61 lines
1.9 KiB
JSON
61 lines
1.9 KiB
JSON
{
|
|
"redirects": [
|
|
{
|
|
"source": "/",
|
|
"has": [
|
|
{
|
|
"type": "header",
|
|
"key": "host",
|
|
"value": "mirror-cn.clawhub.com"
|
|
}
|
|
],
|
|
"destination": "https://cn.clawhub-mirror.com/",
|
|
"statusCode": 302
|
|
},
|
|
{
|
|
"source": "/:path*",
|
|
"has": [
|
|
{
|
|
"type": "header",
|
|
"key": "host",
|
|
"value": "mirror-cn.clawhub.com"
|
|
}
|
|
],
|
|
"destination": "https://cn.clawhub-mirror.com/:path*",
|
|
"statusCode": 302
|
|
}
|
|
],
|
|
"rewrites": [
|
|
{
|
|
"source": "/api/:path*",
|
|
"destination": "https://wry-manatee-359.convex.site/api/:path*"
|
|
}
|
|
],
|
|
"images": {
|
|
"sizes": [256, 640, 1024, 1920],
|
|
"formats": ["image/webp"],
|
|
"minimumCacheTTL": 86400,
|
|
"dangerouslyAllowSVG": true,
|
|
"contentDispositionType": "attachment",
|
|
"contentSecurityPolicy": "default-src 'self'; script-src 'none'; sandbox;",
|
|
"remotePatterns": [
|
|
{ "protocol": "https", "hostname": "raw.githubusercontent.com" },
|
|
{ "protocol": "https", "hostname": "user-images.githubusercontent.com" },
|
|
{ "protocol": "https", "hostname": "avatars.githubusercontent.com" },
|
|
{ "protocol": "https", "hostname": "camo.githubusercontent.com" },
|
|
{ "protocol": "https", "hostname": "github.com" },
|
|
{ "protocol": "https", "hostname": "raw.github.com" },
|
|
{ "protocol": "https", "hostname": "img.shields.io" },
|
|
{ "protocol": "https", "hostname": "shields.io" },
|
|
{ "protocol": "https", "hostname": "cdn.jsdelivr.net" },
|
|
{ "protocol": "https", "hostname": "i.imgur.com" },
|
|
{ "protocol": "https", "hostname": "codecov.io" },
|
|
{ "protocol": "https", "hostname": "coveralls.io" },
|
|
{ "protocol": "https", "hostname": "codefactor.io" },
|
|
{ "protocol": "https", "hostname": "badgen.net" },
|
|
{ "protocol": "https", "hostname": "flat.badgen.net" },
|
|
{ "protocol": "https", "hostname": "gitlab.com" }
|
|
]
|
|
}
|
|
}
|