Back to Blog
Next.jsSEOWeb Dev

The Complete SEO Guide for Next.js 14+

How to use Next.js metadata API, structured data, and Core Web Vitals optimizations to rank higher and drive organic traffic from day one.

October 20, 20244 min readProcverse Team

Why SEO Starts at the Framework Level

Most SEO advice focuses on content strategy, backlinks, or keyword research. All of that matters — but before any of it can work, your site needs to be technically sound. Search engines need to crawl your pages, parse your metadata, understand your content hierarchy, and confirm that your user experience meets their quality bar. Next.js gives you exceptional leverage here, but only if you use it intentionally.

This guide covers the technical SEO capabilities available in Next.js 14+ using the App Router, including the new Metadata API, structured data with JSON-LD, and the Core Web Vitals metrics that directly impact search ranking.

The Metadata API

Next.js 14 introduced a declarative Metadata API that replaces the old next/head pattern. You can export a metadata object from any page.tsx or layout.tsx, and Next.js handles the HTML <head> generation for you — with full TypeScript support.

import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "Your Page Title",
  description: "A compelling, accurate description under 160 characters.",
  openGraph: {
    title: "Your Page Title",
    description: "Same description, or a slightly more social-friendly version.",
    images: [{ url: "/og-image.png", width: 1200, height: 630 }],
  },
  twitter: {
    card: "summary_large_image",
    title: "Your Page Title",
  },
};

For dynamic routes, export generateMetadata as an async function. This lets you fetch the page's data and build metadata from it — essential for blog posts, product pages, or any route with a dynamic slug.

export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> {
  const post = getPostBySlug(params.slug);
  return {
    title: post.meta.title,
    description: post.meta.description,
  };
}

Use the template pattern in your root layout to avoid repeating your site name on every page:

export const metadata: Metadata = {
  title: { default: "Procverse", template: "%s | Procverse" },
};

Structured Data with JSON-LD

Structured data tells search engines the semantic meaning of your content. A blog post with Article schema, an organization with Organization schema, or a product with Product schema can unlock rich results — star ratings, breadcrumbs, FAQs — in the SERP.

In Next.js App Router, inject JSON-LD via a <script> tag inside a Server Component. No package required:

export default function BlogPost({ post }: { post: PostMeta }) {
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: post.title,
    description: post.description,
    author: { "@type": "Organization", name: "Procverse" },
    datePublished: post.date,
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      <article>{/* content */}</article>
    </>
  );
}

For the root layout, add Organization schema to establish your entity. This helps Google understand who you are and can improve how your brand appears in knowledge panels.

Core Web Vitals

Google's Core Web Vitals — LCP, INP, and CLS — are ranking signals. Poor scores do not guarantee rank penalties, but strong scores are increasingly a tiebreaker in competitive SERPs. Next.js App Router helps with all three by default, but you need to not work against it.

LCP (Largest Contentful Paint): The largest visible element above the fold must load fast. For most pages, this is a hero image. Mark it with priority on next/image to disable lazy loading and inject a preload link:

<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />

INP (Interaction to Next Paint): Measures responsiveness to user input. Heavy client-side JavaScript is the main culprit. Keep your bundles small, split code aggressively, and defer non-critical scripts.

CLS (Cumulative Layout Shift): Images and embeds without explicit dimensions cause layout shifts as they load. next/image solves this automatically when you provide width and height. For fonts, use next/font with display: swap and preload your critical weights.

Sitemaps and Robots

Generate a dynamic sitemap at app/sitemap.ts:

export default function sitemap(): MetadataRoute.Sitemap {
  const posts = getAllPosts();
  return posts.map((post) => ({
    url: `https://procverse.com/blog/${post.slug}`,
    lastModified: post.date,
    changeFrequency: "monthly",
    priority: 0.8,
  }));
}

Your robots.ts should allow all crawlers by default and point to the sitemap. Avoid blocking CSS or JavaScript — Google needs them to render your pages.

Technical SEO is infrastructure work. Do it once, do it right, and it compounds over time. Next.js makes most of it straightforward — you just need to reach for the right APIs.

Work With Us

Ready to build something great?

We apply these principles on every project we take on. Tell us about yours.