Poznaj prosty system zapewniający spójne stany ładowania, błędu i pustki między web a mobile, dzięki czemu interfejsy generowane przez AI pozostają spójne i wymagają mniej poprawek na finiszu.

Stany ładowania, błędów i pustki to ekrany (lub małe bloki UI), które użytkownik widzi, gdy aplikacja czeka, coś się nie powiodło lub po prostu nie ma nic do pokazania. To normalne: sieć bywa wolna, uprawnienia są odrzucane, a nowe konta zaczynają się od zerowych danych.
Stają się niespójne, bo zwykle są dodawane późno i szybko. Zespoły najpierw budują happy path, a potem doklejają spinner, czerwony komunikat i placeholder „brak elementów” tam, gdzie UI się łamie. Zrób to w kilkudziesięciu ekranach i otrzymasz stos jednorazowych rozwiązań.
Szybkie iteracje pogarszają sprawę. Gdy UI powstaje szybko (w tym UI generowane przez AI), główny układ może pojawić się w minutach, a te stany łatwo pominąć. Każdy nowy ekran kończy z innym stylem spinnera, innym brzmieniem („Spróbuj ponownie” vs „Retry”) i innym umiejscowieniem przycisku. Szybki przyrost pracy na początku zamienia się potem w dopracowywanie tuż przed premierą.
Niespójne stany mylą użytkowników i kosztują zespoły czas. Ludzie nie potrafią odróżnić, czy pusty widok oznacza „brak wyników”, „jeszcze nie załadowano” czy „nie masz dostępu”. QA musi testować długi ogon małych wariantów, a błędy prześlizgują się, bo zachowanie różni się między web a mobile.
„Bałagan” często wygląda tak:
Cel jest prosty: wspólne podejście między web a mobile. Jeśli zespół szybko generuje funkcje (na przykład przy użyciu platformy Koder.ai), wspólny wzorzec stanów ma jeszcze większe znaczenie, bo każdy nowy ekran zaczyna spójnie domyślnie.
Większość aplikacji powtarza te same punkty narażenia: listy, strony szczegółów, formularze, pulpity. To miejsca, gdzie spinnery, bannery i komunikaty „nic tu nie ma” się mnożą.
Zacznij od nazwania i wystandaryzowania pięciu typów stanów:
Dwa specjalne przypadki wymagają własnych reguł, bo zachowują się inaczej:
Na wszystkich ekranach i platformach zachowaj spójną strukturę: miejsce pojawiania się stanu, styl ikony, ton i domyślne akcje (Retry, Refresh, Clear filters, Create). To, co może się różnić, to kontekst: nazwa ekranu i zdanie używające słów użytkownika.
Przykład: jeśli generujesz listę web i listę mobilną dla „Projekty”, powinny dzielić ten sam wzorzec zero-wyników. Etykieta akcji może dopasować się do platformy („Wyczyść filtry” vs „Resetuj”).
Jeśli każdy ekran wymyśla własny spinner, kartę błędu i wiadomość pustego stanu, dostaniesz tuzin nieznacznie różnych wersji. Najszybszym naprawieniem jest mały „state kit”, który każdy feature może podpiąć.
Zacznij od trzech wielokrotnego użytku komponentów: Loading, Error i Empty. Utrzymuj je celowo nudne. Mają być łatwe do rozpoznania i nie rywalizować z głównym UI.
Uczyń komponenty przewidywalnymi, definiując mały zestaw wejść:
Potem usztywnij wygląd. Zdecyduj raz o odstępach, typografii, wielkości ikony i stylu przycisku i traktuj to jak regułę. Gdy rozmiar ikony i typ przycisku pozostają takie same, użytkownicy przestają zauważać UI stanu i zaczynają mu ufać.
Ogranicz warianty, żeby kit nie stał się drugim systemem projektowym. Trzy rozmiary zwykle wystarczą: mały (inline), domyślny (sekcja) i pełnoekranowy (blokujący).
Jeśli generujesz ekrany w Koder.ai, prosta instrukcja jak „use the app StateKit for loading/error/empty with default variant” zapobiega dryfowi. To też zmniejsza porządki przed wydaniem między React web i Flutter mobile.
Kopia to część systemu, nie ozdoba. Nawet gdy układ jest spójny, improwizowane sformułowania sprawiają, że ekrany wydają się inne.
Wybierz wspólny głos: krótki, konkretny, spokojny. Powiedz, co się stało prostymi słowami, a potem powiedz użytkownikowi, co ma zrobić dalej. Większość ekranów potrzebuje jednego jasnego tytułu, krótkiego wyjaśnienia i jednej oczywistej akcji.
Kilka wzorców wiadomości pokryje większość sytuacji. Utrzymuj je krótkie, aby mieściły się na małych ekranach:
Unikaj niejasnych tekstów typu „Coś poszło nie tak” bez dalszego kontekstu. Jeśli naprawdę nie znasz przyczyny, powiedz, co wiesz i co użytkownik może zrobić teraz. „Nie udało się załadować projektów” jest lepsze niż samo „Błąd”.
Ustal jedną regułę: każdy błąd i pusty stan oferuje kolejny krok.
To ma jeszcze większe znaczenie przy UI generowanym przez AI, gdzie ekrany pojawiają się szybko. Szablony utrzymują spójność treści, więc nie przepisujesz dziesiątek jednorazowych komunikatów podczas końcowego dopracowywania.
Gdy ekrany stanu sugerują różne akcje z jednego ekranu na drugi, użytkownicy wahają się. Zespoły potem kończą przy dopracowywaniu przycisków i treści tuż przed wydaniem.
Zdecyduj, jaka akcja należy do każdego stanu i trzymaj się stałego umiejscowienia i etykiet. Większość ekranów powinna mieć jedną akcję główną. Jeśli dodajesz drugą, powinna wspierać główną ścieżkę, a nie z nią konkurować.
Trzymaj dozwolone akcje w wąskim zakresie:
Nudne przyciski to zaleta. Sprawiają, że UI jest znajome i pomagają zachować spójność generowanych ekranów.
Pokaż „Retry” tylko wtedy, gdy ponowna próba ma realistyczne szanse powodzenia (timeouty, niestabilna sieć, 5xx). Dodaj krótki debounce, aby wielokrotne tapnięcia nie spamowały żądań, i przełącz przycisk na stan ładowania podczas retry.
Po powtarzających się niepowodzeniach zachowaj ten sam przycisk główny i popraw pomocnicze informacje (np. wskazówkę „Sprawdź połączenie” lub „Spróbuj później”). Unikaj wprowadzania nowych układów tylko dlatego, że coś zawiodło dwukrotnie.
Dla szczegółów błędu pokaż prostą przyczynę, na którą użytkownik może zareagować („Twoja sesja wygasła. Zaloguj się ponownie.”). Ukrywaj techniczne szczegóły domyślnie. Jeśli są potrzebne, schowaj je za spójnym elementem „Details” na wszystkich platformach.
Przykład: lista „Projekty” nie załaduje się na mobile. Obie platformy pokazują tę samą główną akcję „Retry”, dezaktywują ją podczas ponawiania i po dwóch niepowodzeniach dodają małą wskazówkę o połączeniu zamiast zmieniać cały układ przycisków.
Traktuj spójność stanów jak małą zmianę produktową, a nie redesign. Idź inkrementalnie i ułatw adopcję.
Zacznij od szybkiego przeglądu tego, co już macie. Nie dąż do perfekcji. Zanotuj najczęstsze warianty: skeletony vs spinnery, pełnoekranowe błędy vs bannery, ekrany „brak wyników” z różnym tonem.
Plan wdrożenia, który pozostaje praktyczny:
Gdy komponenty istnieją, prawdziwym oszczędzającym czas elementem jest krótki zestaw reguł, który usuwa spór: kiedy stan blokuje całą stronę, a kiedy tylko kartę, oraz które akcje muszą być obecne.
Utrzymaj reguły krótkie:
Jeśli używasz generatora UI jak Koder.ai, te reguły szybko się zwrócą. Możesz poprosić o „use the state kit components” i uzyskać ekrany, które pasują do systemu zarówno w React web, jak i Flutter mobile, z mniejszą ilością poprawek.
Late polish work zwykle powstaje, bo obsługa stanów była budowana jako jednorazowe rozwiązania. Ekran „działa”, ale doświadczenie różni się za każdym razem, gdy coś trwa dłużej, zawodzi lub nie ma danych.
Skeletony pomagają, ale pozostawienie ich zbyt długo sprawia, że ludzie myślą, że aplikacja zamarła. Częstą przyczyną jest pokazanie pełnego skeletonu przy wolnym wywołaniu bez sygnału, że coś się dzieje.
Ogranicz czas: po krótkim opóźnieniu przełącz na lżejszą wiadomość „Wciąż ładowanie…” lub pokaż postęp, gdy to możliwe.
Zespoły często piszą nową wiadomość za każdym razem, nawet gdy problem jest ten sam. „Coś poszło nie tak”, „Nie można pobrać” i „Błąd sieci” mogą opisywać tę samą sytuację, ale brzmią niespójnie i utrudniają wsparcie.
Wybierz jedną etykietę na typ błędu i używaj jej na web i mobile, z tym samym tonem i poziomem szczegółu.
Klasyczny błąd to pokazanie pustego stanu zanim dane się załadują, lub pokazanie „Brak elementów” gdy prawdziwy problem to nieudane żądanie. Użytkownik podejmuje niewłaściwą akcję (np. zaczyna dodawać treść zamiast ponowić próbę).
Uczyń kolejność decyzji explicit: najpierw loading, potem error jeśli się nie udało, a pusty stan tylko kiedy żądanie zakończyło się sukcesem.
Błąd bez możliwości odzyskania tworzy martwe punkty. Przeciwieństwo też jest częste: trzy przyciski walczą o uwagę.
Trzymaj to krótkie:
Małe różnice sumują się: style ikon, padding, kształty przycisków. To też miejsce, gdzie UI generowane przez AI może odpłynąć, jeśli prompty różnią się per ekran.
Zablokuj odstępy, zestaw ikon i układ komponentów stanów, aby każdy nowy ekran dziedziczył tę samą strukturę.
Aby mieć spójną obsługę stanów między web a mobile, zrób „nudne” reguły jawne. Większość późnych poprawek pojawia się dlatego, że każdy ekran wymyśla własne zachowanie ładowania, timeouty i etykiety.
Dla pełnej strony wybierz jedno domyślne podejście: skeletony dla ekranów ciężkich od treści (listy, karty, pulpity) i spinner tylko dla krótkich oczekiwań, gdy układ jest nieznany.
Dodaj próg timeoutu, żeby UI nie wisiał w ciszy. Jeśli ładowanie trwa dłużej niż około 8–10 sekund, przełącz na jasny komunikat i widoczną akcję jak „Retry”.
Dla częściowych ładowań nie białkuj ekranu. Trzymaj istniejącą zawartość widoczną i pokaż mały wskaźnik postępu w pobliżu sekcji, która się odświeża (np. cienki pasek w nagłówku lub inline spinner).
Dla danych z cache preferuj „stare, ale użyteczne”. Pokaż zawartość z cache od razu i dodaj subtelny indicator „Refreshing…”, aby ludzie wiedzieli, że dane mogą się zmienić.
Offline to odrębny stan. Powiedz to wprost i powiedz, co nadal działa. Przykład: „Jesteś offline. Możesz przeglądać zapisane projekty, ale synchronizacja jest wstrzymana.” Zaproponuj jedną następną akcję, jak „Try again” lub „Otwórz zapisane”.
Zachowaj je spójne między platformami:
Jeśli generujesz UI za pomocą narzędzia jak Koder.ai, wbudowanie tych reguł w wspólny state kit pomaga utrzymać spójność każdego nowego ekranu domyślnie.
Wyobraź sobie prosty CRM z ekranem listy Kontaktów i ekranem szczegółów Kontaktu. Jeśli traktujesz stany ładowania, błędu i pustki jako jednorazowe, web i mobile szybko się rozjadą. Mały system utrzymuje porządek nawet, gdy UI powstaje szybko.
Pierwszy pusty stan (lista Kontaktów): użytkownik otwiera Kontakty i nic jeszcze nie ma. Na web i mobile tytuł pozostaje ten sam („Contacts”), komunikat wyjaśnia przyczynę („Brak kontaktów”) i jest jedna jasna następna akcja („Add your first contact”). Jeśli wymagana jest konfiguracja (np. połączenie skrzynki lub import CSV), pusty stan wskazuje dokładny krok.
Wolna sieć podczas ładowania: użytkownik otwiera stronę szczegółów Kontaktu. Obie platformy pokazują przewidywalny skeleton dopasowany do finalnej struktury strony (nagłówek, kluczowe pola, notatki). Przycisk wstecz nadal działa, tytuł strony jest widoczny i unikamy losowych spinnerów w różnych miejscach.
Błąd serwera: żądanie szczegółów nie powiodło się. Ten sam wzorzec pojawia się na web i mobile: krótki nagłówek, jedno zdanie i akcja główna („Retry”). Jeśli ponowne próby się nie powiodą, zaoferuj drugą opcję jak „Go back to Contacts”, aby użytkownik nie został zablokowany.
Co pozostaje spójne, jest proste:
Wydanie może wyglądać „gotowe”, dopóki ktoś nie trafi na wolne łącze, świeże konto lub niestabilne API. Ta lista pomaga wykryć braki ostatniej mili bez zamieniania QA w polowanie na skarby.
Zacznij od ekranów list, bo one się mnożą. Wybierz trzy powszechne listy (wyniki wyszukiwania, zapisane elementy, ostatnia aktywność) i upewnij się, że wszystkie używają tego samego układu pustego stanu: jasny tytuł, jedno pomocne zdanie i jedna akcja główna.
Upewnij się, że puste stany nigdy nie pojawiają się podczas trwającego ładowania. Jeśli migocze „Nic tu nie ma” przez ułamek sekundy, a potem pojawiają się treści, zaufanie spada szybko.
Sprawdź wskaźniki ładowania pod kątem spójności: rozmiar, umiejscowienie i sensowna minimalna długość, aby nie migały. Jeśli web pokazuje spinner w pasku u góry, a mobile pełnoekranowy skeleton dla tego samego ekranu, wygląda to jak dwa różne produkty.
Błędy powinny zawsze odpowiadać „co teraz?”. Każdy błąd potrzebuje następnego kroku: retry, refresh, zmień filtry, zaloguj się ponownie lub contact support.
Krótki przegląd przed oznaczeniem builda jako gotowego:
Jeśli używasz generatora AI jak Koder.ai, te kontrole mają jeszcze większe znaczenie, bo ekrany mogą być tworzone szybko, ale spójność nadal zależy od wspólnego kitu i zasad kopii.
Spójność jest najłatwiejsza, gdy jest częścią codziennej pracy, a nie jednorazowego porządku. Każdy nowy ekran powinien używać tych samych wzorców bez potrzeby pamiętania „dopasuj do reszty” na finiszu.
Włącz zachowanie stanów do definicji ukończenia. Ekran nie jest skończony, dopóki ma stan ładowania, pusty stan (jeśli ma zastosowanie) i stan błędu z jasną akcją.
Utrzymuj reguły lekkie, ale zapisz je. Krótki dokument z kilkoma zrzutami ekranu i dokładnymi wzorcami kopii zwykle wystarczy. Traktuj nowe warianty jako wyjątki. Kiedy ktoś proponuje nowy projekt stanu, zapytaj, czy to naprawdę nowy przypadek, czy pasuje do kitu.
Jeśli refaktoryzujesz wiele ekranów, zmniejsz ryzyko, robiąc to etapami: aktualizuj jeden przepływ na raz, weryfikuj na web i mobile, potem kontynuuj. W Koder.ai snapshoty i rollback mogą uczynić większe zmiany bezpieczniejszymi, a tryb planowania pomaga zdefiniować wspólny state kit, żeby nowe ekrany od pierwszego dnia używały waszych domyślnych ustawień.
Wybierz jeden obszar w tym tygodniu, gdzie problemy stanów powodują późne poprawki (często wyniki wyszukiwania, onboarding lub feed aktywności). Następnie:
Konkretny znak, że to działa: mniej „małych” ticketów typu „dodaj retry”, „pusty stan wygląda źle” czy „spinner blokuje stronę”.
Wyznacz jednego właściciela standardów stanów (projektant, tech lead lub oboje). Nie muszą zatwierdzać wszystkiego, ale powinni chronić kit przed powolnym rozpadem na nowe warianty, które wyglądają podobnie, zachowują się inaczej i później kosztują czas.
Zacznij od nazwania małego zestawu stanów, których będziecie używać wszędzie: początkowe ładowanie, odświeżanie, bazowy pusty stan, brak wyników i błąd. Dodaj jasne reguły dla trybu offline i wolnej sieci, aby nie były mylone z losowymi błędami. Gdy zespół zgodzi się na nazwy i wyzwalacze, UI staje się przewidywalne na wszystkich ekranach i platformach.
Zbuduj mały StateKit z trzema wielokrotnego użytku elementami: Loading, Error i Empty. Każdy komponent niech przyjmuje te same wejścia (tytuł, krótka wiadomość, jedna akcja główna i opcjonalne szczegóły), aby dowolny ekran mógł je wstawić bez wymyślania nowych rozwiązań. Ustaw domyślny wariant jako najprostszy w użyciu, żeby zespoły przestały tworzyć jednorazowe elementy.
Użyj prostego porządku decyzji: pokazuj ładowanie do momentu zakończenia żądania, potem pokaż błąd jeśli nie powiodło się, a pusty stan wyświetlaj tylko po pomyślnym zapytaniu, gdy naprawdę nie ma danych. To zapobiega sytuacji, gdzie „Brak elementów” pojawia się chwilowo przed załadowaniem treści.
Wybierz jedną domyślną akcję dla każdego stanu i używaj tego samego etykietowania i umiejscowienia na wszystkich ekranach. Błędy zwykle dostają „Retry”, pusty bazowy stan — „Create” (lub następny krok konfiguracji), a brak wyników — „Clear filters”. Gdy główna akcja jest przewidywalna, użytkownicy działają szybciej, a zespoły mniej dyskutują nad słowami przycisków.
Pisz kopię według wspólnego szablonu: krótki tytuł, który nazywa sytuację, jedno zdanie wyjaśnienia prostym językiem i jedna jasna następna czynność. Wolniej brzmiące, konkretne komunikaty typu „Nie udało się załadować projektów” są lepsze niż ogólne „Coś poszło nie tak”. Utrzymaj spokojny, spójny ton tak, aby web i mobile sprawiały wrażenie jednego produktu.
Traktuj offline jako odrębny stan, a nie ogólny błąd. Pokaż dane z pamięci podręcznej, jeśli są, napisz wprost „Jesteś offline” i wyjaśnij, co nadal działa. Zaproponuj jedną kolejną akcję, np. „Try again”, żeby użytkownik nie był pozostawiony bez wskazówek.
Unikaj szybkich komunikatów o błędzie przy wolnym połączeniu — zaczekaj krótko zanim zmienisz UI. Jeśli ładowanie przekroczy próg, przełącz wiadomość na „Still loading…” (lub podobną) i pokaż widoczną akcję typu „Retry”. To sprawia, że aplikacja wydaje się responsywna, nawet gdy sieć jest powolna.
Używaj trzech wariantów rozmiaru: mały inline (wewnątrz karty lub sekcji), domyślny sekcyjny i pełnoekranowy blokujący. Zdefiniuj, kiedy każdy jest dopuszczalny, aby zespoły nie improwizowały dla każdego ekranu. Utrzymanie tych samych odstępów, stylu ikon i przycisków między wariantami tworzy spójne doświadczenie.
Wbuduj kilka reguł: przenieś fokus na komunikat i akcję główną, gdy stan się pojawi; ogłaszaj ładowanie i błędy krótkimi, jasnymi etykietami dla czytników ekranu; upewnij się, że przyciski są łatwe do trafienia na urządzeniach mobilnych; nie polegaj wyłącznie na kolorze czy animacji. Jeśli te zasady są częścią StateKit, każdy nowy ekran dziedziczy je automatycznie.
Wprowadzaj to krokami, obszar po obszarze, zaczynając od ekranów o dużym ruchu. Zrób listę istniejących wariantów, wybierz kilka kanonicznych miejsc, zastąp jednorazowe stany komponentami i dodaj wymagania stanu do kryteriów akceptacji. Jeśli generujesz UI w Koder.ai, dodaj stałą instrukcję „używaj StateKit” aby nowe ekrany nie odpływały od standardu.