Skip to content
    2025-09-15|5 min read

    Structured Data and JSON-LD: A Practical Guide

    #seo#json-ld#structured-data#schema#rich-results

    Structured data is the most underutilized SEO lever. It doesn't directly impact rankings, but it enables rich results — the enhanced search listings with star ratings, pricing, FAQs, and images that dominate page one and drive dramatically higher click-through rates.

    This guide covers everything you need to implement structured data with JSON-LD in a real application, from schema selection to testing.

    Why JSON-LD?

    Google recommends JSON-LD (JavaScript Object Notation for Linked Data) over other formats like Microdata or RDFa. It's cleaner, doesn't bloat your HTML, and is easy to generate programmatically.

    ``html <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "headline": "Structured Data and JSON-LD: A Practical Guide", "author": { "@type": "Person", "name": "Rahul Singh Negi" } } </script> ``

    Core Schema Types for Developer Portfolios

    BlogPosting

    Every blog article should include this schema:

    ```typescript interface BlogPostingSchema { '@context': 'https://schema.org'; '@type': 'BlogPosting'; headline: string; description: string; image: string; datePublished: string; dateModified: string; author: Person; publisher: Person; mainEntityOfPage: WebPage; wordCount: number; timeRequired: string; // ISO 8601 duration keywords: string; }

    function generateBlogPostSchema(post: BlogPost): BlogPostingSchema { return { '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, description: post.excerpt, image: https://www.rahulsinghnegi.com${post.coverImage}, datePublished: post.date, dateModified: post.updatedAt || post.date, author: { '@type': 'Person', name: 'Rahul Singh Negi', url: 'https://www.rahulsinghnegi.com/about', }, publisher: { '@type': 'Person', name: 'Rahul Singh Negi', }, mainEntityOfPage: { '@type': 'WebPage', '@id': https://www.rahulsinghnegi.com/blog/${post.slug}, }, wordCount: post.content.split(/\s+/).length, timeRequired: post.readingTime, keywords: post.tags.join(', '), }; } ```

    FAQPage

    FAQs are one of the most effective rich result types. Implement them on your services or about page:

    ```typescript interface FAQSchema { '@context': 'https://schema.org'; '@type': 'FAQPage'; mainEntity: FAQQuestion[]; }

    interface FAQQuestion { '@type': 'Question'; name: string; acceptedAnswer: { '@type': 'Answer'; text: string; }; }

    const faqSchema: FAQSchema = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: [ { '@type': 'Question', name: 'How long does it take to build a web app?', acceptedAnswer: { '@type': 'Answer', text: 'A simple MVP typically takes 2-4 weeks, while a full SaaS product can take 4-10 weeks depending on complexity.', }, }, { '@type': 'Question', name: 'What technologies do you use?', acceptedAnswer: { '@type': 'Answer', text: 'I primarily use Next.js, React, TypeScript, Firebase, and Tailwind CSS. For mobile, I work with React Native and Flutter.', }, }, ], }; ```

    LocalBusiness (Service-Based)

    If you offer services in a specific location:

    ``typescript const businessSchema = { '@context': 'https://schema.org', '@type': 'LocalBusiness', '@id': 'https://www.rahulsinghnegi.com', name: 'Rahul Singh Negi — Software Developer', description: 'Freelance full-stack developer specializing in Next.js, React, and Firebase.', url: 'https://www.rahulsinghnegi.com', telephone: '+1-555-0123', email: 'hello@rahulsinghnegi.com', image: 'https://www.rahulsinghnegi.com/images/profile.jpg', priceRange: '$$', areaServed: [ { '@type': 'City', name: 'San Francisco' }, { '@type': 'City', name: 'New York' }, { '@type': 'City', name: 'Austin' }, ], sameAs: [ 'https://github.com/rahulsinghnegi', 'https://linkedin.com/in/rahulsinghnegi', 'https://twitter.com/rahulsinghnegi', ], }; ``

    Product (For Digital Products or Services)

    If you sell templates, courses, or software:

    ``typescript const productSchema = { '@context': 'https://schema.org', '@type': 'Product', name: 'SaaS MVP Development Package', description: 'End-to-end MVP development including design, development, and deployment.', image: 'https://www.rahulsinghnegi.com/images/mvp-package.jpg', offers: { '@type': 'Offer', price: '5000', priceCurrency: 'USD', availability: 'https://schema.org/InStock', priceValidUntil: '2026-12-31', }, aggregateRating: { '@type': 'AggregateRating', ratingValue: '4.9', reviewCount: '24', }, }; ``

    Testing Your Structured Data

    Before deploying, validate every schema:

    1. Google Rich Results Test: https://search.google.com/test/rich-results — validates eligibility for rich results
    2. Schema.org Validator: https://validator.schema.org/ — validates syntax and completeness
    3. Google Search Console: The "Enhancements" section shows errors and warnings for live pages

    Common errors to watch for:

    • Missing required fields (e.g., datePublished for Article)
    • Invalid image URLs (must be absolute, indexable, and publicly accessible)
    • Incorrect date formatting (use ISO 8601: 2025-09-15 or 2025-09-15T10:00:00Z)
    • Missing @id or mainEntityOfPage references

    Rendering JSON-LD in React

    Create a reusable component that injects structured data into the page <head>:

    ```tsx 'use client';

    import { useMemo } from 'react'; import { usePathname } from 'next/navigation';

    interface JsonLdProps { schema: Record<string, unknown>; }

    export function JsonLd({ schema }: JsonLdProps) { const pathname = usePathname();

    const json = useMemo( () => JSON.stringify({ ...schema, '@id': ${process.env.NEXT_PUBLIC_URL}${pathname} }), [schema, pathname] );

    return ( <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: json }} /> ); } ```

    Advanced: BreadcrumbList

    Breadcrumb structured data helps search engines understand site hierarchy:

    ``typescript const breadcrumbSchema = (items: { name: string; url: string }[]) => ({ '@context': 'https://schema.org', '@type': 'BreadcrumbList', itemListElement: items.map((item, index) => ({ '@type': 'ListItem', position: index + 1, name: item.name, item: https://www.rahulsinghnegi.com${item.url}, })), }); ``

    Conclusion

    Structured data is one of the highest-ROI SEO investments you can make. Each schema type you implement increases your surface area for rich results on Google, Bing, and other search engines. Start with BlogPosting for your articles, add FAQPage on your services page, and work through the other types as your site grows. Test every schema before deploying, and monitor Google Search Console for errors.

    Need help implementing structured data on your site? Contact me for a structured data audit and implementation plan.

    ---

    R

    Written by

    Rahul

    Freelance developer for startups building SaaS products, MVPs, mobile apps, and conversion-focused website improvements.

    Building something?

    I am currently available for new projects. Share your idea and I will give you an honest assessment, delivery plan, and quote.