FREDDI.
Home
CareersContact
Get in touch

Core services

Custom Software

Dashboards, portals and internal tools that fit perfectly.

Web Development

Custom websites and web applications. From essential to enterprise.

Mobile App Development

iOS & Android apps. One codebase, two platforms.

E-commerce & Web Shops

Online stores that sell. Custom, Shopify or WooCommerce.

More services

SEO Optimization

Get found on Google. More traffic, more customers.

AI Solutions

Chatbots, automation and smart analytics for your business.

UI/UX Design

From wireframe to pixel-perfect design. Conversion-focused.

API & Integrations

Connect systems. CRM, ERP, payment systems and more.

Maintenance & Support

Monitoring, updates and security. Fixed monthly fee.

Not sure which service you need?

View all services
FREDDI.

Software that works. Websites, SEO and AI solutions for businesses that want to move forward.

Services

Web DevelopmentSEO OptimizationAI Solutions

Company

PortfolioCareersContact

Contact

info@freddimedia.nl06-21544459Nieuwegein
© 2026 Freddi. All rights reserved.
KVK: 93287259BTW: NL005011866B25

BLOG — SEO & DEVELOPMENT

SEO in Next.js: the complete technical guide

Next.js has excellent SEO capabilities built in. But you need to use them correctly. In this article, we walk through every step — from metadata to structured data.

Read the guide →06-21544459

Metadata and generateMetadata

Metadata is the foundation of SEO in Next.js. The App Router provides a powerful system through the generateMetadata function. Each page can define its own title, description, and Open Graph tags.

import type { Metadata } from 'next'

export async function generateMetadata(): Promise<Metadata> {
  return {
    title: 'My Page — My Site',
    description: 'A short description for search engines.',
    openGraph: {
      title: 'My Page — My Site',
      description: 'A short description.',
      type: 'article',
    },
  }
}

Pro tip: use a title template in your root layout so you don't have to repeat ' | My Site' everywhere:

// app/layout.tsx
export const metadata: Metadata = {
  title: {
    template: '%s | My Site',
    default: 'My Site',
  },
}

Don't forget alternates for multilingual sites. This tells Google which language versions exist:

alternates: {
  canonical: 'https://example.com/en/page',
  languages: {
    nl: 'https://example.com/nl/pagina',
    en: 'https://example.com/en/page',
  },
}

Sitemap and robots.txt

A sitemap tells search engines which pages your site has. Next.js supports this natively via a sitemap.ts file:

// app/sitemap.ts
import type { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: 'https://example.com',
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 1,
    },
  ]
}

For robots.txt you create a similar file:

// app/robots.ts
import type { MetadataRoute } from 'next'

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
    },
    sitemap: 'https://example.com/sitemap.xml',
  }
}

Both files are automatically generated as /sitemap.xml and /robots.txt when you build the site.

Structured data (JSON-LD)

Structured data helps Google understand your content better and can result in rich snippets — enhanced search results with stars, FAQ dropdowns, or breadcrumbs.

The most common format is JSON-LD. In Next.js, you add this as a script tag:

function FAQSchema({ items }: { items: { q: string; a: string }[] }) {
  const schema = {
    '@context': 'https://schema.org',
    '@type': 'FAQPage',
    mainEntity: items.map((item) => ({
      '@type': 'Question',
      name: item.q,
      acceptedAnswer: {
        '@type': 'Answer',
        text: item.a,
      },
    })),
  }

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

Other useful schema types: Article (for blog posts), Organization (for your company page), BreadcrumbList (for navigation), and HowTo (for tutorials).

Performance and Core Web Vitals

Google uses Core Web Vitals as a ranking factor. The three metrics that matter:

LCP (Largest Contentful Paint)

How fast does the largest element on the page load? Target: under 2.5 seconds. Use next/image for automatic image optimization.

INP (Interaction to Next Paint)

How fast does the page respond to interaction? Target: under 200ms. Minimize client-side JavaScript and use Server Components where possible.

CLS (Cumulative Layout Shift)

Does the layout jump during loading? Target: under 0.1. Always provide width and height for images, and load fonts via next/font.

Next.js helps with each of these: next/image optimizes images automatically, next/font prevents layout shifts for fonts, and Server Components reduce the JavaScript bundle.

import Image from 'next/image'
import { GeistSans } from 'geist/font/sans'

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

// Font without layout shift
<body className={GeistSans.className}>

Server Components and SEO

The Next.js App Router uses Server Components by default. This is a major advantage for SEO for two reasons:

First: Server Components render on the server. Google sees the complete HTML without needing to execute JavaScript. This is more reliable than client-side rendering where Googlebot has to run the JavaScript.

Second: Server Components send no JavaScript to the browser. Less JavaScript = faster page = better Core Web Vitals = higher ranking.

Rule of thumb: make everything a Server Component unless you need interactivity (forms, dropdowns, animations). Only mark those components with 'use client'.

// Server Component (default) — good for SEO
export default async function BlogPost() {
  const post = await getPost()
  return <article>{post.content}</article>
}

// Client Component — only for interactivity
'use client'
export function ContactForm() {
  const [name, setName] = useState('')
  return <form>...</form>
}

Read more

SEO optimization

The fundamentals of SEO, explained for business owners.

Read article

Build a Next.js website

From setup to deployment — a complete guide.

Read article

Frequently asked questions

Are Single Page Apps bad for SEO?

Traditional SPAs that rely entirely on client-side rendering are trickier for SEO — Google has to execute JavaScript to see the content. Next.js solves this with Server Components and SSR: the HTML is rendered on the server, allowing search engines to index the content directly.

Should I use SSR or SSG?

Use SSG (Static Site Generation) for content that doesn't change often — blog posts, landing pages, documentation. Use SSR (Server-Side Rendering) for content that varies per request — personalized pages, search results. In Next.js, you can choose per page.

How do I test the SEO of my Next.js site?

Use Google Search Console for indexing status and search performance. Lighthouse (in Chrome DevTools) measures Core Web Vitals. And Google's Rich Results Test checks your structured data. Always test on a production build (next build + next start), not the dev server.

Need SEO help for your Next.js project?

We help developers and businesses with technical SEO implementation in Next.js. From audit to implementation.

Our SEO servicesOur web development services

We always respond within one business day.