nextjs
Next.js Metadata Helper
Reusable helper function for generating SEO-optimized metadata in Next.js App Router.
#seo
#metadata
#app-router
A type-safe helper to generate consistent metadata across your Next.js app.
createMetadata Helper
// lib/metadata.ts
import type { Metadata } from 'next';
interface MetadataParams {
title: string;
description: string;
path?: string;
image?: string;
type?: 'website' | 'article';
publishedTime?: string;
noIndex?: boolean;
}
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'https://example.com';
const SITE_NAME = 'Your Site Name';
const DEFAULT_IMAGE = '/og-image.jpg';
export function createMetadata({
title,
description,
path = '',
image = DEFAULT_IMAGE,
type = 'website',
publishedTime,
noIndex = false,
}: MetadataParams): Metadata {
const url = `${BASE_URL}${path}`;
const imageUrl = image.startsWith('http') ? image : `${BASE_URL}${image}`;
return {
title,
description,
metadataBase: new URL(BASE_URL),
alternates: { canonical: url },
robots: noIndex ? { index: false, follow: false } : undefined,
openGraph: {
title,
description,
url,
siteName: SITE_NAME,
type,
images: [{ url: imageUrl, width: 1200, height: 630, alt: title }],
...(publishedTime && { publishedTime }),
},
twitter: {
card: 'summary_large_image',
title,
description,
images: [imageUrl],
},
};
}
Usage in Pages
// app/page.tsx
import { createMetadata } from '@/lib/metadata';
export const metadata = createMetadata({
title: 'Home - My Site',
description: 'Welcome to my website',
path: '/',
});
Usage for Blog Posts
// app/blog/[slug]/page.tsx
import { createMetadata } from '@/lib/metadata';
import { getPost } from '@/lib/posts';
export async function generateMetadata({ params }: Props) {
const post = await getPost(params.slug);
return createMetadata({
title: post.title,
description: post.excerpt,
path: `/blog/${params.slug}`,
image: post.coverImage,
type: 'article',
publishedTime: post.publishedAt,
});
}
Dynamic Metadata Template
// For title templates
export const metadata: Metadata = {
title: {
template: '%s | My Site',
default: 'My Site',
},
};
Key features:
- Consistent OpenGraph and Twitter cards
- Automatic canonical URLs
- Article metadata support
- noIndex option for private pages