Structured data helps search engines understand your content and display rich results. Here is how to implement it.
Step 1: JSON-LD Component
// components/JsonLd.tsx
export function JsonLd({ data }: { data: Record<string, unknown> }) {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
);
}
Step 2: Organization Schema
Add to your root layout or homepage:
// app/layout.tsx
import { JsonLd } from "@/components/JsonLd";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "Organization",
name: "RCB Software",
url: "https://rcbsoftware.com",
logo: "https://rcbsoftware.com/logos/logo.png",
description:
"Custom web design, development, and software solutions for businesses worldwide.",
foundingDate: "2020",
sameAs: [
"https://twitter.com/rcbsoftware",
"https://linkedin.com/company/rcbsoftware",
"https://github.com/rcbsoftware",
],
contactPoint: {
"@type": "ContactPoint",
contactType: "customer service",
url: "https://rcbsoftware.com/contact",
},
}}
/>
{children}
</body>
</html>
);
}
Step 3: Article Schema
// app/blog/[slug]/page.tsx
import { JsonLd } from "@/components/JsonLd";
interface BlogPost {
title: string;
slug: string;
excerpt: string;
date: string;
author: string;
image?: string;
modifiedDate?: string;
}
function ArticleJsonLd({ post }: { post: BlogPost }) {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "Article",
headline: post.title,
description: post.excerpt,
author: {
"@type": "Person",
name: post.author,
},
publisher: {
"@type": "Organization",
name: "RCB Software",
logo: {
"@type": "ImageObject",
url: "https://rcbsoftware.com/logos/logo.png",
},
},
datePublished: post.date,
dateModified: post.modifiedDate ?? post.date,
mainEntityOfPage: {
"@type": "WebPage",
"@id": `https://rcbsoftware.com/blog/${post.slug}`,
},
image: post.image ?? "https://rcbsoftware.com/images/og-default.png",
}}
/>
);
}
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug); // Your data fetching logic
return (
<article>
<ArticleJsonLd post={post} />
<h1>{post.title}</h1>
{/* Post content */}
</article>
);
}
Step 4: FAQ Schema
// components/FaqJsonLd.tsx
import { JsonLd } from "./JsonLd";
interface FAQ {
question: string;
answer: string;
}
export function FaqJsonLd({ faqs }: { faqs: FAQ[] }) {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: faqs.map((faq) => ({
"@type": "Question",
name: faq.question,
acceptedAnswer: {
"@type": "Answer",
text: faq.answer,
},
})),
}}
/>
);
}
Usage:
<FaqJsonLd
faqs={[
{
question: "How long does it take to build a website?",
answer: "Most projects take 4-8 weeks from design to launch.",
},
{
question: "Do you offer ongoing maintenance?",
answer: "Yes, we offer monthly maintenance plans.",
},
]}
/>
Step 5: Breadcrumb Schema
// components/BreadcrumbJsonLd.tsx
import { JsonLd } from "./JsonLd";
interface BreadcrumbItem {
name: string;
url: string;
}
export function BreadcrumbJsonLd({ items }: { items: BreadcrumbItem[] }) {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: items.map((item, index) => ({
"@type": "ListItem",
position: index + 1,
name: item.name,
item: item.url,
})),
}}
/>
);
}
Step 6: Product Schema
// components/ProductJsonLd.tsx
import { JsonLd } from "./JsonLd";
interface ProductData {
name: string;
description: string;
image: string;
price: number;
currency: string;
availability: "InStock" | "OutOfStock" | "PreOrder";
rating?: { value: number; count: number };
brand?: string;
sku?: string;
url: string;
}
export function ProductJsonLd({ product }: { product: ProductData }) {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
description: product.description,
image: product.image,
brand: product.brand
? { "@type": "Brand", name: product.brand }
: undefined,
sku: product.sku,
offers: {
"@type": "Offer",
price: product.price,
priceCurrency: product.currency,
availability: `https://schema.org/${product.availability}`,
url: product.url,
},
aggregateRating: product.rating
? {
"@type": "AggregateRating",
ratingValue: product.rating.value,
reviewCount: product.rating.count,
}
: undefined,
}}
/>
);
}
Step 7: Service Schema
// components/ServiceJsonLd.tsx
import { JsonLd } from "./JsonLd";
interface ServiceData {
name: string;
description: string;
provider: string;
areaServed?: string;
url: string;
}
export function ServiceJsonLd({ service }: { service: ServiceData }) {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "Service",
name: service.name,
description: service.description,
provider: {
"@type": "Organization",
name: service.provider,
},
areaServed: service.areaServed ?? "Worldwide",
url: service.url,
}}
/>
);
}
Step 8: Local Business Schema
// components/LocalBusinessJsonLd.tsx
import { JsonLd } from "./JsonLd";
export function LocalBusinessJsonLd() {
return (
<JsonLd
data={{
"@context": "https://schema.org",
"@type": "ProfessionalService",
name: "RCB Software",
url: "https://rcbsoftware.com",
logo: "https://rcbsoftware.com/logos/logo.png",
description: "Custom web and software development services",
priceRange: "$$",
address: {
"@type": "PostalAddress",
addressLocality: "Worldwide",
addressCountry: "US",
},
openingHoursSpecification: {
"@type": "OpeningHoursSpecification",
dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
opens: "09:00",
closes: "17:00",
},
}}
/>
);
}
Step 9: Testing
Validate your structured data with:
- Google Rich Results Test: https://search.google.com/test/rich-results
- Schema Markup Validator: https://validator.schema.org/
Best Practices
- Use one
@typeper JSON-LD block for clarity - Include required properties for each schema type
- Keep data accurate and consistent with visible page content
- Test with Google Rich Results Test before deploying
- Monitor Google Search Console for structured data errors
Need SEO Optimization?
We implement technical SEO including structured data to help your pages stand out in search results. Contact us to get started.