Next.js SEO for a Portfolio: A Practical Setup That Actually Works

A practical walkthrough of the SEO setup I use in my Next.js portfolio: Metadata API, Open Graph, Twitter cards, dynamic sitemap, robots rules, and JSON-LD.

nextjs
seo
web development
portfolio
metadata
Kazi Efazul Karim
4 min read
Next.js SEO for a Portfolio: A Practical Setup That Actually Works

Next.js SEO for a Portfolio: A Practical Setup That Actually Works

Most SEO guides are either too generic or too enterprise-heavy. For a personal portfolio, I wanted a setup that is simple, maintainable, and measurable.

This post covers the exact structure I use in Next.js App Router projects.

SEO flow from metadata to search results

1) Start with strong global metadata

Your app/layout.tsx should define a clean default title, description, canonical URL, Open Graph, and Twitter card values.

tsx
1export const metadata = {
2  title: 'Efazul Karim | Software Engineer & Automation Developer',
3  description:
4    'Software engineer specializing in backend systems, automation, and AI-assisted workflows.',
5  alternates: {
6    canonical: 'https://your-domain.com',
7  },
8  openGraph: {
9    title: 'Efazul Karim | Software Engineer & Automation Developer',
10    description:
11      'Software engineer specializing in backend systems, automation, and AI-assisted workflows.',
12    url: 'https://your-domain.com',
13    type: 'website',
14    images: ['/images/thumbnail.png'],
15  },
16  twitter: {
17    card: 'summary_large_image',
18    title: 'Efazul Karim | Software Engineer & Automation Developer',
19    description:
20      'Software engineer specializing in backend systems, automation, and AI-assisted workflows.',
21    images: ['/images/thumbnail.png'],
22  },
23};
24

Why this matters

  • Search engines get a consistent canonical reference.
  • Social shares render a proper card preview.
  • Every route inherits sensible defaults unless you override them.

2) Add page-level metadata when the intent changes

For routes like /blog, /projects, and /products-services, override metadata so the snippet matches search intent.

tsx
1export async function generateMetadata() {
2  return {
3    title: 'Blog | Efazul Karim',
4    description:
5      'Engineering notes on React, Next.js, backend architecture, and performance.',
6    alternates: { canonical: 'https://your-domain.com/blog' },
7  };
8}
9

Practical rule

If a page could rank for a unique query, give it a unique title + description.


3) Generate a dynamic sitemap

Sitemaps are especially useful when your blog and project pages are generated from data or MDX.

tsx
1import type { MetadataRoute } from 'next';
2
3export default function sitemap(): MetadataRoute.Sitemap {
4  return [
5    {
6      url: 'https://your-domain.com',
7      lastModified: new Date(),
8      changeFrequency: 'monthly',
9      priority: 1,
10    },
11    {
12      url: 'https://your-domain.com/blog',
13      lastModified: new Date(),
14      changeFrequency: 'weekly',
15      priority: 0.9,
16    },
17    {
18      url: 'https://your-domain.com/projects',
19      lastModified: new Date(),
20      changeFrequency: 'monthly',
21      priority: 0.8,
22    },
23  ];
24}
25

4) Configure robots rules intentionally

Keep robots rules explicit. Let public pages be crawled, while hiding private or admin routes.

tsx
1import type { MetadataRoute } from 'next';
2
3export default function robots(): MetadataRoute.Robots {
4  return {
5    rules: [
6      {
7        userAgent: '*',
8        allow: '/',
9        disallow: ['/admin', '/api/private'],
10      },
11    ],
12    sitemap: 'https://your-domain.com/sitemap.xml',
13  };
14}
15

5) Add JSON-LD for machine-readable context

Structured data helps search engines interpret who you are and what your site represents.

tsx
1const personSchema = {
2  '@context': 'https://schema.org',
3  '@type': 'Person',
4  name: 'Efazul Karim',
5  url: 'https://your-domain.com',
6  sameAs: [
7    'https://github.com/efazulkarim',
8    'https://www.linkedin.com/in/kazi-efazul-karim-046964202/',
9  ],
10  jobTitle: 'Software Engineer',
11};
12

I usually include this in the root layout so every page has structured context.


6) Validate in production, not just locally

After deploying:

  1. Inspect page source for title/meta tags.
  2. Run Google Rich Results Test for JSON-LD.
  3. Check Open Graph cards using social preview tools.
  4. Submit/update sitemap in Google Search Console.

Core web vitals and technical SEO checklist


Final takeaway

SEO in Next.js is less about hacks and more about clean defaults + route-specific metadata + technical hygiene.

If your portfolio has:

  • clear metadata,
  • real canonical URLs,
  • valid sitemap/robots,
  • and structured data,

you're already ahead of most personal sites.

References

Share this article

Help others discover this content