Żegnaj, WordPressie: nowa strona gabinetu psychologicznego na własnym stacku

PsychodietetykNaMiare.pl to krakowska poradnia psychologiczna i psychodietetyczna, prowadząca konsultacje stacjonarne w kilku gabinetach na terenie miasta oraz sesje w 100% online.
Poprzednia witryna poradni działała na WordPressie z page builderem Elementor. Strona jakoś funkcjonowała, ale była ociężała, regularnie sypała się po nocnych aktualizacjach wtyczek, a wdrożenie jakiejkolwiek poprawki wiązało się ze stresem, czy coś nagle nie zniknie. Decyzja była krótka: koniec z wordpressem i klejeniem wtyczek – budujemy serwis od zera na nowoczesnym, bezkompromisowym stacku.
Stack technologiczny
- Framework i frontend: Next.js 15 (App Router) z React Server Components (React 19)
- Język i style: TypeScript, Tailwind CSS
- System CMS: Payload CMS 3 z bazą PostgreSQL (uruchomiony wewnątrz tej samej aplikacji Next.js)
- Infrastruktura: Docker (multi-stage build), GitLab CI/CD, ręcznie pisane idempotentne migracje SQL
Poniżej konkretne zestawienie obszarów, w których nowa architektura deklasuje poprzednie rozwiązanie na WordPressie.
1. Bezkompromisowa szybkość bez walki z wtyczkami
- Jak było: WordPress z page builderem wysyła do przeglądarki tony zbędnego kodu CSS i JavaScriptu – często ładując skrypty dla modułów, których w ogóle nie ma na danej podstronie.
- Jak jest teraz: Prawie cały serwis renderowany jest po stronie serwera za pomocą React Server Components (RSC), więc przeglądarka użytkownika otrzymuje gotowy, lekki kod HTML. JavaScript trafia wyłącznie do komponentów, które faktycznie wymagają interaktywności: menu nawigacyjnego, akordeonów FAQ, formularza kontaktowego czy banera cookies.
- Obrazy są automatycznie konwertowane do nowoczesnych formatów AVIF i WebP oraz skalowane pod konkretny ekran za pomocą modułu
next/image. - Typografia serwowana jest bezpośrednio z naszej własnej domeny dzięki
next/font(zero odpytywania zewnętrznych serwerów Google Fonts). - Ciężki widget zewnętrznego systemu do rezerwacji wizyt jest leniwie dociągany (lazy loading) dopiero w momencie, gdy użytkownik przewinie stronę w jego pobliże.
Na WordPressie każda z tych optymalizacji wymagałaby osobnej wtyczki (do cache'u, kompresji zdjęć, opóźnionego ładowania), a te wtyczki nierzadko wchodziły ze sobą w konflikty.
Wynik w Google PageSpeed Insights: 98/100 na urządzeniach mobilnych oraz 100/100 na komputerach stacjonarnych.
2. Zero wtyczek aktualizujących się w nocy
Na WordPressie stabilność strony jest dokładnie tak wysoka, jak jakość jej najsłabszej wtyczki. Jedna nieprzemyślana aktualizacja potrafi rozjechać layout albo otworzyć lukę bezpieczeństwa w systemie.
W nowym projekcie nie ma ani jednej wtyczki firm trzecich. Każda biblioteka ma precyzyjnie przypiętą wersję w plikach konfiguracyjnych i zmienia się wyłącznie wtedy, gdy sam o tym zdecyduję po lokalnych testach. Mniejsza liczba ruchomych elementów to brak niespodzianek, gdy nikt nie patrzy, oraz drastycznie zredukowana powierzchnia potencjalnego ataku.
3. Wszystko w kodzie i w Gicie, zero konfiguracji „wyklikiwanej” w bazie
Na WordPressie potężna część logiki leży zakopana w bazie danych – opcje wtyczek, układ pól, stan widgetów. Niemal nie da się tam śledzić historii zmian ani bezpiecznie wycofać błędnej konfiguracji.
Tutaj definicje typów treści, pól formularzy w panelu i reguł biznesowych to czysty kod w TypeScripcie pod pełną kontrolą Gita. Panel administracyjny, schemat tabel w PostgreSQL i interfejsy frontendowe generowane są z jednego, wspólnego źródła prawdy. Każda zmiana struktury bazy danych to wersjonowana migracja SQL w repozytorium – wykonuje się automatycznie przy starcie i nigdy nie nadpisuje treści wprowadzonych przez klienta.
4. Wdrożenia bez FTP i bez strachu
Każde polecenie git push uruchamia zautomatyzowany potok GitLab CI/CD:
- Skanowanie zależności i kontrola pod kątem wycieków sekretów.
- Lintery i rygorystyczna kontrola typów TypeScript.
- Testy automatyczne.
- Budowanie zoptymalizowanego obrazu Dockerowego.
- Automatyczny deploy na serwer za pomocą webhooka.
Obraz Dockera jest w 100% identyczny na maszynie deweloperskiej i na serwerze produkcyjnym. Jeśli aplikacja przeszła testy lokalnie, wstanie bezbłędnie na produkcji. W razie jakichkolwiek problemów powrót do poprzedniej wersji sprowadza się do natychmiastowego przełączenia tagu kontenera. Skończyły się czasy aktualizowania plików bezpośrednio na produkcji przez FTP i modlitwy, żeby strona nie zgasła.
5. Panel administracyjny uszyty na miarę, nie uniwersalny kombajn
Elementor oferuje tysiące opcji stylowania, które dla osoby nietechnicznej są wyłącznie polem minowym. Wystarczy jedno przypadkowe kliknięcie, by popsuć marginesy na telefonach.
W Payload CMS klientka otrzymała przejrzysty panel z dokładnie takimi polami, jakich realnie potrzebuje jej gabinet – w całości po polsku i z czytelnymi podpowiedziami. Przykładowo: dni przyjęć w poszczególnych gabinetach wybiera się z gotowej listy klikalnych tagów, a nie wpisuje ręcznie w pole tekstowe. Wyklucza to ryzyko literówki, która mogłaby zmylić pacjenta lub uniemożliwić robotom Google poprawne odczytanie danych adresowych. Godziny przyjęć są opcjonalne – bez nich strona elegancko prezentuje same dni. Drobiazgi architektoniczne, dzięki którym właścicielka poradni może bez obaw samodzielnie zarządzać treścią.
6. Strukturyzowane SEO z realnych danych, nie z kombajnu SEO
Na WordPressie pozycjonowanie oznacza instalację kolejnej ciężkiej wtyczki z własnymi, często niespójnymi ustawieniami.
W nowej architekturze mikrodane strukturalne Schema.org (profil specjalisty, dane poradni, adresy fizycznych gabinetów, cennik usług, pytania z sekcji FAQ) generowane są dynamicznie z tych samych rekordów, które klientka edytuje w panelu. Dzięki temu dane dla wyszukiwarki są zawsze w 100% zsynchronizowane z tym, co widzi pacjent.
Mapa strony (sitemap.xml) buduje się na żywo wprost z bazy danych. Dodatkowo wszystkie historyczne adresy URL ze starego WordPressa – które skrupulatnie odtworzyłem z archiwów Wayback Machine – otrzymały stałe przekierowania 301 na nowe podstrony, zabezpieczając wypracowane przez lata pozycje w wyszukiwarkach.
7. Zero licencji i zero vendor lock-in
Brak abonamentów za Elementor Pro, zaawansowane wtyczki formularzy czy rozszerzenia SEO, za które co roku trzeba płacić odnawialne licencje. Cały serwis to nasz autorski kod oparty o wolne oprogramowanie open-source – witrynę można bez przeszkód przenieść na dowolny serwer VPS lub do chmury w dowolnym momencie.
Architektura techniczna w szczegółach
Frontend i renderowanie
Warstwa wizualna działa na Next.js 15 z architekturą App Router i React 19. Niemal wszystkie podstrony są komponentami serwerowymi (React Server Components). Pobierają dane bezpośrednio z silnika CMS za pomocą mechanizmu Payload Local API – bezpośredniego wywołania funkcji wewnątrz tego samego procesu Node.js. Eliminuje to zbędny narzut sieciowy HTTP oraz konieczność utrzymywania osobnego API gatewaya.
Komponenty klienckie ("use client") zostały ograniczone do absolutnego minimum (menu, rozwijane panele FAQ, interaktywny formularz, baner RODO). Treść z edytora wizualnego konwertowana jest do czystego HTML-a już po stronie serwera – ciężki kod edytora nigdy nie trafia do przeglądarki użytkownika. Dzięki temu strona główna przy pierwszym wejściu pobiera zaledwie ok. 115 kB JavaScriptu.
Style bazują na Tailwind CSS ze scentralizowaną paletą kolorów marki, a krytyczny arkusz CSS jest wstrzykiwany bezpośrednio w kod HTML (inline), eliminując zjawisko blokowania renderowania (render-blocking resources). Zasoby graficzne optymalizuje next/image (formaty AVIF/WebP, responsywne srcset, agresywne cache'owanie), a fonty serwowane są lokalnie przez next/font. Ikony pochodzą z bibliotek Lucide i Tabler – importowane są selektywnie, więc do paczki produkcyjnej wchodzą wyłącznie wykorzystywane glify. Pliki sitemap.xml, robots.txt oraz znaczniki JSON-LD generuje bezpośrednio Next.js Metadata API.
CMS i magazyn danych
Systemem zarządzania treścią jest Payload 3, zintegrowany bezpośrednio wewnątrz aplikacji Next.js, korzystający z bazy PostgreSQL za pośrednictwem adaptera Drizzle. Każdy typ danych to ścisła kolekcja lub global zdefiniowany w kodzie TypeScript. Z tej pojedynczej definicji Payload automatycznie buduje panel administracyjny, schemat tabel relacyjnych oraz interfejsy typów dla frontendu.
Jako edytor treści zaimplementowano Lexical z autorskimi konwerterami kolorów i formatowania list. Panel jest całkowicie zlokalizowany w języku polskim, wpisy blogowe wspierają wersjonowanie i wersje robocze (drafts), a przesłane zdjęcia są optymalizowane w locie przez bibliotekę sharp.
Formularz kontaktowy zapisuje każde zgłoszenie bezpośrednio w dedykowanej kolekcji w CMS oraz asynchronicznie wysyła powiadomienie e-mail przez API Resend. Baner cookies oparto o lekki skrypt vanilla-cookieconsent, a cała treść zgód jest w pełni edytowalna z poziomu panelu.
Konteneryzacja i CI/CD
Aplikacja została spakowana w wieloetapowy obraz Dockera (multi-stage build): osobne warstwy dla zależności deweloperskich, produkcyjnych, etapu kompilacji oraz minimalnego środowiska uruchomieniowego. Wykorzystuje tryb standalone Next.js i działa z uprawnieniami użytkownika nieuprzywilejowanego (non-root). Dzięki precyzyjnemu odsianiu pakietów potrzebnych tylko na etapie budowania rozmiar obrazu został zredukowany z 1,75 GB do zaledwie ok. 1 GB, co drastycznie skróciło czas pobierania i wdrażania kontenerów.
Zmiany w strukturze bazy danych to ręcznie pisane, w pełni idempotentne migracje SQL. Wykonują się automatycznie przed startem serwera aplikacji i nigdy nie naruszają treści wprowadzonych przez użytkownika.
Potok GitLab CI/CD realizuje pełny audyt: skanowanie podatności w paczkach npm i sekretów w kodzie, lintery, testy, budowanie obrazu z wykorzystaniem pamięci podręcznej warstw, publikację w prywatnym rejestrze oraz natychmiastowe wdrożenie produkcyjne za pomocą bezpiecznego webhooka. Pojedynczy git push sprawia, że po kilku minutach nowa wersja bezprzerwowo działa na produkcji.
Podsumowanie
Własny, nowoczesny stack technologiczny nie oznacza niekończącej się pracy przy utrzymaniu. Oznacza błyskawicznie działającą witrynę, drastyczną redukcję elementów, które mogłyby zawieść, oraz stuprocentową kontrolę nad każdą linijką kodu.
Najlepszy moment tego wdrożenia? Dzień, w którym klientka całkowicie samodzielnie dodała nowe ikony mediów społecznościowych w panelu – i nawet nie musiała do mnie w tej sprawie pisać.
👉 Zobacz wdrożenie na żywo: psychodietetyknamiare.pl
#Case Study#Core Web Vitals#Custom CMS#Docker#GitLab CI/CD#Headless CMS#Healthcare Website#Next.js#PageSpeed#Payload CMS#PostgreSQL#React Server Components#SEO#Structured Data#Tailwind CSS#TypeScript#Web Performance#WordPress migration
Komentarze
Jeszcze nikt nie skomentował. Bądź pierwszy.