fix(placeholder): rename SVG to bust Cloudflare cache

The new A-monogram placeholder shipped in d8ca8ff was correct in the
deployed container, but Cloudflare was serving the previous cached SVG
(cf-cache-status: HIT, last-modified from this morning) because the
account token doesn't carry Zone:Cache Purge scope, so we couldn't
issue an API purge.

Renaming the file to article-placeholder-v2.svg gives CF a fresh URL
to cache, sidestepping the missing-permission entirely. Updated all
6 referencing files (AppImage fallback, legacy-source FALLBACK_IMAGE
constants, FeaturedBento[FromDb], manufacturers/authors pages).

Old file (cached as the old wordmark) just becomes a dangling asset —
not referenced from anywhere, harmless.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 21:44:20 +00:00
parent d8ca8ff3ec
commit 761ebf0cdc
7 changed files with 18 additions and 18 deletions

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -89,7 +89,7 @@ export default function AuthorProfilePage() {
excerpt: a.excerpt || "", excerpt: a.excerpt || "",
category: a.category || "News", category: a.category || "News",
date: a.date || "", date: a.date || "",
image: a.image || "/assets/images/article-placeholder.svg", image: a.image || "/assets/images/article-placeholder-v2.svg",
alt: a.alt || a.title, alt: a.alt || a.title,
readTime: a.readTime || "1 min read", readTime: a.readTime || "1 min read",
})); }));
@@ -275,7 +275,7 @@ export default function AuthorProfilePage() {
> >
<div className="img-zoom h-44 overflow-hidden"> <div className="img-zoom h-44 overflow-hidden">
<AppImage <AppImage
src={article.image || "/assets/images/article-placeholder.svg"} src={article.image || "/assets/images/article-placeholder-v2.svg"}
alt={article.alt} alt={article.alt}
width={400} width={400}
height={176} height={176}

View File

@@ -47,77 +47,77 @@ const rotatingStories = [
{ {
title: "Telestream Expands Its Cloud Services with the Introduction of UP", title: "Telestream Expands Its Cloud Services with the Introduction of UP",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Cloud services infrastructure for broadcast production environments", alt: "Cloud services infrastructure for broadcast production environments",
slug: "telestream-expands-cloud-services-up", slug: "telestream-expands-cloud-services-up",
}, },
{ {
title: "Operative Launches AOS Configuration for Digital-First Monetization", title: "Operative Launches AOS Configuration for Digital-First Monetization",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Digital monetization analytics dashboard for broadcast advertising", alt: "Digital monetization analytics dashboard for broadcast advertising",
slug: "operative-launches-aos-configuration", slug: "operative-launches-aos-configuration",
}, },
{ {
title: "Calrec Redefines Broadcast Workflows at NAB 2026 with its Most Powerful Audio Lineup Yet", title: "Calrec Redefines Broadcast Workflows at NAB 2026 with its Most Powerful Audio Lineup Yet",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Calrec audio mixing console for broadcast production at NAB 2026", alt: "Calrec audio mixing console for broadcast production at NAB 2026",
slug: "calrec-redefines-broadcast-workflows-nab-2026", slug: "calrec-redefines-broadcast-workflows-nab-2026",
}, },
{ {
title: "Ease Live Powers Interactive Premier Padel Experiences on Red Bull TV as Viewership Surges 30%", title: "Ease Live Powers Interactive Premier Padel Experiences on Red Bull TV as Viewership Surges 30%",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Interactive sports broadcast experience on streaming platform", alt: "Interactive sports broadcast experience on streaming platform",
slug: "ease-live-premier-padel-red-bull-tv", slug: "ease-live-premier-padel-red-bull-tv",
}, },
{ {
title: "From Metadata to Meaning: Why Semantic Intelligence Is Media\'s Next Competitive Advantage", title: "From Metadata to Meaning: Why Semantic Intelligence Is Media\'s Next Competitive Advantage",
category: "FEATURED", category: "FEATURED",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Media metadata intelligence and content analytics visualization", alt: "Media metadata intelligence and content analytics visualization",
slug: "from-metadata-to-meaning-semantic-intelligence", slug: "from-metadata-to-meaning-semantic-intelligence",
}, },
{ {
title: "Mediagenix Title Management Accelerates Content Monetization Through Advanced Semantic Intelligence", title: "Mediagenix Title Management Accelerates Content Monetization Through Advanced Semantic Intelligence",
category: "POST PRODUCTION", category: "POST PRODUCTION",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Content management system for media title management and monetization", alt: "Content management system for media title management and monetization",
slug: "mediagenix-title-management", slug: "mediagenix-title-management",
}, },
{ {
title: "Emergent Launches Fusion: The \'Interactive Anything\' Platform Transforming Data-Driven Storytelling", title: "Emergent Launches Fusion: The \'Interactive Anything\' Platform Transforming Data-Driven Storytelling",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Interactive data storytelling platform for broadcast and enterprise use", alt: "Interactive data storytelling platform for broadcast and enterprise use",
slug: "emergent-launches-fusion-platform", slug: "emergent-launches-fusion-platform",
}, },
{ {
title: "Matrox Video Enables the Next Era of Software-Defined Media Production at NAB 2026", title: "Matrox Video Enables the Next Era of Software-Defined Media Production at NAB 2026",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Matrox video production hardware and software at NAB 2026 exhibition", alt: "Matrox video production hardware and software at NAB 2026 exhibition",
slug: "matrox-video-software-defined-nab-2026", slug: "matrox-video-software-defined-nab-2026",
}, },
{ {
title: "Video is King: 2026 Iconik Media Stats Report Finds Video Consumes 64% of Storage Needs", title: "Video is King: 2026 Iconik Media Stats Report Finds Video Consumes 64% of Storage Needs",
category: "FEATURED", category: "FEATURED",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Video storage statistics and media asset management data visualization", alt: "Video storage statistics and media asset management data visualization",
slug: "video-is-king-2026-iconik-media-stats", slug: "video-is-king-2026-iconik-media-stats",
}, },
{ {
title: "QuickLink\'s Latest StudioEdge Models to Make North American Debut at NAB 2026", title: "QuickLink\'s Latest StudioEdge Models to Make North American Debut at NAB 2026",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "QuickLink StudioEdge broadcast production equipment at NAB exhibition", alt: "QuickLink StudioEdge broadcast production equipment at NAB exhibition",
slug: "quicklink-studioedge-nab-2026", slug: "quicklink-studioedge-nab-2026",
}, },
{ {
title: "Utah Scientific Expands Technology Partner Program With Integrations From Audinate, Bitfocus, and Skaarhoj", title: "Utah Scientific Expands Technology Partner Program With Integrations From Audinate, Bitfocus, and Skaarhoj",
category: "BROADCAST", category: "BROADCAST",
image: "/assets/images/article-placeholder.svg", image: "/assets/images/article-placeholder-v2.svg",
alt: "Broadcast routing and control system technology partner integration", alt: "Broadcast routing and control system technology partner integration",
slug: "utah-scientific-partner-program", slug: "utah-scientific-partner-program",
}, },

View File

@@ -417,7 +417,7 @@ export default async function ManufacturerProfile({
article featured_image → company logo → static placeholder. */} article featured_image → company logo → static placeholder. */}
{/* eslint-disable-next-line @next/next/no-img-element */} {/* eslint-disable-next-line @next/next/no-img-element */}
<img <img
src={r.featured_image || company.logo_url || '/assets/images/article-placeholder.svg'} src={r.featured_image || company.logo_url || '/assets/images/article-placeholder-v2.svg'}
alt="" alt=""
className="w-20 h-14 rounded object-cover bg-[#FFFFFF] flex-shrink-0" className="w-20 h-14 rounded object-cover bg-[#FFFFFF] flex-shrink-0"
loading="lazy" loading="lazy"

View File

@@ -63,7 +63,7 @@ export default async function FeaturedBento() {
const heroAd = pickAds("300x600", 1)[0] || null; const heroAd = pickAds("300x600", 1)[0] || null;
function img(r: Row): string { function img(r: Row): string {
return r.featured_image ? rewriteLegacyImageUrl(r.featured_image) : "/assets/images/article-placeholder.svg"; return r.featured_image ? rewriteLegacyImageUrl(r.featured_image) : "/assets/images/article-placeholder-v2.svg";
} }
return ( return (

View File

@@ -35,7 +35,7 @@ const AppImage = memo(function AppImage({
fill = false, fill = false,
sizes, sizes,
onClick, onClick,
fallbackSrc = '/assets/images/article-placeholder.svg', fallbackSrc = '/assets/images/article-placeholder-v2.svg',
loading = 'lazy', loading = 'lazy',
unoptimized = false, unoptimized = false,
...props ...props

View File

@@ -49,8 +49,8 @@ interface PersonaJoin {
avatar_url: string | null; avatar_url: string | null;
} }
const FALLBACK_IMAGE = "/assets/images/article-placeholder.svg"; const FALLBACK_IMAGE = "/assets/images/article-placeholder-v2.svg";
const REWRITE_FALLBACK_IMAGE = "/assets/images/article-placeholder.svg"; const REWRITE_FALLBACK_IMAGE = "/assets/images/article-placeholder-v2.svg";
type Section = Article["section"]; type Section = Article["section"];
const SECTION_TAGS: Record<Section, string[]> = { const SECTION_TAGS: Record<Section, string[]> = {