--- name: seo-structured-data version: 3.1.0 description: > Implement production-grade SEO, structured data, Open Graph, and metadata for scardubu.dev. Use when: adding JSON-LD schemas, writing meta descriptions, configuring Open Graph images, generating sitemaps, managing robots.txt, auditing SEO, implementing canonical URLs, or setting up RSS feeds for the blog. Portfolio context: scardubu.dev targeting Google search for "ML engineer Lagos", "full-stack engineer Nigeria", and discovery via LinkedIn/Twitter/GitHub shares. Triggers: "SEO", "metadata", "JSON-LD", "structured data", "Open Graph", "sitemap", "canonical", "robots.txt", "OG image", "meta description", "/seo". Do NOT use for: component styling (use 03-frontend-design-SKILL.md), animation design (use 06-animation-SKILL.md), or API design. stack: Next.js 15 Metadata API · next-sitemap · schema.org · OpenGraph Protocol portfolio: scardubu.dev --- For a portfolio targeting Stripe, Cloudflare, and Vercel engineering leads, SEO is not about ranking on "hire me" keyword queries. It is about: 1. Looking credible when a recruiter Googles "Oscar Ndugbu" 2. Rendering beautifully when shared on LinkedIn, Twitter, and WhatsApp 3. Appearing in search results for "TaxBridge Lagos fintech" and "SabiScore ML" 4. Passing structured data validation so rich results appear in Google Every page is a recruiting tool. Metadata is its packaging. --- ## PHASE 1 — NEXT.JS 15 METADATA ARCHITECTURE ### 1.1 Root Layout Metadata (Base Layer) ```typescript // src/app/layout.tsx import type { Metadata } from 'next'; export const metadata: Metadata = { // Title template — child pages fill the %s slot title: { template: '%s — Oscar Ndugbu', default: 'Oscar Ndugbu — Staff Full-Stack ML Engineer, Lagos', }, description: 'Staff Full-Stack ML Engineer building fintech infrastructure in Lagos. ' + 'Creator of TaxBridge, SabiScore, and Hashablanca. ' + 'Open to Staff/Principal roles at Stripe, Cloudflare, Coinbase.', // Canonical + robots metadataBase: new URL('https://scardubu.dev'), alternates: { canonical: '/' }, robots: { index: true, follow: true, googleBot: { index: true, follow: true, 'max-image-preview': 'large' }, }, // Open Graph — base layer (page-level overrides cascade) openGraph: { type: 'website', url: 'https://scardubu.dev', siteName: 'Oscar Ndugbu — CONVICTION ENGINE', title: 'Oscar Ndugbu — Staff Full-Stack ML Engineer', description: 'Building fintech infrastructure that Nigerian SMEs actually use. ' + 'TaxBridge · SabiScore · Hashablanca.', images: [ { url: '/og/default.png', // 1200×630, generated by Edge Route width: 1200, height: 630, alt: 'Oscar Ndugbu — Staff Full-Stack ML Engineer — scardubu.dev', }, ], }, // Twitter / X Card twitter: { card: 'summary_large_image', site: '@Scardubu', creator: '@Scardubu', title: 'Oscar Ndugbu — Staff Full-Stack ML Engineer', description: 'Building fintech infrastructure in Lagos. TaxBridge · SabiScore · Hashablanca.', images: ['/og/default.png'], }, // Authors + verification authors: [{ name: 'Oscar Ndugbu', url: 'https://scardubu.dev' }], creator: 'Oscar Ndugbu', publisher: 'Oscar Ndugbu', verification: { google: 'YOUR_GOOGLE_SEARCH_CONSOLE_VERIFICATION_TOKEN', }, // App-specific meta applicationName: 'CONVICTION ENGINE', keywords: [ 'full-stack engineer Lagos', 'ML engineer Nigeria', 'fintech engineer Africa', 'TaxBridge', 'SabiScore', 'Next.js engineer', 'TypeScript engineer', 'Oscar Ndugbu', 'Scardubu', ], }; ``` ### 1.2 Page-Level Metadata (Cascades Over Base) ```typescript // src/app/projects/taxbridge/page.tsx import type { Metadata } from 'next'; export const metadata: Metadata = { title: 'TaxBridge — Tax Filing Infrastructure for Lagos SMEs', description: 'TaxBridge reduces VAT/CIT/PIT filing from 4 hours to 15 minutes for Nigerian SMEs. ' + 'Built with Fastify 5, PostgreSQL 15 RLS, BullMQ, and Paystack/Remita integrations.', alternates: { canonical: '/projects/taxbridge' }, openGraph: { title: 'TaxBridge — Tax Filing in 15 Minutes', description: 'How I built tax infrastructure that Lagos SMEs actually use. ' + '4h → 15min. Paystack + FIRS + Remita + Youverify.', images: [ { url: '/og/projects/taxbridge.png', width: 1200, height: 630, alt: 'TaxBridge — Nigerian SME tax filing platform by Oscar Ndugbu', }, ], type: 'article', }, }; ``` ### 1.3 Dynamic OG Image Generation (Edge Route) ```typescript // src/app/og/projects/[slug]/route.tsx // Generates 1200×630 OG images dynamically at the edge import { ImageResponse } from 'next/og'; import { type NextRequest } from 'next/server'; export const runtime = 'edge'; const projects: Record = { taxbridge: { title: 'TaxBridge', metric: '4h → 15min filing', stack: 'Fastify 5 · PostgreSQL · BullMQ', }, sabiscore: { title: 'SabiScore', metric: 'ML credit scoring', stack: 'XGBoost · LightGBM · CatBoost', }, hashablanca: { title: 'Hashablanca', metric: 'Privacy as primitive', stack: 'ZK-SNARKs · Multi-chain', }, }; export async function GET( request: NextRequest, { params }: { params: { slug: string } } ) { const project = projects[params.slug]; if (!project) return new Response('Not found', { status: 404 }); return new ImageResponse( (
{/* Top: site attribution */}
scardubu.dev @Scardubu
{/* Center: project info */}
{project.metric} {project.title} {project.stack}
{/* Bottom: author */}
ON
Oscar Ndugbu
), { width: 1200, height: 630 } ); } ``` --- ## PHASE 2 — JSON-LD STRUCTURED DATA ### 2.1 Person Schema (Homepage — Always Present) ```typescript // src/components/seo/PersonSchema.tsx // Renders as