Klasyczna paginacja z numerami stron. Użytkownik widzi, ile jest stron, i przeskakuje między nimi dowolnie. To wariant, który SEO lubi najbardziej, bo każda strona ma własny, stabilny URL — indeksowalny, udostępnialny i taki, do którego wrócisz zakładką. Domyślny wybór dla blogów, katalogów i portfolio.
2. Infinite scroll — ładuj więcej przy scrollu
Lista rośnie automatycznie, gdy użytkownik scrolluje. Popularne w social media i feedach. Gorsze dla SEO (jedna strona, dynamiczne ładowanie) i nawigacji (trudno wrócić do konkretnego elementu).
3. „Load more" button — hybrid
Przycisk „Załaduj więcej" na dole listy. Użytkownik kontroluje ładowanie. Dobry kompromis między UX a SEO.
Google nie używa już rel="prev" / rel="next" jako sygnału indeksowania serii, więc nie próbuj generować ich przez metadata.other — to pole tworzy meta tagi, nie linki relacyjne. Najważniejsze są stabilne URL-e, poprawny canonical, linkowanie wewnętrzne i brak duplikatów.
Problem: wymaga od bazy danych przeskoczenia 10 000 rekordów. Przy milionach wierszy — wolne.
Cursor pagination
Code
// Szybkie nawet przy milionach rekordówasync function getPaginatedPosts({ cursor, perPage,}: { cursor?: string // ID ostatniego elementu z poprzedniej strony perPage: number}) { const posts = await db.post.findMany({ where: { published: true }, orderBy: { createdAt: 'desc' }, take: perPage + 1, // Pobierz +1 żeby wiedzieć, czy jest następna strona ...(cursor && { cursor: { id: cursor }, skip: 1, // Pomiń sam cursor }), }) const hasMore = posts.length > perPage const items = hasMore ? posts.slice(0, -1) : posts const nextCursor = hasMore ? items[items.length - 1].id : null return { posts: items, nextCursor, hasMore }}
nie pozwala przeskakiwać
do strony 50 — wymaga sekwencyjnego przechodzenia. Idealne dla infinite scroll,
gorsze dla numerycznej paginacji.
Kiedy co?
Kryterium
Offset
Cursor
Przeskakiwanie do strony N
Tak
Nie
Wydajność przy dużych zbiorach
Wolne
Szybkie
„Ile jest stron?"
Łatwe (COUNT)
Trudne
Infinite scroll
Możliwe
Idealne
SEO (numeryczne URL)
Natywne
Wymaga obejścia
Rekomendacja: offset dla blogów i katalogów, gdzie potrzebujesz numerów stron i skakania do konkretnej strony. Cursor dla feedów, logów i dużych zbiorów z infinite scroll, gdzie ważniejsza jest stabilność i wydajność niż numer strony.
Infinite scroll z Intersection Observer
Infinite scroll najczyściej zbudujesz na — elementem-wartownikiem na końcu listy, którego pojawienie się w widoku uruchamia doładowanie kolejnej porcji.
Tak, pod warunkiem że mają canonical wskazujący na siebie i są dostępne przez linkowanie wewnętrzne albo sitemapę. Google traktuje ?page=2 jak osobną stronę z unikalną treścią. Kluczowe jest, żeby canonical strony drugiej wskazywał na ?page=2, a nie na pierwszą stronę, ponieważ w przeciwnym razie głębsze strony mogą wypaść z indeksu.
Ile elementów powinno być na stronę?
Dla blogów i artykułów rozsądne jest 10–20 pozycji. Dla siatek produktów sprawdza się 20–48, najlepiej w wielokrotności liczby kolumn (2, 3, 4), żeby ostatni rząd był pełny. Najważniejsze to przetestować na prawdziwych danych: zbyt wiele elementów spowalnia ładowanie strony, zbyt mało zmusza użytkownika do nadmiaru kliknięć.
Czym różni się offset od cursor pagination?
Offset (skip/OFFSET) mówi bazie, ile rekordów pominąć — jest prosty i pozwala skoczyć do dowolnej strony, ale przy dużych przesunięciach baza musi fizycznie przejść przez wszystkie pominięte wiersze, co go spowalnia. Cursor zamiast tego pamięta pozycję ostatniego elementu (np. jego ID albo datę) i pobiera rekordy „po" nim — jest szybki niezależnie od skali, ale działa sekwencyjnie, więc nie przeskoczysz nim od razu do strony pięćdziesiątej.
Czy infinite scroll szkodzi SEO?
Może. Przy infinite scroll Google zwykle widzi tylko pierwszą porcję treści, ponieważ kolejne ładują się dopiero w reakcji na scroll, którego robot nie wykonuje tak jak użytkownik. Jeśli treść ma być indeksowana, użyj numerycznej paginacji z prawdziwymi adresami URL. Infinite scroll zostaw dla paneli użytkownika, feedów i widoków, które nie muszą trafiać do wyszukiwarki. Taki podział jest najbardziej optymalny i bezpieczny.
Czy nadal trzeba dodawać rel=prev i rel=next?
Nie. Google oficjalnie przestał używać rel="prev" i rel="next" jako sygnału do rozumienia serii paginowanych stron. Generowanie ich przez metadata.other tworzy zresztą meta tagi, a nie linki relacyjne, więc nie spełnia nawet pierwotnej funkcji. Skup się na tym, co faktycznie działa: stabilne URL-e, poprawny canonical na każdej stronie, brak duplikatów i czytelne linkowanie między stronami.
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 rozwija własne projekty side-projecty.
Astro 7 to nowa era szybkości. Dzięki Vite 8 i usprawnieniom kompilacji, skrócisz czas builda nawet o 61%. Sprawdź, kiedy migrować, a kiedy poczekać na stabilizację.
Agentic Browsing w PageSpeed Insights pokazuje, czy strona jest czytelna dla agentów AI. Sprawdź, co bada Lighthouse i jak przygotować React, Astro i Next.js.