
NextJS App Router SEO Best Practices
Posted by
kamlesh paulon
Apr 21, 2025| 4 min read
Last updated on : Apr 21, 2025
SEO is crucial for ensuring your Next.js app ranks well in search results. With the introduction of the NextJS App Router SEO Best Practices, it’s more important than ever to optimize your site.
In this guide, we’ll walk you through the best practices to improve your site’s visibility. From optimizing meta tags to setting up structured data, creating a sitemap, and configuring robots.txt, you’ll learn everything needed to make your Next.js app search engine-friendly.
Table of contents
Optimize Meta Tags
Next.js offers a Metadata API to easily manage your app’s metadata, like meta and link tags, for better SEO and web shareability. You can handle metadata in two ways:
Static Metadata
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '...',
description: '...',
};
export default function Page() {}
Dynamic Metadata
import type { Metadata, ResolvingMetadata } from 'next';
type Props = {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const id = params.id;
const product = await fetch(`https://.../${id}`).then((res) => res.json());
const previousImages = (await parent).openGraph?.images || [];
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
};
}
export default function Page({ params, searchParams }: Props) {}
Implement Structured Data
Structured data (schema markup) helps search engines understand your site’s content. You can add it with JSON-LD in Next.js. Here’s a sample for a blog post:
import { BlogPosting, Organization } from 'schema-dts';
export default function BlogPost({ post }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': BlogPosting,
headline: post.title,
datePublished: post.publishedAt,
author: {
'@type': Organization,
name: 'My Website',
},
};
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
</div>
);
}
This example includes data like the headline, publication date, and author for better SEO.
Optimize Images
Images are essential for visual content but can slow down your site if not optimized. Next.js provides the Image component, which optimizes and lazy loads images for better performance. Don’t forget to add alt text for SEO!
import Image from 'next/image';
export default function HomePage() {
return (
<div>
<Image src="/hero.jpg" alt="Hero Image" width={1200} height={600} />
</div>
);
}
Sitemap
You can create a sitemap in Next.js by using the sitemap.ts
file. Here’s how to dynamically generate a sitemap:
import type { MetadataRoute } from 'next';
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://yourdomain.com',
lastModified: new Date(),
changeFrequency: 'yearly',
priority: 1,
images: ['https://yourdomain.com/image.jpg'],
},
{
url: 'https://yourdomain.com/about',
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: 'https://yourdomain.com/blog',
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.5,
},
];
}
Dynamically Generate Social Images
To enhance your site’s appearance when shared on social media, you can dynamically generate social images using Open Graph tags:
import { ImageResponse } from 'next/og';
import { join } from 'node:path';
import { readFile } from 'node:fs/promises';
export default async function Image() {
const logoData = await readFile(join(process.cwd(), 'logo.png'));
const logoSrc = Uint8Array.from(logoData).buffer;
return new ImageResponse(
(
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<img src={logoSrc} height="100" />
</div>
)
);
}
Robots.txt
A robots.txt
file tells search engine crawlers which parts of your site to access. You can create one manually or generate it with a custom robots.ts
file.
Static robots.txt
User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://yourdomain.com/sitemap.xml
Generate a Robots File
import type { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: '/private/',
},
sitemap: 'https://yourdomain.com/sitemap.xml',
};
}
Customizing for Specific User Agents
import type { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: 'Googlebot',
allow: ['/'],
disallow: '/private/',
},
{
userAgent: ['Applebot', 'Bingbot'],
disallow: ['/'],
},
],
sitemap: 'https://yourdomain.com/sitemap.xml',
};
}
Conclusion
Optimizing your Next.js app for SEO is essential for improving search engine rankings and driving traffic to your site. By focusing on meta tags, structured data, image optimization, and properly setting up your sitemap and robots.txt, you’ll give your app the best chance to succeed.
SEO is an ongoing process, so keep monitoring and refining your strategies. By prioritizing it from the start, your Next.js app can achieve long-term search engine success.
Get updates directly to your inbox.
Join 500+ developers getting updates on Laravel & Next.js tips. No spam,
unsubscribe anytime.