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.
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.
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};
24Why 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.
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}
9Practical 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.
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}
254) Configure robots rules intentionally
Keep robots rules explicit. Let public pages be crawled, while hiding private or admin routes.
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}
155) Add JSON-LD for machine-readable context
Structured data helps search engines interpret who you are and what your site represents.
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};
12I usually include this in the root layout so every page has structured context.
6) Validate in production, not just locally
After deploying:
- Inspect page source for title/meta tags.
- Run Google Rich Results Test for JSON-LD.
- Check Open Graph cards using social preview tools.
- Submit/update sitemap in Google Search Console.
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.
Related on this site
- The reasoning behind investing in a personal site: Why I Built My Personal Website (And Why It Keeps Evolving).
- See a Next.js site built with this SEO approach in the Agency Portfolio project.
