
SEO průvodce pro Next.js 15
Ahoj! Vítejte u našeho podrobného SEO průvodce pro
Příprava projektu a Metadata API
Nejprve se ujistěte, že máte ve svém projektu složku
// /app/layout.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Kompletní SEO průvodce pro Next.js 15',
description: 'Rozsáhlý návod na SEO v Next.js 15: od metadat až po monitoring',
metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL || 'https://webzi.cz'),
alternates: {
canonical: '/blog/seo-optimalizace-nextjs-15',
languages: {
cs: '/cs/blog/seo-optimalizace-nextjs-15',
en: '/en/blog/seo-optimalizace-nextjs-15'
}
},
openGraph: {
title: 'SEO Next.js 15',
description: 'Jak optimalizovat SEO v Next.js 15',
url: '/blog/seo-optimalizace-nextjs-15',
images: ['/assets/img/blog/seo-nextjs15-hero.jpg']
},
twitter: { card: 'summary_large_image' },
other: {
robots: 'index, follow'
}
};
Použitím
Vlastní hlavička pro speciální tagy
Pro meta tagy, které
// /app/head.tsx
'use client';
import React from 'react';
export default function Head() {
return (
<>
<meta name="viewport" content="width=device-width, initial-scale=1" />
{/* Přidejte další custom tagy, např. preconnect pro fonty */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
</>
);
}
Díky této komponentě zajistíte, že máte plnou kontrolu nad každým meta tagem, aniž byste přišli o výhody server-side renderingu.
Open Graph a Twitter Cards
Pro atraktivní náhledy na sociálních sítích využijte sekce
Strukturovaná data pomocí JSON-LD
Rich snippets (hvězdičky, autor, datum) získáte vložením JSON-LD do hlavičky pomocí
// /app/layout.tsx (pokračování)
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: metadata.title,
image: [new URL(metadata.openGraph.images[0], metadata.metadataBase).toString()],
author: { '@type': 'Person', name: metadata.author || 'Webzi Team' },
publisher: {
'@type': 'Organization',
name: 'Webzi',
logo: { '@type': 'ImageObject', url: 'https://webzi.cz/assets/img/logo/meta_webzi_logo.png' }
},
datePublished: '2025-05-19'
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="cs">
<head>
{/* metadata se generuje automaticky */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
</head>
<body>{children}</body>
</html>
);
}
Generování sitemapy
Dynamická
// /app/api/sitemap/route.ts
import { NextResponse } from 'next/server';
import dbConnect from '@/app/src/lib/mongoose';
import BlogPost from '@/app/src/lib/models/BlogPost';
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'https://webzi.cz';
export async function GET() {
await dbConnect();
const posts = await BlogPost.find().lean();
const urls = posts
.map(
(p) =>
`<url><loc>${BASE_URL}/blog/${p.slug}</loc><changefreq>weekly</changefreq></url>`
)
.join('');
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${urls}</urlset>`;
return new NextResponse(xml, { headers: { 'Content-Type': 'application/xml' } });
}
Crawl optimalizace
Soubor
User-agent: *
Disallow: /api/private
Allow: /blog
Sitemap: https://webzi.cz/api/sitemap
Optimalizace obrázků a Core Web Vitals
import Image from 'next/image';
export default function Hero() {
return (
<Image
src="/assets/img/blog/seo-nextjs15-hero.jpg"
alt="SEO Next.js 15"
width={1200}
height={630}
priority
/>
);
}
Internationalizace a hreflang
Díky sekci
Přístupnost a semantika
Používejte správné HTML elementy (
Interní prolinkování
Komponenta
Monitoring SEO, analytika a alerty
Integrujte Google Analytics 4 a Search Console API. Vložte do aplikace komponentu
import Script from 'next/script';
export default function Analytics() {
return (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA4_ID}`}
strategy="afterInteractive"
/>
<Script id="ga4-config" strategy="afterInteractive">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.NEXT_PUBLIC_GA4_ID}');`}
</Script>
</>
);
}