11 min read
ā¢Question 46 of 47hardAdvanced SEO in Next.js
Comprehensive SEO optimization strategies.
Advanced SEO
Dynamic Metadata
code.txtTSX
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [{ url: post.image, width: 1200, height: 630 }],
type: 'article',
publishedTime: post.publishedAt,
authors: [post.author.name],
},
twitter: {
card: 'summary_large_image',
title: post.title,
description: post.excerpt,
images: [post.image],
},
};
}JSON-LD Structured Data
code.txtTSX
// components/JsonLd.tsx
export function ArticleJsonLd({ post }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
description: post.excerpt,
image: post.image,
datePublished: post.publishedAt,
dateModified: post.updatedAt,
author: {
'@type': 'Person',
name: post.author.name,
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
);
}
// Usage in page
<ArticleJsonLd post={post} />Sitemap Generation
code.txtTSX
// app/sitemap.ts
import { MetadataRoute } from 'next';
export default async function sitemap(): MetadataRoute.Sitemap {
const posts = await getPosts();
const blogEntries = posts.map((post) => ({
url: `https://example.com/blog/${post.slug}`,
lastModified: post.updatedAt,
changeFrequency: 'weekly' as const,
priority: 0.8,
}));
return [
{
url: 'https://example.com',
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
},
...blogEntries,
];
}Robots.txt
code.txtTSX
// app/robots.ts
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{ userAgent: '*', allow: '/', disallow: '/admin' },
{ userAgent: 'Googlebot', allow: '/' },
],
sitemap: 'https://example.com/sitemap.xml',
};
}