Home·Blog·SEO
SEO

Mastering SEO Metadata in Next.js 15: The Complete Guide.

generateMetadata, Open Graph, Twitter Cards, JSON-LD structured data, and canonical URLs — everything you need to dominate search results with Next.js.

8 min readMar 2025Ababil.sec

Next.js 15 provides first-class support for SEO metadata through the Metadata API. When used correctly, it generates all the tags needed for search engines and social platforms — with full TypeScript support and automatic deduplication.

Static Metadata

Export a metadata object from any page or layout for static metadata:

import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'SQL Injection Prevention | Ababil.sec Blog',
  description: 'Learn how parameterized queries, ORMs, and WAFs combine to eliminate SQL injection entirely.',
  keywords: ['sql injection', 'web security', 'parameterized queries'],
  authors: [{ name: 'Ababil.sec' }],
  openGraph: {
    title: 'SQL Injection in 2025: Still the #1 Threat',
    description: 'Complete guide to preventing SQL injection.',
    url: 'https://ababilsec.com/blog/sql-injection-prevention',
    siteName: 'Ababil.sec',
    type: 'article',
  },
  twitter: {
    card: 'summary_large_image',
    title: 'SQL Injection Prevention Guide',
    creator: '@ababilsec',
  },
  alternates: {
    canonical: 'https://ababilsec.com/blog/sql-injection-prevention',
  },
};

Dynamic Metadata with generateMetadata

For dynamic routes like blog posts, generate metadata from your data source:

export async function generateMetadata(
  { params }: { params: { slug: string } }
): Promise<Metadata> {
  const article = getArticleBySlug(params.slug);

  if (!article) return { title: 'Not Found' };

  return {
    title: article.title + ' | Ababil.sec',
    description: article.excerpt,
    openGraph: {
      title: article.title,
      description: article.excerpt,
      type: 'article',
      publishedTime: article.date,
    },
  };
}

Title Templates

Define a title template in the root layout to automatically append your site name:

export const metadata: Metadata = {
  title: {
    template: '%s | Ababil.sec',
    default: 'Ababil.sec — Cybersecurity & Web Development',
  },
};

JSON-LD Structured Data

Add structured data as a script tag in your page component for rich search results:

export default function BlogPost({ article }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: article.title,
    description: article.excerpt,
    author: { '@type': 'Organization', name: 'Ababil.sec' },
    datePublished: article.date,
  };

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

Robots and Sitemap

Generate a dynamic sitemap by creating app/sitemap.ts:

export default function sitemap() {
  const articles = getAllArticles();
  return articles.map(article => ({
    url: 'https://ababilsec.com/blog/' + article.slug,
    lastModified: new Date(),
    changeFrequency: 'monthly',
    priority: 0.8,
  }));
}

Conclusion

The Next.js Metadata API handles the mechanics of SEO tags — your job is providing accurate, compelling metadata for every page. Invest time in writing unique titles and descriptions, implement structured data for rich results, and validate everything with Google's Rich Results Test.

Ready to Secure Your
Project?

Get a professional security audit or start a project with us today.

Start a Project
Related Articles