diff --git a/src/app/[locale]/applications/[slug]/ApplicationClient.tsx b/src/app/[locale]/applications/[slug]/ApplicationClient.tsx index 5d761bb..9a8d195 100644 --- a/src/app/[locale]/applications/[slug]/ApplicationClient.tsx +++ b/src/app/[locale]/applications/[slug]/ApplicationClient.tsx @@ -9,6 +9,8 @@ import Script from "next/script"; import { ArrowLeft, CheckCircle2, Zap, LayoutDashboard, Cpu, PencilRuler, Factory, MapPin, ChevronDown, Play, FileText, Box, Loader2, Maximize, X, ChevronLeft, ChevronRight } from "lucide-react"; import BreathingField from "@/components/visuals/BreathingField"; import AutoPlayVideo from "@/components/AutoPlayVideo"; +import Breadcrumbs from "@/components/seo/Breadcrumbs"; +import type { BreadcrumbItem } from "@/components/seo/Breadcrumbs"; // 🔥 EL TRUCO DEFINITIVO PARA TYPESCRIPT Y WEB COMPONENTS 🔥 // Al asignar el string a una variable con 'as any', TypeScript deja de @@ -999,7 +1001,7 @@ function ExpandedCaseStudy({ node }: { node: any }) { } // --- COMPONENTE PRINCIPAL --- -export default function ApplicationClient({ data, realCases, images }: { data: any, realCases: any[], images: any }) { +export default function ApplicationClient({ data, realCases, images, breadcrumbs }: { data: any, realCases: any[], images: any, breadcrumbs?: BreadcrumbItem[] }) { const [expandedCase, setExpandedCase] = useState(null); const [mainLightboxOpen, setMainLightboxOpen] = useState(false); @@ -1053,6 +1055,7 @@ export default function ApplicationClient({ data, realCases, images }: { data: a
+ {breadcrumbs && }
{data.category} diff --git a/src/app/[locale]/applications/[slug]/page.tsx b/src/app/[locale]/applications/[slug]/page.tsx index 27a2e76..b2d24d3 100644 --- a/src/app/[locale]/applications/[slug]/page.tsx +++ b/src/app/[locale]/applications/[slug]/page.tsx @@ -158,24 +158,28 @@ export default async function ApplicationPage({ params }: { params: Promise<{ sl const images = getApplicationImages(slug); // 4. JSON-LD structured data — wrapped to never break the render. + const appTitle = data?.title || "FLUX Application"; + const appUrl = `${baseUrl()}/${locale}/applications/${slug}`; + const crumbs = [ + { name: "Home", url: `/${locale}` }, + { name: "Applications", url: `/${locale}#applications-deep` }, + { name: appTitle, url: `/${locale}/applications/${slug}` }, + ]; + let jsonLd: object[] = []; try { - const url = `${baseUrl()}/${locale}/applications/${slug}`; - const title = data?.title || "FLUX Application"; const description = data?.shortDescription || data?.subtitle || ""; jsonLd = [ productSchema({ - name: title, + name: appTitle, description, imageUrl: images.heroImage || undefined, category: data?.category || "RF Industrial", - url, + url: appUrl, }), - breadcrumbSchema([ - { name: "Home", url: `${baseUrl()}/${locale}` }, - { name: "Applications", url: `${baseUrl()}/${locale}#applications-deep` }, - { name: title, url }, - ]), + breadcrumbSchema( + crumbs.map((c) => ({ name: c.name, url: `${baseUrl()}${c.url}` })) + ), ]; } catch (error) { console.error(`[applications/${slug}] JSON-LD build failed:`, error); @@ -184,7 +188,7 @@ export default async function ApplicationPage({ params }: { params: Promise<{ sl return ( <> {jsonLd.length > 0 && } - + ); } diff --git a/src/app/[locale]/news/[slug]/page.tsx b/src/app/[locale]/news/[slug]/page.tsx index 168940e..6885e76 100644 --- a/src/app/[locale]/news/[slug]/page.tsx +++ b/src/app/[locale]/news/[slug]/page.tsx @@ -10,6 +10,7 @@ import BreathingField from "@/components/visuals/BreathingField"; import { setRequestLocale } from "next-intl/server"; import { getLocalizedData } from "@/lib/i18nHelper"; +import Breadcrumbs from "@/components/seo/Breadcrumbs"; import { buildPageMetadata, articleSchema, @@ -259,6 +260,12 @@ export default async function ArticlePage({ params }: { params: Promise<{ slug: const articleUrl = `${baseUrl()}/${locale}/news/${slug}`; const cover = article.coverImage ? `/news/${slug}/${article.coverImage}` : undefined; + const crumbs = [ + { name: "Home", url: `/${locale}` }, + { name: "News", url: `/${locale}/news` }, + { name: article?.title || "Article", url: `/${locale}/news/${slug}` }, + ]; + let jsonLd: object[] = []; try { jsonLd = [ @@ -270,11 +277,9 @@ export default async function ArticlePage({ params }: { params: Promise<{ slug: publishedAt: article?.publishedAt || new Date(), updatedAt: article?.updatedAt || new Date(), }), - breadcrumbSchema([ - { name: "Home", url: `${baseUrl()}/${locale}` }, - { name: "News", url: `${baseUrl()}/${locale}/news` }, - { name: article?.title || "Article", url: articleUrl }, - ]), + breadcrumbSchema( + crumbs.map((c) => ({ name: c.name, url: `${baseUrl()}${c.url}` })) + ), ]; } catch (error) { console.error(`[news/${slug}] JSON-LD build failed:`, error); @@ -299,6 +304,9 @@ export default async function ArticlePage({ params }: { params: Promise<{ slug:
+
+ +
{article.category} diff --git a/src/components/seo/Breadcrumbs.tsx b/src/components/seo/Breadcrumbs.tsx new file mode 100644 index 0000000..38ecfcc --- /dev/null +++ b/src/components/seo/Breadcrumbs.tsx @@ -0,0 +1,52 @@ +// src/components/seo/Breadcrumbs.tsx +// ───────────────────────────────────────────────────────────────────────────── +// Visible breadcrumb navigation trail — complements the JSON-LD BreadcrumbList +// already rendered by individual pages. +// +// Design: Apple-clean, muted, small text — blends with the hero overlays +// on article and application detail pages. +// ───────────────────────────────────────────────────────────────────────────── + +import Link from "next/link"; +import { ChevronRight } from "lucide-react"; + +export interface BreadcrumbItem { + name: string; + url: string; +} + +export default function Breadcrumbs({ items }: { items: BreadcrumbItem[] }) { + if (items.length < 2) return null; + + return ( + + ); +}