← Insights
2 czerwca 2026 Insights PL

zrodelko.org — jak zbudowałem full-stack stronę dla żłobka z WCAG 3.0, ElevenLabs i pipelinem GSC

Żłobek w Beskidach potrzebował strony zastępującej Canva — dostępnej, dwujęzycznej, z artykułami czytanymi przez lektora i automatyczną synchronizacją Facebooka. Oto jak zbudowałem to od zera na Next.js 15, Payload CMS 3 i Supabase, z pełnym potokiem analitycznym GSC.

zrodelko.org — jak zbudowałem full-stack stronę dla żłobka z WCAG 3.0, ElevenLabs i pipelinem GSC

Kiedy Źródełko — żłobek i przedszkole w Gruszowcu w Beskidzie Wyspowym — zwróciło się do mnie z prośbą o nową stronę, miałem jasny obraz punktu startowego: strona zbudowana w Canva, bez zarządzania treścią, bez dostępności, bez dwujęzyczności. I bez żadnej drogi do rozbudowy.

Mógłbym postawić WordPress i skończyć w tydzień. Zamiast tego podjąłem decyzję, której nie żałuję: pełny custom stack, który dałoby się rozwijać latami.

To co powstawało przez kilka miesięcy stało się jednym z technicznie ciekawszych projektów, które zrealizowałem.

Stack: dlaczego Next.js 15 + Payload CMS 3

Kluczowa decyzja architekturalna: chciałem CMS-a wbudowanego w aplikację Next.js, a nie osobnego procesu. Payload CMS 3 umożliwia dokładnie to — jeden deployment na Vercel, panel admina pod /admin, baza PostgreSQL na Railway.

Pełny stack:

Warstwa Technologia
Framework Next.js 15.4 + React 19, App Router, TypeScript 5.7
CMS Payload CMS 3 (embedded, Lexical editor, lokalizacja PL/EN)
Baza danych PostgreSQL (Railway), 8 kolekcji + 2 globale
Stylowanie Tailwind CSS 3 + CSS custom properties (:root variables)
AI / TTS ElevenLabs (generowanie audio artykułów) + Media Session API
Integracje Facebook Graph API v19 (ISR 2h, cron revalidation)
Analityka SEO Google Search Console API + Supabase Edge Functions + GitHub Actions
Python Pillow, OpenCV, face_recognition (HOG), rembg, FFmpeg
Infra Vercel (SSR + CI/CD) + Railway (PostgreSQL) + Supabase (Edge Functions)

WCAG 3.0 — toolbar dostępności zbudowany od zera

Większość stron instytucjonalnych udaje, że „jest dostępna” — ma alt w obrazkach i na tym koniec. Zdecydowałem się zaimplementować pełny toolbar dostępności zgodny z WCAG 3.0, z dziewięcioma niezależnymi parametrami sterowanymi przez CSS custom properties na :root.

Komponent AccessibilityToolbar pozwala użytkownikowi regulować:

Typografia
Rozmiar tekstu (0.8×–1.6×)
Wysokość linii
Odstęp liter i słów
Czcionka dyslektyczna

Wizualne
Wysoki kontrast
Tryb ciemny (CSS invert)
Redukcja animacji
Wzmocniony focus ring

Każdy parametr działa przez zmienną CSS ustawianą na document.documentElement. Np. rozmiar tekstu to font-size: calc(16px * var(--text-size-scale)) na html — zmiana jednej zmiennej skaluje wszystko na stronie proporcjonalnie. Stan zapisywany jest w localStorage i przywracany przy każdej wizycie.

Dlaczego to ważne dla OPP: Organizacje pożytku publicznego mają prawny obowiązek zapewnienia dostępności cyfrowej (WCAG 2.1 AA jako minimum). Źródełko przyjmuje dzieci z niepełnosprawnościami — rozsądne, żeby strona była dostępna dla wszystkich rodziców.

ElevenLabs TTS + AudioPlayer + Media Session API

Strefa Rodziców to hub z artykułami eksperckimi o wychowaniu, rozwoju dziecka i metodyce Pikler. Postanowiłem, że kluczowe artykuły będą miały wersję audio — czytaną przez lektorkę z głosem wygenerowanym w ElevenLabs.

Pipeline wygląda tak:

1
Generowanie audio (Python)
Skrypt Python wywołuje ElevenLabs SDK z multilingualnym modelem TTS — tekst artykułu zamieniany jest na wysokiej jakości MP3 serwowany statycznie przez Next.js.
2
Komponent AudioPlayer (React)
Własny player z paskiem postępu, przyciskiem play/pause, timerem i seekiem klikowym. Zero zewnętrznych bibliotek — 125 linii TypeScript.
3
Media Session API
Integracja z systemem operacyjnym: tytuł artykułu i avatar lektorki pojawiają się na ekranie blokady telefonu. Działają przyciski play/pause i przewijanie ±10s z poziomu słuchawek lub Bluetooth.

Efekt: rodzic może uruchomić artykuł, schować telefon do kieszeni i słuchać podczas gotowania obiadu.

Facebook ISR — aktualności bez panelu admina

Źródełko aktywnie publikuje na Facebooku — to naturalne centrum komunikacji ze społecznością. Zamiast prosić obsługę o podwójne wklejanie postów, zbudowałem automatyczną synchronizację.

Komponent FacebookPosts to Server Component z ISR (Incremental Static Regeneration) — Next.js buduje stronę ze świeżymi danymi z Facebook Graph API i trzyma cache przez 2 godziny. Treść posta, zdjęcie i data są pobierane automatycznie; tytuł wyciągany z pierwszej linii, reszta staje się excerptm. Daty lokalizowane są do języka strony. Dodatkowy endpoint pozwala wymusić odświeżenie przez zewnętrzny cron.

Pipeline GSC: GitHub Actions → Supabase Edge → email

Zbudowałem pełny, bezserwerowy pipeline analityczny dla Google Search Console — żeby klient dostawał co poniedziałek email z raportem widoczności strony, a dane historyczne były dostępne do analizy.

Supabase Edge Function (Deno)
Codziennie pobiera dane z GSC Search Analytics API — kliki, wyświetlenia, CTR i pozycja dla frazy, strony i daty. Wszystko trafia do Supabase PostgreSQL z historią i widokami tygodniowymi.
📧
GitHub Actions: tygodniowy raport
Co poniedziałek workflow generuje HTML email z top frazami i stronami ostatnich 7 dni i wysyła przez SMTP. Historia danych jest commitowana do repozytorium.
🗄
PostgreSQL: historia i widoki
Dane przechowywane są z unikalnością per dzień i fraza/strona. Widoki SQL agregują tygodniowe podsumowania gotowe do wyświetlenia lub wysłania w raporcie.

Koszt tego pipeline’u: zero. Cały setup działa na darmowych tierach — GitHub Actions, Supabase Edge Functions i PostgreSQL mieszczą się w bezpłatnych limitach przy tej skali ruchu.

Python: automatyczne przetwarzanie zdjęć dzieci

Żłobek ma tysiące zdjęć dzieci z zajęć. Problem: RODO wymaga, żeby nie publikować rozpoznawalnych twarzy dzieci bez osobnej zgody każdego z rodziców.

Rozwiązanie: skrypt Python używający face_recognition (dlib HOG) do wykrywania twarzy i cv2.GaussianBlur do ich rozmycia. Dodatkowy skrypt z rembg do usuwania tła ze zdjęć pracowników. FFmpeg kompresuje filmy do rozsądnego rozmiaru — zdjęcia nie puchną na serwerze.

Formularz zapisu: 5 kroków, walidacja wieku, email do rodzica

Komponent RegistrationForm to 617 linii TypeScript obsługujących pełny proces rekrutacji: wybór żłobek/przedszkole → dane dziecka → dane rodzica → zdrowie → zgody RODO.

Jeden element, który naprawdę działa dobrze: auto-suggest daty rozpoczęcia. Na podstawie daty urodzenia dziecka i wybranego typu placówki system automatycznie proponuje najbliższy termin rekrutacyjny (marzec lub wrzesień), kiedy dziecko będzie w odpowiednim przedziale wiekowym. Żłobek: 10–36 miesięcy. Przedszkole: 30–72 miesiące.

Po submicie endpoint zapisuje dane do Payload CMS, wysyła email potwierdzający do rodzica i email wewnętrzny do administracji — przez SMTP skonfigurowany przez @payloadcms/email-nodemailer.

JSON-LD i LLMO/GEO: optymalizacja pod AI search engines

Standardowe SEO to za mało, jeśli zależy ci na widoczności w AI Overviews (Google SGE) i odpowiedziach ChatGPT/Perplexity. LLMO (Large Language Model Optimization) i GEO (Generative Engine Optimization) to optymalizacja struktury treści pod modele językowe — nie tylko pod crawlery.

Co zostało zaimplementowane:

  • Organization schema z typem ChildCare + LocalBusiness, z geolokalizacją (621 m n.p.m.) i areaServed dla gminy Dobra i powiatu limanowskiego
  • Article schema z author (Person), dateModified, inLanguage i mainEntityOfPage dla każdego artykułu w Strefie Rodziców
  • FAQPage schema na stronie głównej i podstronie planu owego — pytania i odpowiedzi, które AI może serwować bezpośrednio
  • BreadcrumbList na każdej podstronie
  • Odpowiedzi pisane w stylu encyklopedycznym — kompletne zdania, bez fragmentów wyrwanych z kontekstu

Efekt: strona ma szansę pojawiać się w odpowiedziach AI na zapytania o „żłobek Beskidy”, „żłobek Dobra Limanowa” czy „żłobek WCAG” — nie tylko w tradycyjnych wynikach wyszukiwania.

Podsumowanie

zrodelko.org zaczęło się jako „nowa strona dla żłobka”. Skończyło się jako projekt, który nauczył mnie kilku rzeczy:

  • Payload CMS 3 embedded w Next.js to naprawdę dojrzałe rozwiązanie — zero osobnego backendu, jedno repo, jeden deploy
  • WCAG 3.0 przez CSS custom properties to eleganckie podejście — jeden punkt zmiany, cały UI reaguje
  • Media Session API jest bardzo niedoceniana — podwyższa UX audio o rząd wielkości bez żadnego kosztu
  • Bezserwerowy pipeline GSC (Edge Functions + GitHub Actions) działa niezawodnie i praktycznie za darmo

Projekt jest wdrożony produkcyjnie na zrodelko.org. Jeśli prowadzisz małą organizację i zastanawiasz się, czy taki stack ma sens — tak, ma. Zwłaszcza jeśli zależy ci na rosnącej stronie, którą klient może obsługiwać samodzielnie.

// Porozmawiajmy //

Wdrażasz AI, automatyzację lub VR w swojej organizacji? Chętnie porozmawiam o Twoim przypadku.

Umów rozmowę →