Strona firmowa · all4cups Sp. z o.o. · 2026 · 3 tygodnie
all4cups - strona firmowa na WordPressie bez page buildera
Zamiast page buildera motyw przechwytuje żądanie i oddaje gotowy plik HTML - klient zachowuje wp-admin i formularz, którego używał, a treść strony przestaje być składana z bazy przy każdym wejściu.
- WordPress
- PHP
- HTML
- CSS Custom Properties
- JavaScript
- Contact Form 7
- Three.js
Wyzwanie
all4cups produkuje kubki wielokrotnego użytku i gadżety z nadrukiem dla festiwali, koncertów, stoków i firm. Sprzedaż idzie przez zapytanie ofertowe, nie przez koszyk, a każda technika znakowania ma inne minimum: IML zaczyna się od 18 000 sztuk, druk UV nie ma minimum w ogóle. Strona, która tego nie mówi wprost, produkuje dwa rodzaje rozczarowania naraz - agencja eventowa pyta o 200 kubków w technologii, której nie da się zrobić poniżej osiemnastu tysięcy, a duży klient nie wie, że w ogóle jest w dobrym miejscu. Do tego poprzednia wersja stała na page builderze, więc każda zmiana treści oznaczała klikanie w edytorze i stronę, która składa się z bazy przy każdym wejściu.
Nasze rozwiązanie
Strona jest statycznym HTML-em, ale mieszka w WordPressie. Motyw przechwytuje żądanie w `template_redirect`, mapuje adres na plik w katalogu motywu i oddaje go bezpośrednio - z pominięciem pętli, bazy i page buildera. Ścieżki `wp-admin`, `wp-json` i `wp-login.php` są wyłączone z tego przechwytywania, więc panel, REST i formularz Contact Form 7 działają dalej. Treść nie jest wymyślona: minimalne nakłady, pojemności i techniki znakowania pochodzą z pliku faktów biznesowych spisanego z rozmów z klientem. Przepisy o plastiku jednorazowym dostały własną podstronę, bo to one są powodem, dla którego organizator w ogóle szuka kubka wielorazowego.
187 ms
Czas do pierwszego bajtu
0,44 s
Pierwsze renderowanie treści
15
Żądań na stronę główną
Co zbudowaliśmy
- 01 Statyczny motyw WordPress: HTML z katalogu motywu, bez page buildera i bez renderowania szablonu
- 02 wp-admin, REST i logowanie wyłączone z przechwytywania, panel klienta działa bez zmian
- 03 Formularz kontaktowy wysyłany do Contact Form 7 przez REST, bez zewnętrznego serwisu
- 04 Podstrona Dyrektywa SUP: przepisy jako punkt wyjścia rozmowy, nie jako stopka
- 05 Minimalne nakłady i techniki znakowania wprost w treści, z pliku faktów biznesowych
- 06 Własny baner zgód na localStorage: przed decyzją nie startuje żaden skrypt
- 07 Animacje wejścia z zabezpieczeniem - awaria JavaScriptu nie zostawia pustej strony
- 08 Menu mobilne, sticky header, akordeon FAQ i scrollspy w jednym pliku bez zależności
- 09 Konfigurator 3D kubków zbudowany i zaparkowany do czasu decyzji o budżecie
Spis treści +
- Punkt wyjścia
- Decyzje, które ukształtowały projekt
- WordPress jako panel, nie jako silnik strony
- Formularz zostaje w WordPressie
- Przepisy jako podstrona, nie jako stopka
- Minimalne nakłady napisane wprost
- Animacje, które nie mogą zabrać treści
- Zgody bez wtyczki i bez skryptów na zapas
- Konfigurator, którego nie ma na stronie
- Co z tego wyszło
- Technicznie
Punkt wyjścia
Organizator festiwalu nie szuka „kubka”. Szuka kubka, który wróci z mycia na kolejny dzień, zmieści się w przepisach o plastiku jednorazowym i będzie miał na sobie logo sponsora. Firma zamawiająca gadżety na koniec roku szuka czegoś zupełnie innego, a oba zapytania trafiają do tej samej skrzynki.
Problem nie polegał więc na opisaniu, co all4cups potrafi zrobić. Polegał na tym, żeby osoba, która wejdzie na stronę, w kilkanaście sekund wiedziała, czy jej zamówienie w ogóle mieści się w tym, co ta firma robi - i którą techniką.
Decyzje, które ukształtowały projekt
WordPress jako panel, nie jako silnik strony
Klient miał WordPressa i nie było powodu, żeby mu go zabierać: tam siedzi formularz, tam są dostępy, tam przychodzą zapytania. Powodem do zmiany był tylko page builder, przez który przechodziła każda strona. To jest zresztą decyzja, którą przy stronie firmowej podejmuje się raz i żyje z nią latami - rozpisaliśmy ją szerzej w tekście o tym, czy wybrać WordPressa czy Next.js.
Motyw przechwytuje żądanie w template_redirect, sprawdza, czy adresowi odpowiada plik HTML w katalogu motywu, i oddaje go bezpośrednio. Nie ma pętli, nie ma składania treści z bazy, nie ma wtyczki, która renderuje układ. Lista wyjątków - wp-admin, wp-json, wp-login.php, wp-content, wp-includes - jest sprawdzana przed wszystkim innym, więc panel i REST działają dokładnie tak jak przedtem.
Warto powiedzieć wprost, czego to rozwiązanie nie robi: WordPress nadal startuje w całości. Wczytuje opcje, wtyczki i sesję, zanim motyw w ogóle dostanie szansę przechwycić żądanie. Znika renderowanie strony, nie znika WordPress - inaczej nie działałby ani panel, ani endpoint formularza.
Kompromis jest uczciwy i trzeba go nazwać: klient nie edytuje już treści przez kliknięcie w edytorze. Zmiana tekstu to zmiana pliku i wgranie motywu. W zamian strona przestaje zależeć od wtyczki, która za dwa lata może przestać być rozwijana, i ładuje się jako zwykły plik.
Formularz zostaje w WordPressie
Statyczny front nie musi znaczyć zewnętrznego serwisu do formularzy. Formularz zbiera dane w przeglądarce i wysyła je do endpointu Contact Form 7 przez REST, czyli do tej samej wtyczki i tej samej skrzynki, z której klient korzystał wcześniej. Zapytania ofertowe nie przechodzą przez trzecią firmę i nie trzeba ich opisywać w polityce prywatności jako powierzenia danych.
Ta sama obsługa formularza rozpoznaje, czy działa na produkcji, czy w makiecie lokalnej. W makiecie nic nie wysyła i mówi o tym wprost, zamiast udawać, że wiadomość poszła.
Co do samej treści formularza: im mniej pól, tym więcej zapytań, ale przy zamówieniach z minimum osiemnastu tysięcy sztuk kilka pytań kwalifikujących oszczędza obu stronom tygodnia korespondencji. Rozpisaliśmy ten kompromis osobno, w tekście o formularzu kontaktowym, który generuje leady.
Przepisy jako podstrona, nie jako stopka
Dyrektywa o plastiku jednorazowym jest powodem, dla którego organizator w ogóle zaczyna szukać kubka wielorazowego. Wylądowanie tego tematu w akapicie na dole strony głównej byłoby zmarnowaniem najlepszego argumentu sprzedażowego, jaki ta branża ma.
Dostał więc własny adres z wyjaśnieniem, co się zmienia i kiedy. To także osobne zapytanie w wyszukiwarce i osobny moment, w którym ktoś szuka odpowiedzi, a nie produktu.
Minimalne nakłady napisane wprost
IML od 18 000 sztuk, do sześciu wzorów w ramach minimum, pojemności 0,3, 0,4 i 0,5 litra. Druk UV bez minimum. Sublimacja i laser w dowolnej ilości.
Te liczby siedzą w osobnym pliku z faktami biznesowymi i są jedynym źródłem dla treści. Pokusa, żeby napisać „realizujemy zamówienia każdej wielkości”, jest duża i kosztuje potem godziny na odpisywanie ludziom, dla których odpowiedź brzmi „nie w tej technice”. Strona, która mówi „nie” wcześniej, zostawia w skrzynce zapytania, na które warto odpowiadać.
Animacje, które nie mogą zabrać treści
Sekcje pojawiają się przy przewijaniu, co jest ładne dokładnie do momentu, w którym JavaScript się nie wykona. Wtedy element z ustawioną przezroczystością zero zostaje niewidoczny, a użytkownik widzi pustą stronę i nie ma pojęcia, że coś poszło nie tak.
Są więc trzy zabezpieczenia. Elementy widoczne w kadrze przy załadowaniu dostają stan końcowy od razu, bez przejścia, żeby strona nie migała przy odświeżeniu. Przy prefers-reduced-motion albo braku IntersectionObserver wszystko jest po prostu widoczne. A skrypt awaryjny sprawdza po chwili, czy nagłówek się w ogóle wyrenderował, i jeśli nie - odsłania wszystko siłą.
Zgody bez wtyczki i bez skryptów na zapas
Baner zgód to kilkadziesiąt linii: wybór zapisany w localStorage, przycisk w stopce do zmiany decyzji, zdarzenie a4:consent jako punkt zaczepienia. Dopóki użytkownik nie zdecyduje, nie startuje żaden skrypt analityczny ani marketingowy - bo nie ma żadnego wpiętego. Miejsce na niego jest przygotowane i czeka.
Konfigurator, którego nie ma na stronie
Do projektu powstało studio podglądu kubków w 3D: własne siatki, nakładanie grafiki, eksport packshotów. Nie jest linkowane z żadnego miejsca w nawigacji, stopce ani CTA.
Klient nie budżetuje na razie strony z konfiguratorem, a wypuszczenie takiego narzędzia „przy okazji” znaczyłoby wsparcie, poprawki i pytania do końca życia projektu. Kod został, decyzja i sposób przywrócenia są zapisane. To nie jest porzucona funkcja, tylko funkcja z datą do ustalenia.
Co z tego wyszło
Pomiar strony głównej z 13 września 2026, przeglądarka bez cache, łącze stacjonarne: 187 ms do pierwszego bajtu, 0,44 s do pierwszego renderowania treści, 0,51 s do zdarzenia load. Piętnaście żądań na całą stronę: dokument, dwa arkusze stylów, jeden plik JavaScript, siedem obrazów i cztery pliki fontów. Jedyny host spoza domeny klienta to Google Fonts.
Uczciwa uwaga do tych liczb: nie ma tu porównania „przed i po”. Poprzednia wersja na page builderze została zastąpiona, zanim ktokolwiek ją zmierzył, więc nie mamy jej wyników i nie zamierzamy ich szacować. To, co wyżej, to stan po wdrożeniu, nie dowód na poprawę o iks procent.
Na tej stronie zostaje jeszcze rezerwa i widać, gdzie: 624 kB transferu to prawie w całości obrazy. Sam kod motywu to 45 kB stylów i 9 kB skryptu. Jeśli kiedyś trzeba będzie zejść niżej, ruszamy grafikę, nie architekturę - co jest dokładnie tą sytuacją, którą opisujemy w checkliście Core Web Vitals.
Technicznie
Motyw WordPress bez zależności: jeden plik functions.php z routingiem i typami MIME, jeden arkusz stylów na zmiennych CSS, jeden plik JavaScript na wszystkie interakcje. Kolorystyka marki siedzi w --navy i --orange, nie w klasach. Treści pisane w makiecie lokalnej, wdrażane jako paczka motywu, formularz na Contact Form 7 przez REST. Studio 3D kubków na Three.js, trzymane poza publiczną nawigacją.
Jedno zastrzeżenie na przyszłość, bo to realne ryzyko tego układu: skoro strona jest paczką plików, a nie wpisami w bazie, to zmiana klikana bezpośrednio na serwerze ginie przy następnym wgraniu motywu. Wdrożenie musi iść z repozytorium albo wcale.
Zrzuty ekranu
Podobny problem do rozwiązania?
Napisz krótko, o co chodzi — wycena wraca w 24 godziny.
Zapytaj o wycenę →