f in x
SEO with Next.js — Metadata API, Sitemap and Open Graph to Rank Your Site
> cd .. / HUB_EDITORIALE
Sviluppo di siti web

SEO with Next.js — Metadata API, Sitemap and Open Graph to Rank Your Site

[2026-07-12] Author: Ing. Calogero Bono
Zenithby Meteora Web The operating system for your business. Social, clients, bookings and invoices in one platform. Gyms, barbers, professionals. Discover Zenith Free demo · no card

Your Next.js site loads fast, but Google isn't indexing it properly. Meta tags are a mess. Social shares show bare URLs. This is the problem we see most often in projects coming to us: modern stack, forgotten SEO. And without SEO, a site is just an empty shell.

We, at Meteora Web, have been working with Next.js since 2021. We've guided clients from first deploy to stable Google positions. In this guide, we don't teach search engine theory. We show you exactly how to use Next.js APIs for metadata, sitemap, and Open Graph — the three pillars of technical SEO on this framework.

How to use the Next.js Metadata API to control title and description?

Next.js App Router introduced a native Metadata API. No more external plugins, no react-helmet. You declare everything in an export const metadata object or via the generateMetadata function. Google, Facebook, Twitter read these tags directly.

Static metadata: the simplest case

For static pages (e.g. about, contact) you export an object:

// app/about/page.tsx
export const metadata = {
  title: 'About Us | Meteora Web - Digital Agency in Sicily',
  description: 'For 8 years we develop websites and digital strategies for Italian SMEs. Discover our team and philosophy.',
};

export default function About() {
  return 

About Us

; }

Attention: the metadata object must be exported from a page.tsx or layout.tsx. It doesn't work in client components.

Sponsored Protocol

Dynamic metadata with generateMetadata

For product, article, or detail pages — where title and description change based on data — use generateMetadata:

// app/products/[id]/page.tsx
import { notFound } from 'next/navigation';

type Props = {
  params: { id: string }
};

export async function generateMetadata({ params }: Props): Promise {
  const product = await getProductById(params.id);
  if (!product) return {}; // or notFound()

  return {
    title: `${product.name} | Online Store`,
    description: product.metaDescription || product.shortDescription,
    openGraph: {
      title: product.name,
      description: product.metaDescription,
      images: [product.image],
    },
  };
}

This pattern is the most important for dynamic SEO. We often see it misused: titles too long, duplicate descriptions. Remember: title max 60 chars, description max 160. Google truncates the rest.

How to generate a dynamic XML sitemap with Next.js App Router?

The sitemap tells Google: "Here are all the pages on my site." Next.js allows you to generate it automatically via a sitemap.ts file in the app folder. No plugins, no external scripts.

Example dynamic sitemap with products and categories

// app/sitemap.ts
import { MetadataRoute } from 'next';

export default async function sitemap(): Promise {
  const baseUrl = 'https://yourdomain.com';

  // Static pages
  const staticPages = [
    { url: baseUrl, lastModified: new Date() },
    { url: `${baseUrl}/about`, lastModified: new Date('2025-01-15') },
    { url: `${baseUrl}/contact`, lastModified: new Date('2025-01-10') },
  ];

  // Dynamic pages from data
  const products = await fetch('https://api.yours.com/products').then(res => res.json());
  const productPages = products.map((prod: any) => ({
    url: `${baseUrl}/products/${prod.slug}`,
    lastModified: new Date(prod.updatedAt),
    changeFrequency: 'weekly' as const,
    priority: 0.8,
  }));

  const categories = await fetch('https://api.yours.com/categories').then(res => res.json());
  const categoryPages = categories.map((cat: any) => ({
    url: `${baseUrl}/categories/${cat.slug}`,
    lastModified: new Date(cat.updatedAt),
    changeFrequency: 'monthly' as const,
    priority: 0.5,
  }));

  return [...staticPages, ...productPages, ...categoryPages];
}

Common mistakes: forgetting to handle 404 pages, not updating lastModified when content changes, or adding too many entries with priority=1. Google ignores inflated priorities.

Sponsored Protocol

How to configure robots.txt with Next.js

Alongside the sitemap, a good robots.txt helps crawlers. Next.js generates it with a robots.ts file:

Sponsored Protocol

// app/robots.ts
import { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/admin/',
    },
    sitemap: 'https://yourdomain.com/sitemap.xml',
  };
}

Include the sitemap link here. Google finds it faster.

How to set up Open Graph for Facebook, LinkedIn and Twitter?

Open Graph controls how your link appears when shared. Good OG tags can increase click-through rate by 30% — our words, not theory. In Next.js, you declare it directly in the metadata.openGraph object.

Basic Open Graph for a product page

// app/products/[id]/page.tsx
export const metadata = {
  openGraph: {
    title: 'Running Pro X Shoes | SportShop',
    description: 'Light and responsive, ideal for asphalt. Delivery in 24h.',
    url: 'https://yourdomain.com/products/running-pro-x',
    siteName: 'SportShop',
    images: [
      {
        url: 'https://yourdomain.com/og/running-shoes.jpg',
        width: 1200,
        height: 630,
        alt: 'Running Pro X shoes on asphalt road',
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
};

Critical detail: the image must be at least 1200x630 pixels. Otherwise social networks crop it poorly. We solve this with an automatic OG image generator server-side — but a static PNG works too.

Sponsored Protocol

Twitter Card: don't forget

Twitter uses a parallel tag. You can set it in the same object:

metadata.twitter = {
  card: 'summary_large_image',
  title: 'Running Pro X Shoes',
  description: 'Light and responsive. Delivery in 24h.',
  images: ['https://yourdomain.com/og/running-shoes.jpg'],
};

If you don't set it, Twitter uses OG tags. But for optimization, explicit declaration is better.

Which technical SEO mistakes to avoid on Next.js?

We see the same errors every week. Here they are.

  • Identical title and description across all pages: Google sees duplicate content and penalizes. Every page must have a unique title and different description.
  • Metadata not handled for 404 pages: if a product does not exist, the 404 page should still have a sensible title and description (e.g. "Product not found | Site Name").
  • Sitemap with staging or localhost URLs: happens when building locally and forgetting to change the base URL. Always verify that baseUrl is correct.
  • Open Graph without absolute URL: the url attribute must be the full URL, not a relative string.
  • Not testing with validators: use Facebook Sharing Debugger and Twitter Card Validator to verify.

How to verify that SEO on Next.js works?

We follow a precise flow in every project:

Sponsored Protocol

  1. Lighthouse: run the SEO test. Must score 100.
  2. Google Search Console: submit the sitemap and check for indexing errors.
  3. OG and Twitter validators: test social previews.
  4. Manual check: view page source and look for meta tags. They must appear as you set them.

One piece of advice we always give: don't stop at deploy. Monitor your page positions every month. If they drop, check metadata first.

What to do now

  1. Open your Next.js app and verify that every page.tsx has export const metadata or generateMetadata.
  2. Create the app/sitemap.ts file with the code above, customizing the fetch APIs.
  3. Add the app/robots.ts file and verify it points to the correct sitemap.
  4. Test a couple of pages with the Facebook validator: if the preview is empty, fix the OG image.
  5. Read the official Next.js Metadata API documentation.
  6. If you want to dive deeper into Next.js architecture, we have a dedicated pillar: Next.js App Router — from theory to deploy.

SEO on Next.js is not a mystery. It's discipline. Tags are written once, but checked always. And if you have a project that isn't taking off, you know where to find us.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()