NextJS App Router SEO Best Practices

NextJS App Router SEO Best Practices

Posted by

kamlesh paul

on

Apr 21, 2025

4 min read

Last updated on : Apr 21, 2025

104 views

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

layout.tsx
import type { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: '...',
  description: '...',
};
 
export default function Page() {}

Dynamic Metadata

layout.tsx
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:

page.tsx
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!

page.tsx
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:

app/sitemap.ts
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:

app/opengraph-image.tsx
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

app/robots.txt
User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://yourdomain.com/sitemap.xml

Generate a Robots File

app/robots.ts
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

app/robots.ts
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.


Share this article:

104 views