Search Engine Optimization (SEO) is crucial for any modern web application. Whether you're building a blog, product website, or SaaS platform with Next.js, having proper SEO practices ensures your pages are visible and clickable on Google.
In this article, you'll learn how to implement effective SEO in a Next.js project—whether you're using TypeScript or JavaScript, and whether you're working with the App Router (Next.js 13+) or the Pages Router.
✅ This is the ultimate guide—including best practices, code examples, pitfalls, myths, debugging tips, FAQs, and tooling. Let’s make your Next.js web app rank better!
✅ 1. Set Titles and Meta Descriptions
In App Router (Next.js 13+)
You can export metadata
or use generateMetadata
for dynamic metadata on server components.
TypeScript Example:
// app/about/page.tsx
export const metadata = {
title: "\"About Us - My App\","
description: "\"Learn more about our team and mission.\","
};
JavaScript Example:
// app/about/page.js
export const metadata = {
title: "\"About Us - My App\","
description: "\"Learn more about our team and mission.\","
};
⚠️ Pitfall: Metadata in Client Components
Metadata is only supported in server components. If you're using a client-side rendered page (e.g., using "use client"
), metadata
won’t work.
✅ Solution for CSR Pages:
Use next/head
in a client component:
"use client";
import Head from "next/head";
export default function AboutPage() {
return (
<>
<Head>
<title>About Us - My App</title>
<meta name="description" content="Learn more about our team." />
</Head>
<main>
<h1>About Us</h1>
</main>
</>
);
}
⚠️ Common Debugging Tip
If metadata isn’t updating, check:
- Whether the component is a server component.
- Whether you're using the correct metadata structure.
- If a custom
_document.js
orlayout.tsx
is overridinghead
content.
✅ 2. Social Sharing with Open Graph and Twitter Cards
Make your links share beautifully with OG and Twitter meta tags.
Add to metadata
in App Router:
export const metadata = {
openGraph: {
title: "About Us - My App",
description: "Learn more about our team.",
url: "https://myapp.com/about",
images: [
{
url: "https://myapp.com/images/about-og.jpg",
width: 1200,
height: 630,
alt: "About Page",
},
],
},
twitter: {
card: "summary_large_image",
title: "About Us - My App",
description: "Learn more about our team.",
images: ["https://myapp.com/images/about-og.jpg"],
},
};
✅ 3. Generate robots.txt
and sitemap.xml
Install:
npm install next-sitemap
Add next-sitemap.config.js
:
module.exports = {
siteUrl: "https://myapp.com",
generateRobotsTxt: true,
};
Update package.json
:
"scripts": {
"postbuild": "next-sitemap"
}
Then run:
npm run build && npm run postbuild
🧠 Myth: "Google will find all my pages even without a sitemap." Not true. Use a sitemap to explicitly tell search engines what to index.
✅ 4. Use Semantic HTML
Using proper HTML5 elements improves accessibility and SEO.
<main>
<h1>Welcome</h1>
<article>
<section>
<h2>Our Mission</h2>
<p>...</p>
</section>
</article>
</main>
✅ 5. Optimize Images
Use next/image
with alt
text:
import Image from 'next/image';
<Image
src="/team.jpg"
alt="Our Team"
width={800}
height={600}
/>
⚠️ Pitfall:
Missing alt
attributes hurts accessibility and SEO.
✅ 6. Add Canonical URLs
Avoid duplicate content penalties by using canonical URLs.
export const metadata = {
alternates: {
canonical: "https://myapp.com/about",
},
};
💡 Tip: Use a consistent domain (e.g., always
https://www.myapp.com
orhttps://myapp.com
, not both).
✅ 7. Structured Data with JSON-LD
Structured data helps Google understand your content.
import Script from 'next/script';
<Script id="structured-data" type="application/ld+json">
{JSON.stringify({
"@context": "https://schema.org",
"@type": "Organization",
name: "My App",
url: "https://myapp.com",
})}
</Script>
✅ 8. Bonus: Use next-seo
for Advanced Control
Install:
npm install next-seo
Create a config:
// seo.config.ts
const SEO = {
title: 'Default Title',
description: 'Default description',
openGraph: {
type: 'website',
locale: 'en_IE',
url: 'https://myapp.com/',
site_name: 'My App',
},
};
export default SEO;
Then use in pages:
import { NextSeo } from 'next-seo';
import SEO from '@/seo.config';
<NextSeo title="About" description="About us page" openGraph={SEO.openGraph} />
❌ Common SEO Mistakes in Next.js
Mistake | Why it hurts SEO | Solution |
---|---|---|
Setting metadata in client components | Metadata won’t render on initial load | Use next/head or move to server components |
Missing alt on images |
Google can’t understand images | Always add meaningful alt text |
Forgetting canonical URLs | Duplicate content confusion | Add canonical using metadata or head
|
No sitemap or robots.txt | Search engines might miss pages | Use next-sitemap
|
Inconsistent titles across pages | Confuses users and search engines | Use a global SEO config or next-seo
|
Too much client-side rendering | Poor crawlability | Use SSR/SSG for SEO-critical pages |
🤔 FAQs
Q: Can I use metadata in client components?
A: No. Use next/head
instead.
Q: Do I need a sitemap if I use dynamic routes?
A: Yes! Use next-sitemap
with dynamic route mapping to cover all URLs.
Q: What about international SEO (i18n)?
A: Use alternate
tags with hrefLang
, or configure with next-sitemap
.
Q: Should I enable indexing during development?
A: No. Always block indexing in non-production environments via robots.txt
or meta tags.
✅ Final Thoughts
By understanding the differences between App Router, Pages Router, and CSR vs SSR, and avoiding common pitfalls, you can build a fully optimized, search-friendly Next.js application.
Make use of:
- Proper metadata and titles
- Social share tags (OG & Twitter)
- Sitemaps and robots.txt
- Semantic HTML
- Image optimization
- Structured data
Your SEO success is in your control—apply this guide and watch your visibility grow!
📌 Related Resources
🚀 Stay tuned for Blog 2: How to Add Google Analytics to Your Next.js App (TS/JS)
Top comments (2)
Good job man
Thanks bro!