Back-end

Rewalidacja w Next.js 13

Next.js to fullstackowy framework służący do budowy aplikacji webowych. Jedną z zalet Next.js jest statyczne generowanie stron, co pozwala na serwowanie gotowego HTMLa, kiedy użytkownik wchodzi na stronę. Czyni to ten framework niezwykle szybkim. Co jednak, kiedy strona nie jest do końca statyczna - dane w CMSie lub API zmieniają się raz na tydzień, miesiąc lub kwartał?

29 sie 2023

Problem

Chcemy rozwiązać następujący case: dane na stronie internetowej są bliskie statycznym - zmieniają się z częstotliwością np. tygodnia lub miesiąca. Chcemy pokazywać użytkownikom nową zawartość jak najszybciej, z zachowaniem jak największej wydajności.

 

Rozwiązanie pierwsze - Dynamic SSR

Dynamic SSR, czyli Dynamic Server-Side Rendering może być jednym z podejść do zastosowania w takim przypadku. Strona będzie budować HTMLa od nowa, za każdym razem kiedy user wejdzie na daną podstronę. To zapewnia użytkownikom dostęp do nowej zawartości praktycznie od razu. Implementacja polega na ustawieniu opcji revalidate na 0 w konfiguracji danej podstrony i wyłączeniu cache'a dla funkcji fetch(). Nie jest to jednak najlepsza opcja z punktu widzenia wydajności.

Rewalidacja w Next.js 13

Rozwiązanie drugie - Time-based ISR

ISR to skrót od Incremental Static Regeneration. Polega ona na rebudowaniu stron, tak, aby miały one zawsze świeże dane, przy jednoczesnych serwowaniu ich jako gotowy, zacache'owany HTML. Jednym ze sposobów implementacji ISR w Next.js 13 jest ustawienie wyżej wspomnianego atrybutu revalidate na ilość sekund, która ma upłynąć między rebuildami strony. Przykładowo revalidate ustawione na 3600 spowoduje, że strona będzie aktualizować serwowanego użytkownikom HTMLa co godzinę. Jest to dla nas jednak problematyczne rozwiązanie ze względu na potrzebę ustawienia "sztywnej" liczby sekund. Mamy tutaj dwa problemy:
 

  1. Aplikacja będzie budować od nowa widoki, które się nie zmieniły, pobierając te same dane wielokrotnie.
  2. Użytkownik będzie musiał czekać (maksymalnie) podaną przez nas liczbę sekund, żeby zobaczyć nową zawartość. Jest to problematyczne, ponieważ usecase uwzględniał natychmiastową aktualizację zawartości.

Sprawia to że Time-based ISR jest dobrą opcją dla case'ów, które nie wymagają natychmiastowej aktualizacji zawartości, a zatem dla naszego usecase'u pozostaje opcją awaryjną.

 

Rozwiązanie trzecie - Path-based on-demand ISR

Path-based on-demand ISR polega na budowaniu od nowa tylko tych podstron, na których zawartość się zmieniła i tylko wtedy, kiedy się zmieniła. Brzmi to jak idealne rozwiązanie dla nas. Załóżmy, że mamy artykuły - każdy znajduje się pod ścieżką /blog/[slug]. Wystawmy sobie endpoint, który przyjmuje informacje o tym co się zmieniło (np. artykuł) i użyjmy w nim funkcji revalidatePath zaimportowanej z next/cache. Następnie używamy jej w następujący sposób:

 

revalidatePath('/blog/[slug]')

 

W ten sposób użytkownik otrzyma nowe dane za następnym razem, kiedy wejdzie na stronę artykułu. Kawałek kodu powyżej zrewaliduje wszystkie segmenty, a co za tym idzie - wszystkie artykuły. 

 

Rozwiązanie czwarte - Tag-based on-demand ISR

Tag-based on-demand ISR różni się od rozwiązania trzeciego tym, że nie musimy wiedzieć, w którym miejscu zostałe użyte dane. Wystarczy że do konfiguracji funkcji fetch() dodamy:

 

next: { tags: ['my-tag'] }

 

I w ten sposób nasz request zostaje powiązany z tagiem, który przekazaliśmy. Teraz w enpoincie do rewalidacji możemy skonstruować odpowiedni tag na podstawie danych, które otrzymaliśmy przy aktualizacji contentu i wywołać funkcję do rewalidacji tagu, zaimportowaną z next/cache:

 

revalidateTag('my-tag')

 

W ten sposób wszystkie podstrony używające danych z requestów z tym tagiem zostaną zbudowane od nowa kiedy użytkownik na nie wejdzie. Jest to bardzo wygodny feature Nexta, ułatwiający pracę z case'ami pokroju footera strony budowanego na podstawie danych z CMSa - po prostu rewalidujemy odpowiedni tag, a Next znajduje używające go route'y za nas.

 

Podsumowanie

Next.js 13 daje masę możliwości w kwestii aktualizacji contentu. Pamiętajmy że feature'y opisane wyżej są dostępne tylko jeśli używamy App Routera. Część funkcji może też nie działać prawidłowo jeśli nasza instancja Nexta jest self-hosted, bez użycia platformy Vercel dedykowanej dla tego frameworku.

 

Źródło: https://nextjs.org/docs

FAQ

Najczęstsze pytania

  • Chodzi o przypadek, gdy dane na stronie są bliskie statycznym — zmieniają się z częstotliwością np. tygodnia lub miesiąca — a chcemy pokazywać użytkownikom nową zawartość jak najszybciej, z zachowaniem jak największej wydajności statycznie generowanych stron.
  • Dynamic Server-Side Rendering polega na budowaniu HTML-a od nowa za każdym razem, gdy użytkownik wchodzi na podstronę, co zapewnia dostęp do nowej zawartości praktycznie od razu. Implementacja polega na ustawieniu opcji revalidate na 0 i wyłączeniu cache'a dla funkcji fetch(). Nie jest to jednak najlepsza opcja z punktu widzenia wydajności.
  • Incremental Static Regeneration polega na przebudowywaniu stron, aby miały świeże dane, przy jednoczesnym serwowaniu ich jako gotowy, zcache'owany HTML. Ustawienie atrybutu revalidate np. na 3600 powoduje aktualizację co godzinę. Problemem jest „sztywna" liczba sekund: aplikacja przebudowuje widoki, które się nie zmieniły, a użytkownik musi czekać na nową zawartość — dlatego to opcja dla przypadków niewymagających natychmiastowej aktualizacji.
  • Polega na budowaniu od nowa tylko tych podstron, na których zawartość się zmieniła i tylko wtedy, kiedy się zmieniła. Wystawia się endpoint przyjmujący informację o zmianie (np. artykułu) i używa funkcji revalidatePath zaimportowanej z next/cache, np. revalidatePath('/blog/[slug]'). Użytkownik otrzyma nowe dane przy następnym wejściu na stronę.
  • Różni się od wariantu path-based tym, że nie trzeba wiedzieć, gdzie dane zostały użyte. Do konfiguracji fetch() dodaje się next: { tags: ['my-tag'] }, wiążąc request z tagiem, a następnie w endpoincie rewalidacji wywołuje revalidateTag('my-tag'). Wszystkie podstrony używające danych z tym tagiem zostaną przebudowane — Next sam znajduje route'y. Funkcje te są dostępne tylko z App Routerem.

Blog

Powiązane artykuły

Czytaj więcej
Back-end

Najważniejsze technologie do tworzenia aplikacji webowych na 2025 rok

Tworzenie aplikacji webowych zmienia się z roku na rok – pojawiają się nowe narzędzia, frameworki i podejścia, które ułatwiają pracę programistom i poprawiają jakość końcowych produktów. W 2025 roku szczególnie widać nacisk na wydajność, automatyzację i lepsze doświadczenia użytkownika. Technologie stają się coraz bardziej inteligentne, szybkie i dostępne. W tym artykule przedstawiamy najważniejsze trendy i rozwiązania, które kształtują web development w nadchodzącym czasie.

Tomasz Kozon
27 mar 2025
Back-end

Czym jest Commerce.js i jak może pomóc w e-commerce?

W dynamicznie zmieniającym się świecie internetowego handlu, Commerce.js pojawia się jako potężny sprzymierzeniec w kreowaniu skutecznej strategii e-commerce. Ten wysoko konfigurowalny framework, dający olbrzymie możliwości personalizacji sklepów internetowych, przenosi funkcjonalność e-handlu na zupełnie nowy poziom. W artykule przyjrzymy się bliżej jego możliwościom.

Tomasz Kozon
29 wrz 2025
Back-end

MERN Stack – charakterystyka i zastosowanie

MERN Stack to jeden z najpopularniejszych zestawów technologii wykorzystywanych do tworzenia nowoczesnych aplikacji webowych. Dzięki połączeniu MongoDB, Express, React oraz Node.js umożliwia on budowę wydajnych i skalowalnych rozwiązań opartych w całości na języku JavaScript. Stack ten jest chętnie wybierany zarówno przez startupy, jak i doświadczone zespoły developerskie.

Tomasz Kozon
14 gru 2025
Back-end

Biome w praktyce: nowoczesne narzędzie do formatowania i lintowania kodu

Utrzymanie spójnego stylu i wysokiej jakości kodu to jedno z największych wyzwań w nowoczesnych projektach programistycznych. Wraz z rozwojem ekosystemu JavaScript i TypeScript deweloperzy coraz częściej muszą korzystać z wielu narzędzi do formatowania i lintowania, co prowadzi do złożonej konfiguracji i potencjalnych konfliktów. Biome powstało jako odpowiedź na te problemy, oferując jedno, szybkie i spójne rozwiązanie typu all-in-one.

Tomasz Kozon
04 gru 2025
Back-end

Bazel – szybkie i skalowalne budowanie projektów

Bazel to jedno z najszybszych i najbardziej niezawodnych narzędzi do budowania projektów, stworzone z myślą o pracy na dużą skalę. Dzięki inteligentnemu zarządzaniu zależnościami i zaawansowanym mechanizmom cache’owania znacząco skraca czas kompilacji, nawet w bardzo rozbudowanych repozytoriach. Pozwala zespołom pracować szybciej, stabilniej i bardziej przewidywalnie, niezależnie od stosowanych języków programowania.

Tomasz Kozon
04 gru 2025
Back-end

Czym jest PocketBase?

PocketBase to narzędzie, które w ostatnim czasie zyskuje coraz większą popularność wśród frontendowców i twórców aplikacji. Oferuje ono szybki sposób na uruchomienie kompletnego backendu bez skomplikowanej konfiguracji i integracji wielu usług. Dzięki połączeniu bazy danych, API oraz systemu autoryzacji w jednym rozwiązaniu pozwala skupić się na budowie samej aplikacji.

Tomasz Kozon
03 gru 2025