W tym artykule pokażę Ci konkretne mechanizmy, dzięki którym Next.js może dać dużą przewagę Twojemu projektowi, pokrywając aspekt techniczny .
Framework pomaga w indeksacji, ale wciąż potrzebna jest właściwa struktura treści, intencji użytkownika i linkowanie wewnętrzne.
Dlaczego React SPA może mieć problemy z SEO?
React jest biblioteką i sam nie narzuca CSR — udostępnia również serwerowe API renderowania HTML. Problem dotyczy typowego projektu SPA zbudowanego np. przez Vite i wdrożonego bez prerenderingu lub własnej warstwy SSR. W takim wariancie serwer wysyła app shell z odwołaniem do JavaScriptu, a właściwa treść pojawia się dopiero po załadowaniu i wykonaniu skryptów. Next.js dostarcza gotową architekturę, dzięki której renderowanie serwerowe i statyczne są łatwiejsze do wdrożenia oraz utrzymania.
Googlebot potrafi renderować JavaScript, lecz jest to osobny etap przetwarzania, a błędy skryptów, zablokowane zasoby lub zależność od stanu przeglądarki mogą uniemożliwić zobaczenie treści. Google nadal rekomenduje renderowanie serwerowe albo prerendering jako dobre rozwiązanie dla użytkowników i crawlerów; część innych botów w ogóle nie wykonuje JavaScriptu. Nie oznacza to jednak, że każda strona CSR będzie źle indeksowana.
Server-Side Rendering (SSR) jako fundament SEO w Next.js
Next.js rozwiązuje ten problem przez renderowanie po stronie serwera i prerendering. W App Routerze komponenty są domyślnie Server Components, ale to nie znaczy, że każda strona jest renderowana dynamicznie przy każdym żądaniu. Strona może być statyczna, rewalidowana albo dynamiczna; z perspektywy SEO najważniejsze jest to, żeby główna treść, nagłówki, linki i metadane znalazły się w początkowej odpowiedzi HTML.
To, co widzisz powyżej, to standardowy komponent React, z tą różnicą, że Next.js może dostarczyć jego HTML bez czekania na wykonanie kodu w przeglądarce. Finalnie, robot Google dostaje gotowy HTML z główną treścią i nie musi odkrywać jej dopiero po hydracji.
SSR sprawdza się szczególnie dobrze, gdy publiczna treść musi być wyliczana przy każdym żądaniu. Nie należy jednak wybierać go automatycznie dla każdej zmiennej danej: dostępność produktu może często korzystać z cache i rewalidacji, a treści zależne od prywatnej sesji zwykle nie powinny być stronami docelowymi indeksowanymi przez wyszukiwarkę.
Static Site Generation (SSG) i wydajność SEO w Next.js
Z kolei SSG jest rozwiązaniem Next.js dla treści, które nie zmieniają się często, jak wpisy blogowe lub strony informacyjne. Przy tego typu treściach nie każda strona wymaga renderowania przy każdym żądaniu. Strony są generowane podczas budowania aplikacji albo prerenderingu, a następnie mogą być serwowane jako statyczny HTML z cache. Zwykle ogranicza to pracę serwera i TTFB, ale samo SSG nie gwarantuje dobrych Core Web Vitals — ciężki JavaScript, nieoptymalny obraz LCP albo skrypty zewnętrzne nadal mogą pogorszyć wynik.
Samo generateStaticParams() nie gwarantuje statycznego wyniku, jeśli trasa używa API zależnych od żądania albo danych bez odpowiedniego cache. Istnieje też (ISR), która pozwala unieważniać i ponownie generować statyczne strony bez przebudowywania całej aplikacji. Możesz ustawić czas przez export const revalidate = 3600 albo wywołać revalidatePath() po zmianie treści. ISR wymaga środowiska, które go obsługuje; nie działa w czystym static export.
Strategia renderowania w Next.js ma większe znaczenie niż framework
Wybór Next.js nie załatwia sprawy z góry, ponieważ nadal musisz dobrać właściwy model renderowania do konkretnej strony. W uproszczeniu masz cztery wzorce do wyboru:
- SSG: blog, dokumentacja, strony ofertowe, evergreen content,
- ISR: listingi, katalogi, strony zmieniające się co jakiś czas,
- SSR: strony zależne od sesji, lokalizacji, świeżych danych lub personalizacji,
- CSR wewnątrz strony SSR/SSG: interaktywne widgety, filtry, sortowanie, aplikacyjne.
To właśnie odpowiednie użycie tych opcji pomaga nam wybrać najlepszą strategię do swojego projektu.
| Podejście | Co dostaje crawler w pierwszym HTML | Kiedy ma sens pod SEO | Główne ryzyko |
|---|---|---|---|
| React SPA / CSR | App shell, treść po JavaScripcie | Aplikacje wewnętrzne, panele, narzędzia | Opóźnione renderowanie i zależność od JS |
| Next.js SSG | Gotowy statyczny HTML | Blog, dokumentacja, strony usług, landing page'e | Nieaktualna treść, jeśli build jest zbyt rzadki |
| Next.js ISR | Gotowy HTML z cache | Katalogi, content z CMS, produkty | Źle dobrana rewalidacja lub brak odświeżenia |
| Next.js SSR | HTML generowany przy żądaniu | Dane świeże, lokalne, zależne od sesji | Wyższy TTFB i większa zależność od backendu |
W praktyce przewaga Next.js nie wynika z samego logo frameworka, tylko z tego, że możesz dobrać strategię renderowania do typu strony. Strona kategorii może działać przez ISR, artykuł blogowy przez SSG, a panel klienta jako CSR wewnątrz zabezpieczonej części aplikacji.
Metadata API w Next.js i kontrola technicznego SEO
Next.js 13+ z App Routerem ma wbudowany sposób zarządzania najważniejszymi metadanymi, więc dla typowych znaczników <head> nie potrzebujesz biblioteki w rodzaju React Helmet.
Metadata API obsługuje między innymi title, description, Open Graph, Twitter Cards, kanoniczne URL-e, robots i znaczniki weryfikacyjne. Nie obejmuje każdego możliwego elementu <head> — na przykład resource hints mają osobne API. Eksporty metadata i generateMetadata działają wyłącznie w Server Components, a wartości dynamiczne trzeba nadal poprawnie zbudować, odziedziczyć i zweryfikować.
Optymalizacja obrazów z next/image pod SEO i Core Web Vitals
Kolejny istotny aspekt technicznego SEO to obrazy, które często są najcięższym elementem strony i głównym winowajcą słabych wyników . Next.js rozwiązuje ten problem specjalnym komponentem next/image.
W telegraficznym skrócie, co robi next/image pod spodem?
- Serwuje formaty skonfigurowane w projekcie i obsługiwane przez przeglądarkę; domyślnie WebP, a opcjonalnie także AVIF,
- Generuje
srcset; przy obrazie responsywnym musisz podać poprawnesizes, - Implementuje dla obrazów poniżej pierwszego ekranu,
- Rezerwuje miejsce na podstawie wymiarów albo statycznego importu, ograniczając przesunięcia layoutu,
- Obsługuje blur placeholder; dla ścieżki tekstowej trzeba samodzielnie dostarczyć
blurDataURL.
Ten komponent znacząco automatyzuje rutynową pracę, ale nie podejmie za Ciebie kluczowych decyzji – nie wybierze właściwego pliku graficznego, odpowiedniego kadru, optymalnej jakości, atrybutu sizes ani obrazu pełniącego funkcję LCP. Warto też pamiętać, że mechanizm optymalizacji może zachowywać się zupełnie inaczej przy włączonym trybie unoptimized, własnym loaderze, eksporcie statycznym czy nieprawidłowo skonfigurowanej sieci CDN. Finalne efekty i wydajność zawsze weryfikuj na podstawie rzeczywistych danych terenowych, a nie samego faktu użycia komponentu w kodzie.
Core Web Vitals w Next.js: gdzie framework daje przewagę?
Core Web Vitals są częścią sygnałów page experience w systemach rankingowych Google, ale dobry wynik sam w sobie nie gwarantuje wysokiej pozycji. Trzy metryki to:
LCP (Largest Contentful Paint) — czas wyrenderowania największego widocznego elementu. Prerendering może skrócić drogę do treści, a next/image pomóc w dostarczeniu grafiki, lecz wynik zależy też od TTFB, preloadu, CSS i rozmiaru zasobu.
(Interaction to Next Paint) — responsywność na interakcje. Server Components i mogą ograniczyć kod klienta, ale zbyt szerokie granice 'use client', ciężkie handlery i skrypty zewnętrzne nadal blokują główny wątek.
CLS (Cumulative Layout Shift) — stabilność wizualna. next/image i next/font ograniczają częste źródła przesunięć, lecz nie eliminują zmian powodowanych np. przez banery, reklamy lub treść doładowywaną bez zarezerwowanego miejsca.
Migracja przyniesie realną poprawę wyników tylko wtedy, gdy faktycznie wyeliminuje renderowanie wyłącznie po stronie klienta oraz zbędny kod JavaScript. Może jednak nie zmienić niczego albo wręcz pogorszyć wydajność, jeśli jedynie odtworzy tę samą ciężką architekturę przy użyciu komponentów klienckich. Efekty zmian zawsze weryfikuj poprzez porównanie wskaźników LCP, INP i CLS sprzed oraz po wdrożeniu, opierając się przede wszystkim na rzeczywistych danych terenowych z bazy CrUX lub raportów Search Console.
Sitemap, robots.txt i dane strukturalne w Next.js
Kompletna strategia SEO wymaga jeszcze kilku elementów, by zamknąć ten temat, a Next.js ułatwia ich implementację.
Sitemap, którą możesz wygenerować dynamicznie:
Robots.txt — analogicznie przez app/robots.ts.
Ważne: app/sitemap.ts i app/robots.ts są specjalnymi Metadata Routes, domyślnie cache'owanymi, o ile nie użyjesz API zależnego od żądania lub konfiguracji dynamicznej. Możesz zasilać sitemapę z , ale nadal musisz pilnować stabilnych, kanonicznych i indeksowalnych URL-i. lastModified powinno odzwierciedlać rzeczywistą istotną zmianę strony — wpisywanie bieżącej daty przy każdym buildzie wysyła fałszywy sygnał.
Dane strukturalne (JSON-LD) — dodaj w komponencie strony:
Zamiana znaku < ogranicza możliwość wstrzyknięcia znacznika przez dane pochodzące z CMS-a. Sam typ Schema.org nie gwarantuje rozszerzonego wyniku: obiekt musi odpowiadać widocznej treści i spełniać wymagania Google dla danego rodzaju danych.
Jak sprawdzić, co Google widzi w aplikacji Next.js?
Po wdrożeniu strony sprawdź, czy treść ważna dla SEO jest dostępna bez czekania na interakcję użytkownika.
Najprostsze testy:
view-source:https://twojadomena.pl/adres. Sprawdź, czy w źródle sąh1, treść, linki wewnętrzne i podstawowe metadane.DevTools → Network → dokument HTML. Zobacz faktyczną odpowiedź serwera, a nie tylko DOM po hydracji.
Google Search Console → Inspekcja URL. Sprawdź renderowany HTML i zrzut strony.
Rich Results Test. Zweryfikuj JSON-LD i dane strukturalne.
test z wyłączonym JavaScriptem, w którym nie musi działać cała aplikacja, ale główna treść contentowa powinna być czytelna.
Wyłączenie obsługi JavaScriptu w przeglądarce stanowi doskonały test odporności serwisu oraz realizacji idei progressive enhancement, jednak nie jest wiarygodną symulacją działania Googlebota, który na co dzień poprawnie wykonuje skrypty. O tym, jak robot widzi witrynę, decyduje w rzeczywistości poprawność odpowiedzi HTML, wynik renderowania w narzędziu Inspekcja URL w Search Console oraz to, czy krytyczne zasoby i żądania asynchroniczne nie są blokowane przez reguły pliku robots.txt.
Jeśli odpowiedź HTML zawiera wyłącznie tzw. szkielet aplikacji (app shell), a kluczowe nagłówki, opisy produktów czy linki nawigacyjne pojawiają się dopiero po wykonaniu zapytania fetch w komponencie klienckim, tracisz większość przewagi SEO, jaką oferuje Next.js. W takiej sytuacji najlepszym rozwiązaniem jest przeniesienie pobierania danych bezpośrednio do komponentów serwerowych oraz dobranie odpowiedniej strategii renderowania – statycznego, ISR lub dynamicznego. Pamiętaj też, że funkcja generateMetadata() odpowiada za poprawne generowanie metadanych, natomiast generateStaticParams() pozwala wskazać listę ścieżek przeznaczonych do wstępnego prerenderingu.
Najczęstsze błędy SEO w Next.js
Treść ładowana dopiero po hydracji, kiedy crawler dostaje pusty HTML, ponieważ dane są pobierane w
useEffect().Metadane generowane client-side. Tytuł, opis lub link kanoniczny pojawiają się dopiero po wykonaniu JS zamiast przez Metadata API.
Przypadkowy
noindex. Zostaje po środowisku testowym albo jest dziedziczony z layoutu.Nieprawidłowe linki kanoniczne. Wszystkie warianty strony wskazują na zły adres albo link kanoniczny nie zgadza się z rzeczywistym URL-em.
Brak crawlable links, czyli linki są przyciskami z
onClick, więc robot nie widzi normalnych adresów whref.Hydration mismatch. Treść w HTML różni się od pierwszego renderu klienta, powodując błędy, ponowne renderowanie albo niespójny widok.
Źle dobrana strategia cache. Artykuły, ceny lub stany produktów są przestarzałe, bo rewalidacja nie pasuje do tempa zmian.
Obrazy bez właściwego LCP, czyli hero image nie ma poprawnego rozmiaru,
sizes, priorytetu ładowania albo stabilnego miejsca w layoucie.
Ten ostatni punkt ma szczególne znaczenie po migracji na Next.js 16. Choć dla głównego obrazu LCP możesz użyć atrybutu preload, uważaj, aby nie nadużywać go dla wielu grafik jednocześnie. Zgodnie z dokumentacją Next.js, preload należy stosować tylko wtedy, gdy obraz faktycznie stanowi element LCP i znajduje się w obszarze widocznym na samym początku strony (above the fold).
Dlaczego Next.js nie gwarantuje pozycji w Google?
Może pomóc w SEO, ale nie zastąpi podstaw, ponieważ jest kolejnym elementem układanki:
- Trafienia w intencję użytkownika, czyli jeśli treść nie odpowiada na zapytanie, SSR niewiele zmieni.
- Semantycznego HTML: dobry nagłówek, listy,
article,nav,main, opisowe linki. - Linkowania wewnętrznego: robot musi rozumieć, które strony są ważne i jak są ze sobą powiązane.
- Kontroli indeksacji: linki kanoniczne,
robots, paginacja, duplikacja treści, czasemnoindex. - Danych z realnych użytkowników: Core Web Vitals pomagają, ale nie zastąpią jakości treści i sensownej architektury informacji.
Kiedy Next.js to dobry wybór pod SEO?
Next.js jest dobrym kandydatem, gdy SEO ma realne znaczenie dla biznesu, a projekt jednocześnie potrzebuje aplikacyjności i elastyczności między renderowaniem statycznym, rewalidacją oraz renderowaniem dynamicznym — na przykład w e-commerce lub publicznej części SaaS.
Kiedy może być przerostem formy nad treścią? Przy prostych aplikacjach wewnętrznych, dashboardach i narzędziach, gdzie SEO nie odgrywa większej roli — tam React z Vite może być lżejszym wyborem. Dla stron silnie zorientowanych na content, takich jak blogi i strony firmowe, prostszą alternatywą bywa Astro, które domyślnie wysyła JavaScript tylko dla komponentów świadomie oznaczonych do hydratacji. Wybór powinien wynikać z wymagań projektu, zespołu i wdrożenia, nie z samej obietnicy SEO.
