Programmatic SEO z Next.js i AI — jak generować tysiące zoptymalizowanych stron
Programmatic SEO z Next.js i AI. Stwórz tysiące zoptymalizowanych stron z jednego szablonu, pokrywaj długi ogon i skaluj dobrej jakości treść.
Maciej Sala
Founder StriveLab
9 min czytaniaOpublikowano 31 marca 2026 (Aktualizacja 29 maja 2026)
W tym artykule rozkładam na części kompletną architekturę programmatic SEO na Next.js, pokazuję jak generować treści z AI bez utraty jakości i jak optymalizować wynikowe strony jednocześnie pod tradycyjne SEO i nowe mechanizmy AI search (/).
Czym jest programmatic SEO i kiedy naprawdę działa?
Zamiast pisać każdą stronę od zera, budujesz cztery elementy, które pracują razem:
Bazę danych ze strukturalnymi informacjami (miasta, usługi, produkty, pytania)
Szablon strony w Next.js, który dynamicznie renderuje dane w spójnym layoutcie
Pipeline treści (z AI lub bez), który generuje unikalne opisy, nagłówki i sekcje dla każdej kombinacji danych
System publikacji — ISR/SSG w Next.js automatycznie generuje statyczne strony z
Rezultat: dziesiątki, setki lub tysiące stron, każda zoptymalizowana pod unikalne long-tail keyword, wygenerowanych z jednego szablonu i jednej bazy danych.
W klasycznym SEO koszt rośnie liniowo z liczbą stron. W programmatic SEO koszt
szablonu płacisz raz, a skalujesz dane.
— zasada skalowania treści
Przykłady programmatic SEO w praktyce
Strony lokalizacyjne — „Przegląd instalacji elektrycznej Kraków", „Przegląd instalacji elektrycznej Warszawa", „Przegląd instalacji elektrycznej Wrocław" (powtórz dla 50 miast × 10 typów usług = 500 stron).
Strony porównawcze — „Next.js vs Remix — porównanie frameworków", „React vs Vue — porównanie" (każda para z matrycy porównań generuje osobną stronę).
Strony oparte na danych publicznych — katalogi firm, agregatory ofert pracy, rankingi oparte na danych GUS, porównywarki cenowe.
Strony FAQ/glossary — każde pytanie lub termin z bazy ma osobną stronę z pełną odpowiedzią, structured data i linkowaniem wewnętrznym.
Architektura programmatic SEO: Next.js, dane i AI
Cały system to przepływ od ustrukturyzowanych danych, przez generowanie i walidację treści, aż po statyczne strony serwowane z CDN. Człowiek wchodzi w pętlę na etapie review próbki — i tam zostaje.
Diagram
Pipeline programmatic SEO: dane zasilają generowanie AI, walidacja i ludzkie review pilnują jakości, ISR/SSG buduje strony serwowane z CDN.
Stack technologiczny
Rekomendowany stack dla programmatic SEO w 2026 roku:
Next.js App Router — SSG z generateStaticParams dla stron statycznych, ISR () dla treści wymagających regularnej aktualizacji
Źródło danych — Supabase (PostgreSQL + ), Sanity, Contentful, pliki JSON/MDX, lub dowolna baza danych
AI do generowania treści — Claude API, GPT API lub lokalne modele do tworzenia unikalnych opisów
Hosting — Vercel (natywne wsparcie ISR) lub Cloudflare Pages
Monitoring — Google Search Console, Ahrefs/Semrush, narzędzia GEO visibility
Struktura projektu
Code
app/
├── [miasto]/
│ └── [usluga]/
│ └── page.tsx # Szablon strony lokalizacyjnej
├── porownanie/
│ └── [para]/
│ └── page.tsx # Szablon strony porównawczej
├── pytania/
│ └── [slug]/
│ └── page.tsx # Szablon strony FAQ
├── sitemap.ts # Dynamiczna mapa strony
└── robots.ts # robots.txt
data/
├── cities.json # Baza miast
├── services.json # Baza usług
└── generated/ # Wygenerowane treści AI
├── krakow-przeglad-elektryczny.json
├── warszawa-przeglad-elektryczny.json
└── ...
Generowanie stron z generateStaticParams
Code
// app/[miasto]/[usluga]/page.tsximport { notFound } from 'next/navigation';import cities from '@/data/cities.json';import services from '@/data/services.json';// W Next.js 15+ kombinacje, które nie istnieją w danych, mają zwracać 404export const dynamicParams = false;// Generuje ścieżki dla wszystkich kombinacji miasto × usługaexport async function generateStaticParams() { const params = []; for (const city of cities) { for (const service of services) { // Pomijaj kombinacje, które nie mają sensu (usługa niedostępna w mieście) if (service.unavailableIn?.includes(city.slug)) continue; params.push({ miasto: city.slug, usluga: service.slug, }); } } return params; // np. 50 miast × 10 usług ≈ 500 stron}// W Next.js 15+ `params` to Promise — trzeba je rozpakować przez awaitexport async function generateMetadata({ params,}: { params: Promise<{ miasto: string; usluga: string }>;}) { const { miasto, usluga } = await params; const city = cities.find((c) => c.slug === miasto); const service = services.find((s) => s.slug === usluga); return { title: `${service.name} ${city.name} - cena, termin, zakres`, description: `${service.name} w ${city.nameDeclension}. Sprawdź zakres, koszt i wymagania. Aktualne informacje na ${new Date().getFullYear()} rok.`, alternates: { canonical: `https://twojadomena.pl/${miasto}/${usluga}`, }, };}export default async function ServiceCityPage({ params,}: { params: Promise<{ miasto: string; usluga: string }>;}) { const { miasto, usluga } = await params; const city = cities.find((c) => c.slug === miasto); const service = services.find((s) => s.slug === usluga); // Kombinacja spoza generateStaticParams (lub usunięta z danych) → 404 if (!city || !service) notFound(); const content = await getGeneratedContent(miasto, usluga); return ( <main> <h1> {service.name} {city.name} </h1> {/* TLDR-first — natychmiast odpowiedź na pytanie */} <p className="lead">{content.tldr}</p> {/* Sekcje treści z danych strukturalnych + AI */} <section> <h2>Zakres {service.nameGenitive} w {city.nameDeclension}</h2> <p>{content.scope}</p> </section> <section> <h2>Ile kosztuje {service.name.toLowerCase()} w {city.nameDeclension}?</h2> <p>{content.pricing}</p> </section> <section> <h2>Jak często wykonywać {service.name.toLowerCase()}?</h2> <p>{content.frequency}</p> </section> <section> <h2>Podstawa prawna</h2> <p>{content.legalBasis}</p> </section> {/* FAQ z FAQPage schema */} <FaqSection items={content.faq} /> {/* Linkowanie wewnętrzne */} <RelatedServices city={city} currentService={service} /> <NearbyCities service={service} currentCity={city} /> {/* Structured data */} <ServiceJsonLd city={city} service={service} content={content} /> </main> );}
ISR dla treści wymagających aktualizacji
Dla stron, które powinny się aktualizować (np. ceny, terminy, nowe przepisy), używaj ISR z revalidate:
Code
// Na poziomie segmentu (layout lub page)export const revalidate = 86400 // Regeneracja co 24h// Lub on-demand revalidation z API route// app/api/revalidate/route.tsimport { revalidatePath } from 'next/cache'export async function POST(request: Request) { const { secret, path } = await request.json() if (secret !== process.env.REVALIDATION_SECRET) { return Response.json({ error: 'Unauthorized' }, { status: 401 }) } revalidatePath(path) return Response.json({ revalidated: true })}
Generowanie treści AI dla programmatic SEO bez utraty jakości
Programmatic SEO z AI to nie masowe produkowanie spamu. Google aktywnie penalizuje thin content i duplicate content. Kluczem do sukcesu jest generowanie treści, które są jednocześnie unikalne na każdej stronie, faktycznie przydatne dla użytkownika, oparte na wiarygodnych danych i napisane profesjonalnym językiem.
Pipeline generowania treści
Code
// scripts/generate-content.tsimport Anthropic from '@anthropic-ai/sdk'import cities from '../data/cities.json'import services from '../data/services.json'import { writeFile, mkdir } from 'fs/promises'const anthropic = new Anthropic()interface GeneratedContent { tldr: string scope: string pricing: string frequency: string legalBasis: string faq: Array<{ question: string; answer: string }>}async function generateContent( city: (typeof cities)[0], service: (typeof services)[0],): Promise<GeneratedContent> { const systemPrompt = `Jesteś ekspertem ds. inspekcji budowlanych w Polsce. Piszesz profesjonalne, merytoryczne treści po polsku. Używaj konkretnych danych: cen, terminów, numerów ustaw i rozporządzeń.NIE generuj ogólników — każda informacja musi być specyficzna dla danego miasta i typu usługi.Format odpowiedzi: JSON zgodny z podanym schematem.` const userPrompt = `Wygeneruj treść strony o usłudze "${service.name}" w mieście ${city.name} (województwo ${city.voivodeship}).Kontekst:- Populacja miasta: ${city.population}- Liczba budynków mieszkalnych: ${city.residentialBuildings}- Specyfika regionalna: ${city.regionalContext}- Przepisy dotyczące usługi: ${service.regulations}- Typowy zakres cenowy w Polsce: ${service.priceRange}Wygeneruj JSON z polami:- tldr: 2-3 zdania podsumowujące najważniejsze informacje (co, kiedy, ile)- scope: szczegółowy opis zakresu usługi (3-4 akapity)- pricing: informacja o kosztach z kontekstem lokalnym (2-3 akapity)- frequency: jak często wymagana, podstawa prawna (2 akapity)- legalBasis: konkretne przepisy (ustawa, rozporządzenie, artykuł)- faq: 5 pytań i odpowiedzi specyficznych dla tej usługi w tym mieścieOdpowiedz WYŁĄCZNIE JSON-em, bez markdown, bez backtickow.` const response = await anthropic.messages.create({ model: 'claude-sonnet-4-6', max_tokens: 4000, system: systemPrompt, messages: [{ role: 'user', content: userPrompt }], }) const text = response.content .filter((block) => block.type === 'text') .map((block) => block.text) .join('') return JSON.parse(text) as GeneratedContent}// Generowanie treści dla wszystkich kombinacji.// W produkcji opakuj pętlę w obsługę błędów per strona i rate limiting// (np. pauza ~1s między requestami albo kolejka z limitem współbieżności),// żeby nie wpaść w limity API przy setkach kombinacji.async function generateAll() { await mkdir('data/generated', { recursive: true }) for (const city of cities) { for (const service of services) { const content = await generateContent(city, service) const filepath = `data/generated/${city.slug}-${service.slug}.json` await writeFile(filepath, JSON.stringify(content, null, 2)) } }}generateAll()
Zapewnianie jakości treści AI
Sam prompt to nie wszystko. Aby treści generowane przez AI spełniały standardy jakości wymagane przez Google (i użytkowników), potrzebujesz procesu weryfikacji:
Walidacja schematowa — sprawdź, czy JSON ma wszystkie wymagane pola, czy teksty mają minimalną długość, czy FAQ nie jest powielony:
Code
function validateContent(content: GeneratedContent): string[] { const errors: string[] = [] if (content.tldr.length < 100) errors.push('TLDR za krótkie') if (content.scope.length < 500) errors.push('Zakres za krótki') if (content.faq.length < 3) errors.push('Za mało pytań FAQ') // Sprawdź duplikaty FAQ const questions = content.faq.map((f) => f.question.toLowerCase()) const uniqueQuestions = new Set(questions) if (uniqueQuestions.size !== questions.length) errors.push('Zduplikowane pytania FAQ') return errors}
Deduplikacja treści — porównaj treści między stronami. Jeśli dwie strony mają zbyt podobną treść (np. ten sam opis zakresu dla różnych miast), odrzuć i wygeneruj ponownie z mocniejszym promptem o unikalności.
Ludzki review próbki — sprawdź ręcznie 10–15% wygenerowanych treści. Oceń faktyczną poprawność, naturalność języka i przydatność. Popraw prompt na podstawie znalezionych problemów i wygeneruj ponownie — to jedyna droga do systematycznej poprawy jakości.
Fact-checking danych — jeśli treść zawiera konkretne ceny, terminy czy numery przepisów, zweryfikuj je z oficjalnymi źródłami. AI potrafi „halucynować" numery artykułów ustaw i podawać nieaktualne kwoty — błąd w tym miejscu podważa wiarygodność całej strony.
Optymalizacja programmatic SEO pod Google i odpowiedzi AI
Programmatic SEO w 2026 roku musi uwzględniać zarówno tradycyjne rankingi Google, jak i cytowania w AI search. Oto praktyczne wskazówki:
Struktura URL
Czyste, hierarchiczne URL-e, które komunikują kontekst:
Unikaj parametrów query (?city=krakow), kodów ID (/page/12345) i zbyt długich URL-i. Hierarchia URL powinna odzwierciedlać hierarchię treści.
Meta tagi — szablony z wariacją
Code
// Szablon z dynamiczną personalizacjąexport async function generateMetadata({ params }) { const { miasto, usluga } = await params const city = getCityData(miasto) const service = getServiceData(usluga) // Warianty tytułów — unikaj identycznych meta tagów const titleVariants = [ `${service.name} ${city.name} — cena, zakres, termin ${currentYear}`, `${service.name} w ${city.nameDeclension} — ile kosztuje i jak przebiega`, `${service.name} ${city.name} — kompletny przewodnik ${currentYear}`, ] // Wybierz wariant na podstawie hasha slug const titleIndex = hashString(miasto + usluga) % titleVariants.length return { title: titleVariants[titleIndex], description: `Wszystko o ${service.nameLocative} w ${city.nameDeclension}. Aktualny cennik, wymagane dokumenty, częstotliwość i podstawa prawna. Informacje zaktualizowane na ${currentYear} rok.`, }}
Structured Data na skalę
Generuj dynamicznie dla każdej strony. Pamiętaj o podziale ról: Service poniżej buduje kontekst semantyczny dla wyszukiwarek i modeli AI, ale sam rich snippet w Google wygeneruje raczej FAQPage (jeśli kwalifikuje się do rich results) niż typ Service. Traktuj structured data jako warstwę zrozumienia treści, nie gwarancję wzbogaconego wyniku.
Programmatic SEO generuje wiele stron — linkowanie między nimi jest kluczowe dla SEO (crawlability, rozkład link equity) i GEO (budowanie topical authority):
Code
// Komponent z powiązanymi usługami w tym samym mieściefunction RelatedServices({ city, currentService }) { const relatedServices = services.filter( (s) => s.slug !== currentService.slug && s.category === currentService.category ); return ( <nav aria-label="Powiązane usługi"> <h2>Inne przeglądy w {city.nameDeclension}</h2> <ul> {relatedServices.map((service) => ( <li key={service.slug}> <a href={`/${city.slug}/${service.slug}`}> {service.name} {city.name} </a> </li> ))} </ul> </nav> );}// Komponent z tą samą usługą w pobliskich miastachfunction NearbyCities({ service, currentCity }) { const nearby = cities .filter((c) => c.slug !== currentCity.slug) .filter((c) => c.voivodeship === currentCity.voivodeship) .slice(0, 5); return ( <nav aria-label="Ta usługa w innych miastach"> <h2>{service.name} w innych miastach</h2> <ul> {nearby.map((city) => ( <li key={city.slug}> <a href={`/${city.slug}/${service.slug}`}> {service.name} {city.name} </a> </li> ))} </ul> </nav> );}
Sitemap XML dla tysięcy stron
Dla dużej liczby stron podziel sitemap na mniejsze pliki (Google limit to 50 000 URL-i per sitemap):
Code
// app/sitemap.tsimport { MetadataRoute } from 'next'import cities from '@/data/cities.json'import services from '@/data/services.json'export default function sitemap(): MetadataRoute.Sitemap { const entries: MetadataRoute.Sitemap = [] // Strona główna i statyczne entries.push({ url: 'https://twojadomena.pl', lastModified: new Date(), changeFrequency: 'weekly', priority: 1.0, }) // Strony programmatic for (const city of cities) { for (const service of services) { entries.push({ url: `https://twojadomena.pl/${city.slug}/${service.slug}`, // Realna data ostatniej regeneracji treści, NIE new Date() z czasu builda — // inaczej sygnalizujesz Google, że wszystkie strony zmieniły się naraz przy każdym deployu lastModified: service.updatedAt ?? city.updatedAt, changeFrequency: 'monthly', priority: 0.7, }) } } return entries}
Najczęstsze pułapki programmatic SEO i jak ich uniknąć
Thin content penalty
Google penalizuje strony z cienką, niewystarczającą treścią. W programmatic SEO ryzyko jest wysokie, gdy:
Szablon jest zbyt prosty (tylko tytuł + 2 zdania + tabela)
Treść AI jest generyczna i powtarzalna między stronami
Nie ma unikalnej wartości na stronie (to samo co 100 innych stron, tylko z inną nazwą miasta)
Remedium: generuj treść specyficzną dla każdej strony, dodawaj kontekst lokalny (dane regionalne, specyfika miasta), twórz unikalne sekcje FAQ i dostarczaj informacje, których użytkownik nie znajdzie skopiowanych z innej strony.
Crawl budget
Google przydziela każdej domenie ograniczony „budżet crawlowania". Jeśli wygenerujesz 10 000 stron, ale większość z nich ma thin content — Google może przestać crawlować Twoją stronę efektywnie.
Strategia: najpierw pilotaż — zweryfikuj indeksację w Search Console i skaluj dopiero wtedy, gdy widzisz, że strony są indeksowane i generują ruch.
Duplicate content
Nawet z AI treści mogą być zbyt podobne między stronami. Narzędzia do sprawdzania duplikacji pomogą wychwycić problem, ale nie sprowadzaj jakości do jednego progu procentowego. Każda strona powinna mieć wyraźną wartość unikalną: własny kontekst, dane, FAQ, porównanie, interpretację albo lokalny niuans, którego nie da się podmienić samą nazwą miasta czy produktu.
Kanoniczne URL-e
To absolutna podstawa SEO, której nie można pominąć przy programmatic SEO. Upewnij się, że każda strona ma prawidłowy tag <link rel="canonical"> — bez niego Google może traktować podobne strony jako duplikaty i sam wybrać „kanoniczny" wariant, niekoniecznie ten, który preferujesz. Ewentualne problemy z kanonizacją widoczne są w Google Search Console w sekcji Coverage.
Jak mierzyć efekty programmatic SEO?
Metryki tradycyjnego SEO
Indeksacja — ile stron z wygenerowanych zostało zaindeksowanych (Search Console → Coverage)
Impressions i clicks — czy strony pojawiają się w wynikach i generują kliknięcia
Pozycje na long-tail — czy strony rankują na docelowe frazy
Ruch organiczny — trend wzrostowy w Google Analytics 4
Metryki GEO/AEO
Cytowania w AI — czy Twoje strony pojawiają się w odpowiedziach ChatGPT, Perplexity, Gemini.
Featured snippets — czy strony trafiają do pozycji zerowej. Pamiętaj, że od 2023 roku Google pokazuje rich results dla FAQPage praktycznie tylko witrynom rządowym i medycznym — schema FAQ wciąż jednak pomaga modelom AI parsować treść.
AI Overview presence — czy Twoje treści są cytowane w Google AI Overviews.
Metryki biznesowe
Konwersje z organicznych — zapytania, zapisy, pobrania lead magnetów.
Koszt per strona — ile kosztuje wygenerowanie i utrzymanie jednej strony (API AI + hosting + monitoring). Dla porządku wielkości: strona z ~4 000 tokenów wyjścia na modelu klasy Sonnet to ułamek centa za generację — przy 10 000 stron mówimy o pojedynczych dziesiątkach dolarów za pełny przebieg. Samo API to zwykle najtańsza pozycja — realny koszt to przygotowanie danych, walidacja i redakcja.
ROI — przychód z ruchu organicznego vs koszt infrastruktury i treści.
Roadmapa wdrożenia programmatic SEO w Next.js
Tydzień 1–2: Fundament
Przygotuj bazę danych (miasta, usługi, produkty) ze strukturalnymi
metadanymi
Zbuduj szablon strony w Next.js z pełnym SEO (meta tagi, JSON-LD, link kanoniczny)
Wygeneruj treści AI dla 20–30 stron pilotażowych
Wdróż na Vercel, wygeneruj sitemap, zgłoś do Search Console
Tydzień 3–4: Weryfikacja
Sprawdź indeksację pilotażowych stron
Przejrzyj treści ręcznie — popraw prompt na podstawie znalezionych problemów
Zweryfikuj brak duplikacji treści (Siteliner, ręczne porównanie)
Zoptymalizuj Core Web Vitals (next/image, next/font, minimalizacja JS)
Programmatic SEO to strategia tworzenia dużej liczby stron na podstawie strukturalnych danych i powtarzalnych szablonów. Zamiast pisać każdą stronę ręcznie, definiujesz szablon, podłączasz bazę danych i automatycznie generujesz strony zoptymalizowane pod wyszukiwanie — pokrywając long-tail, na który nigdy nie opłacałoby się pisać treści ręcznie.
Czy Google karze za programmatic SEO?
Google nie karze za samą strategię, ale za thin content, duplicate content i spam — strony bez wartości dla użytkownika. Jeśli każda wygenerowana strona jest unikalna, merytoryczna i użyteczna, Google ją zaindeksuje i pokaże w wynikach. Kluczem jest jakość, a nie ilość
Ile stron wygenerować na początek?
Zacznij od pilotażu: kilkunastu do kilkudziesięciu stron, które dobrze reprezentują model danych i intencje użytkowników. Najpierw zweryfikuj indeksację, jakość treści, CTR i pierwsze pozycje w Search Console, a dopiero potem skaluj wzorzec — inaczej ryzykujesz wypaleniem crawl budgetu na thin content.
Czy treści generowane przez AI są akceptowane przez Google?
Google nie ocenia treści po tym, czy powstały z AI, lecz po ich jakości i użyteczności. Problem zaczyna się wtedy, gdy AI służy do masowego tworzenia stron bez realnej wartości dodanej — taki setup wchodzi w obszar scaled content abuse. Ostatnią częścią łańcucha powinna być ocena i redakcja przez człowieka.
Jak Next.js ISR wspiera programmatic SEO?
ISR generuje strony statycznie podczas builda, a potem odświeża je w tle po określonym czasie (np. co 24h). Strony ładują się błyskawicznie z CDN jak static site, ale aktualizują treść bez pełnego rebuildu. To idealne dla programmatic SEO, gdzie treść zmienia się rzadziej niż na stronach dynamicznych, ale częściej niż na czysto statycznych.
Ile kosztuje programmatic SEO z AI?
Koszt zależy od objętości promptów, modelu, liczby stron, częstotliwości regeneracji i nakładu na redakcję oraz QA. W praktyce największym kosztem rzadko jest samo API modelu — częściej jest nim przygotowanie danych, walidacja jakości i utrzymanie pipeline. To inwestycja w infrastrukturę treści, nie jednorazowy wydatek na generowanie.
O autorze
Maciej Sala
Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwijam własne projekty.
Programmatic SEO brzmi jak droga na skróty: baza danych, szablon, kilka tysięcy URL-i i gotowe. Właśnie tak powstają serwisy, które Google ignoruje, a zespół boi się ruszyć po trzech miesiącach. Da się zrobić to zdrowiej. Astro generuje szybki HTML, PostgreSQL trzyma dane i statusy publikacji, a n8n prowadzi workflow od importu do review. Bez ręcznego klepania stron. Bez zalewania indeksu kopią tej samej treści.
Maciej Sala
Founder StriveLab
Generative Engine Optimization GEO to praktyka optymalizacji treści tak, aby silniki AI ChatGPT, Perplexity, Google AI Overviews, Gemini i Claude cytowały je w swoich odpowiedziach. Answer Engine Optimization AEO koncentruje się na pojawianiu się w boksem z odpowiedzią, odpowiedziach głosowych i bezpośrednich odpowiedziach na stronach wyników wyszukiwania. Obie razem opisują dodatkowy wymiar widoczności i nie zastępują technicznego SEO ani jakości treści, od których zależy możliwość znalezienia strony.
Maciej Sala
Founder StriveLab
Next.js to framework React, który rozwiązuje największy problem klasycznych aplikacji SPA : serwer wysyła gotowy HTML zamiast pustej strony. Dzięki temu Google widzi treść w początkowym HTML i nie musi czekać na JavaScript, żeby odkryć najważniejsze elementy strony. Do tego dostajesz wbudowane API do metadanych, automatyczną optymalizację obrazów i code splitting podział kodu ładowanego osobno dla każdej podstrony , który realnie poprawia Core Web Vitals.