From 02b69f22528ce7db9c22689db9595c490dddead5 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Thu, 14 May 2026 16:53:42 +0000 Subject: [PATCH] P0-2 + Phase A: drop Adsanity iframes, fix SEO baseline, noindex while staging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P0-2 (Adsanity iframe path removed): - AdImage.tsx: deleted the iframe branch and the ADSANITY_CAMPAIGN_MAP fallback. AdImage now renders local images only; banners without a src render nothing. - ads.ts: removed Ad.adsanity_id from the interface. Pruned AJA, Zixi, Lectrosonics, Opengear, Studio Hero, Magewell 300x250 and Blackmagic 300x600 — they relied on ads.broadcastbeat.com which does not resolve. Surviving live banners: LiveU 728x90, LiveU PAYG 300x250, Telycam 300x250. - SidebarAdStack: key no longer references the removed field. - No banner_analytics rows reference ads.broadcastbeat.com. Phase A (SEO baseline): - robots.ts: fallback base URL now broadcastbeat.com (was rocket staging URL). - sitemap.ts: fallback base URL now broadcastbeat.com (was bb-staging). - news/[slug]/page.tsx and articles/[slug]/page.tsx: same fallback fix. JSON-LD now uses ISO 8601 for datePublished, absolute image URL via SITE_URL prefix, and publisher.logo points at /assets/images/logo.png instead of the 404-ing /legacy/site/broadcastbeat-logo.png. - layout.tsx: removed the /en /es /pt /fr /de /zh /ja /ar /hi hreflang alternates - those routes 404 today; Phase D will reinstate. Replaced rocket.new Organization schema URL with broadcastbeat.com. Set robots index/follow=false until Phase B-D land and Rich Results passes. Featured-image fallback hardening: - legacy-source: rowToArticle now treats BB_Gray, no_image and placeholder URLs as null and falls back to the new placeholder so dead images do not leak through to the page. - public/assets/images/article-placeholder.svg: new clean dark gradient with BroadcastBeat wordmark, NOT no_image.png style. Co-Authored-By: Claude Opus 4.7 (1M context) --- public/assets/images/article-placeholder.svg | 20 +++++++ src/app/articles/[slug]/page.tsx | 21 ++++++-- src/app/layout.tsx | 42 +++++---------- src/app/news/[slug]/page.tsx | 22 ++++++-- src/app/robots.ts | 2 +- src/app/sitemap.ts | 2 +- src/components/AdImage.tsx | 41 +++++++------- src/components/SidebarAdStack.tsx | 2 +- src/lib/ads.ts | 57 +++++--------------- src/lib/articles/legacy-source.ts | 13 +++-- 10 files changed, 114 insertions(+), 108 deletions(-) create mode 100644 public/assets/images/article-placeholder.svg diff --git a/public/assets/images/article-placeholder.svg b/public/assets/images/article-placeholder.svg new file mode 100644 index 0000000..b08f131 --- /dev/null +++ b/public/assets/images/article-placeholder.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + BROADCAST + BEAT + NEWS · INTELLIGENCE · TECHNOLOGY + + diff --git a/src/app/articles/[slug]/page.tsx b/src/app/articles/[slug]/page.tsx index c3a5460..8c3c589 100644 --- a/src/app/articles/[slug]/page.tsx +++ b/src/app/articles/[slug]/page.tsx @@ -16,7 +16,19 @@ interface PageProps { } const SITE_URL = - process.env.NEXT_PUBLIC_SITE_URL || "https://bb-staging.onsethost.com"; + process.env.NEXT_PUBLIC_SITE_URL || "https://broadcastbeat.com"; + +function toIso(d: string | null | undefined): string { + if (!d) return new Date().toISOString(); + const parsed = new Date(d); + return isNaN(parsed.getTime()) ? new Date().toISOString() : parsed.toISOString(); +} + +function absoluteImage(src: string | undefined | null): string { + if (!src) return `${SITE_URL}/assets/images/article-placeholder.jpg`; + if (/^https?:\/\//i.test(src)) return src; + return `${SITE_URL}${src.startsWith("/") ? "" : "/"}${src}`; +} async function loadArticle(slug: string): Promise<{ article: Article | null; @@ -77,15 +89,16 @@ export default async function ArticlePage({ params }: PageProps) { "@type": "Article", headline: article.title, description: article.excerpt, - image: article.image, + image: [absoluteImage(article.image)], author: { "@type": "Person", name: article.author }, publisher: { "@type": "Organization", name: "BroadcastBeat", - logo: { "@type": "ImageObject", url: `${SITE_URL}/legacy/site/broadcastbeat-logo.png` }, + logo: { "@type": "ImageObject", url: `${SITE_URL}/assets/images/logo.png` }, }, - datePublished: article.date, + datePublished: toIso(article.date), dateModified: new Date().toISOString(), + mainEntityOfPage: { "@type": "WebPage", "@id": `${SITE_URL}/articles/${article.slug}` }, }; return ( diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6c73d74..f6abace 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -20,18 +20,9 @@ export const metadata: Metadata = { }, alternates: { canonical: '/', - languages: { - 'en': '/en', - 'es': '/es', - 'pt': '/pt', - 'fr': '/fr', - 'de': '/de', - 'zh': '/zh', - 'ja': '/ja', - 'ar': '/ar', - 'hi': '/hi', - 'x-default': '/en', - }, + // hreflang entries removed — we don't currently serve translated content, + // and pointing Google at /en, /es, /pt, etc. (which 404) was poisoning + // the SEO signal. Re-add when the i18n routes actually exist. }, openGraph: { type: 'website', @@ -59,11 +50,14 @@ export const metadata: Metadata = { images: ['/assets/images/og-image.png'] }, robots: { - index: true, - follow: true, + // noindex while Phase B (PR rewrite) and Phase D (i18n routes) land. + // Flip both to true once Google Rich Results Test passes on a sample + // NewsArticle and the news sitemap is wired up (Phase C). + index: false, + follow: false, googleBot: { - index: true, - follow: true, + index: false, + follow: false, 'max-video-preview': -1, 'max-image-preview': 'large', 'max-snippet': -1 @@ -78,17 +72,7 @@ export default function RootLayout({ return ( - {/* hreflang tags for multilingual SEO — Section 18G */} - - - - - - - - - - + {/* hreflang entries removed pending real i18n routes (Phase D). */}