In the competitive world of search engine optimization (SEO), standing out from the crowd is essential. Google Rich Results offer a powerful way to enhance your website's visibility and improve the user experience by displaying additional information directly in the search results. Rich Results go beyond the standard blue link and can include elements like product carousels, reviews, frequently asked questions (FAQs), and more.
By implementing structured data (Schema Markup) on your Next.js application, you can make your site eligible for Rich Results and potentially increase click-through rates.
The Problem
To be honest, adding Rich Results to your Next.js application is a relatively straightforward process. Next.js provides a guide on how to implement structured data , and Google offers documentation on how to create and validate Rich Results. Additionally, you can find the schema requirements on schema.org.
However, looking up every field in schema.org can be time-consuming, especially if you're implementing multiple schemas. Moreover, you may encounter situations where you have undefined values in your data. Since we use JSON.parse
to convert the structured data to a JSON string, having undefined values can lead to client-side application errors, potentially causing your website to go down.
Solution
As previously mentioned, Next.js has a brief guide on adding Rich Results to your application. To implement structured data, you can use the script tag with the type attribute set to application/ld+json. Here's a step-by-step process:
- Create a script tag for each schema you want to implement.
- Set the type attribute of the script tag to application/ld+json.
- Define the structured data using the appropriate schema types and properties.
- Convert the structured data to a JSON string using JSON.stringify.
- Place the JSON string inside the script tag.
This might seem like a tedious process, but in reality this is what it looks like:
export default async function Page({ params }) {
const product = await getProduct(params.id);
const jsonLd = {
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
image: product.image,
description: product.description,
};
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
);
}
Common Rich Results Schemas
Here are a few examples of common schemas you can implement in your Next.js application:
- Breadcrumbs
- Product
- Carousel
- Article
- FAQ
- Local Business
In this article, we'll go through a few of these schemas and discuss some important caveats to keep in mind when implementing them.
Breadcrumb Schema
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "Home",
item: "https://example.com",
},
{
"@type": "ListItem",
position: 2,
name: "Category",
item: "https://example.com/category",
},
{
"@type": "ListItem",
position: 3,
name: "Product",
item: "https://example.com/product",
},
],
}),
}}
/>
When implementing the Breadcrumbs schema, make sure to provide accurate and complete information about the page's position in the website's hierarchy. This helps search engines understand the structure of your site and can improve navigation for users.
Product Schema
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "Product",
name: "Product Name",
description: "Product Description",
image: "https://example.com/product-image.jpg",
offers: {
"@type": "Offer",
price: "99.99",
priceCurrency: "USD",
availability: "https://schema.org/InStock",
},
}),
}}
/>
It's important to note that while the Product schema doesn't require all offers
, aggregateRating
, and reviews
fields to be defined, at least one of these fields must be present. Otherwise, the Google Search Console will disqualify the schema.
In some cases, our products may or may not have certain fields, like reviews, that we won't know ahead of time. Take for example, a new product. For these situations, we can conditionally render fields in our JSON-LD schema.
Here's an example of conditionally including the reviews and aggregateRating fields:
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "Product",
name: "Product Name",
description: "Product Description",
image: "https://example.com/product-image.jpg",
offers: {
"@type": "Offer",
price: "99.99",
priceCurrency: "USD",
availability: "https://schema.org/InStock",
},
...(product.reviews?.length > 0 && {
review: product.reviews.slice(0, 10).map((review) => ({
"@type": "Review",
reviewRating: {
"@type": "Rating",
ratingValue: review.reviewRating.ratingValue,
},
author: {
"@type": "Person",
name: review.author.name,
},
reviewBody: review.reviewBody,
})),
aggregateRating: {
"@type": "AggregateRating",
ratingValue: Math.ceil(getProductAvgRating(product.reviews)),
reviewCount: product.reviews.length,
},
}),
}),
}}
/>
FAQ Schema
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: [
{
"@type": "Question",
name: "Question 1",
acceptedAnswer: {
"@type": "Answer",
text: "Answer 1",
},
},
{
"@type": "Question",
name: "Question 2",
acceptedAnswer: {
"@type": "Answer",
text: "Answer 2",
},
},
],
}),
}}
/>
The FAQ schema can help your page appear in Google's FAQ rich results, which can improve visibility and drive more traffic to your site. When implementing this schema, make sure to use clear, concise questions and answers that accurately reflect the content on your page.
Local Business Schema
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Business Name",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "City",
"addressRegion": "State",
"postalCode": "12345",
"addressCountry": "Country"
},
"telephone": "+1234567890",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "17:00"
}
]
}
</script>
For local businesses, implementing the Local Business schema can help your business appear in local search results and on Google Maps. Be sure to include accurate information about your business, such as its name, address, phone number, and opening hours.
Conclusion
Implementing Google Rich Results in your Next.js application is a powerful way to enhance your website's visibility, attract more clicks, and improve the user experience. By leveraging structured data and JSON-LD, you can provide valuable information to search engines, making your web pages more engaging and informative in search results.