Jak naprawić błąd failed to fetch w React 18 po deployu
- Jak naprawić błąd „failed to fetch” w React 18 po deployu
- Co naprawdę oznacza „failed to fetch” po wdrożeniu
- Najczęstsze przyczyny błędu „failed to fetch” po deployu
- Problemy z CORS (Cross-Origin Resource Sharing)
- Nieprawidłowe adresy URL API po wdrożeniu
- Backend nie działa lub jest niedostępny z zewnątrz
- Konflikt HTTP/HTTPS i „mixed content”
- Problemy z uwierzytelnianiem i autoryzacją
- Błędne lub brakujące nagłówki HTTP
- Wpływ adblockerów i rozszerzeń przeglądarki
- Praktyczny przewodnik debugowania kroku po kroku
- Konkretny zestaw rozwiązań, które usuwają „failed to fetch”
- Podsumowanie i dalsze kroki
Jak naprawić błąd „failed to fetch” w React 18 po deployu
Wyobraź sobie taką sytuację: spędzasz godziny, dni, może nawet tygodnie, tworząc swoją aplikację w React. Wszystko działa perfekcyjnie na Twoim lokalnym komputerze – dane płyną, komponenty renderują się bezbłędnie, UX jest dopięte na ostatni guzik. Z radością wciskasz przycisk „deploy” i czekasz na chwilę triumfu. A potem… pustka.
Albo, co gorsza, komunikat w konsoli przeglądarki: „Failed to fetch”. Znacie to uczucie, prawda? Ten moment, gdy uświadamiasz sobie, że lokalne środowisko to jedno, a produkcja to zupełnie inna bajka. Nagle okazuje się, że to, co działało bezbłędnie na localhost, w chmurze zaczyna się sypać bez wyraźnego powodu.
W tym artykule rozłożymy na czynniki pierwsze problem, jakim jest jak naprawić błąd „failed to fetch” w aplikacji React 18 po deployu. Zobaczysz, dlaczego ten błąd tak często pojawia się właśnie po wdrożeniu, jakie są jego najczęstsze przyczyny i – co najważniejsze – jak go skutecznie zdiagnozować i naprawić na produkcji.
Przygotuj się na solidną dawkę praktycznej wiedzy. Dzięki niej oszczędzisz sobie wielu frustracji, a Twoje aplikacje React 18 po deployu będą działały stabilniej. Zobaczysz też, jak różni się komunikacja frontend–backend lokalnie i w środowisku produkcyjnym, kiedy w grę wchodzą domeny, protokoły i dodatkowe zabezpieczenia.

Co naprawdę oznacza „failed to fetch” po wdrożeniu
Zacznijmy od podstaw. Błąd „failed to fetch” to sygnał, że Twoja aplikacja React próbowała pobrać jakieś zasoby z serwera, ale z jakiegoś powodu operacja ta się nie powiodła. Może chodzić o dane z API, pliki, obrazy – wszystko, co pobierasz przez fetch lub axios. To ogólny komunikat, który może kryć za sobą wiele różnych problemów, dlatego tak ważna jest właściwa diagnoza.
Najczęściej „failed to fetch” pojawia się w kontekście komunikacji z zewnętrznym API. Frontend (aplikacja React 18) próbuje wysłać żądanie do backendu, a przeglądarka informuje, że nie udało się nawiązać poprawnego połączenia. Sama treść błędu nie mówi jednak, dlaczego tak się stało, więc trzeba sięgnąć głębiej.
Dlaczego błąd pojawia się dopiero po deployu?
Wielu programistów zauważa, że lokalnie wszystko działa poprawnie, a błąd „failed to fetch” pojawia się dopiero w środowisku produkcyjnym. Główna różnica tkwi w samym środowisku oraz konfiguracji domen i protokołów, z których korzysta Twoja aplikacja.
Na lokalnym komputerze zarówno Twoja aplikacja React, jak i serwer backendu działają często na tym samym localhost albo na portach, które nie wywołują dodatkowych problemów bezpieczeństwa. Po wdrożeniu – na Netlify, Vercel, Heroku czy własnym VPS – frontend znajduje się pod jedną domeną, backend pod inną lub innym portem, a w grę wchodzi polityka CORS i zabezpieczenia przeglądarek.
„Failed to fetch” oznacza wtedy tyle, że przeglądarka nie uznała komunikacji z serwerem za bezpieczną lub poprawną. Powodem może być np. brak odpowiednich nagłówków CORS, błędny URL API, problemy z HTTPS, firewall albo błędy po stronie serwera. Wszystko to sprawia, że sytuacja po deployu jest dużo bardziej złożona niż środowisko lokalne.
Najczęstsze przyczyny błędu „failed to fetch” po deployu
Aby skutecznie naprawić problem, trzeba zrozumieć jego typowe źródła. Poniżej znajdziesz najczęściej spotykane przyczyny, przez które fetch w React 18 przestaje działać na produkcji, mimo że lokalnie wszystko wyglądało dobrze.
Problemy z CORS (Cross-Origin Resource Sharing)
Najczęstszym winowajcą są problemy z CORS. CORS to mechanizm bezpieczeństwa w przeglądarkach, który ma zapobiegać temu, by złośliwe strony mogły wykonywać żądania do innych domen bez Twojej zgody. Kiedy frontend i backend działają na różnych domenach lub portach, przeglądarka wymaga, by serwer API jasno zadeklarował, że zezwala na takie połączenia.
Jeśli Twoja aplikacja React działa pod adresem https://moja-aplikacja.pl, a API pod https://api.moja-aplikacja.pl, przeglądarka wysyła tzw. żądanie preflight (OPTIONS). Oczekuje wtedy w odpowiedzi nagłówków CORS, takich jak Access-Control-Allow-Origin. Jeśli serwer backendu nie jest poprawnie skonfigurowany, przeglądarka zablokuje żądanie.
W konsoli przeglądarki często zobaczysz wtedy komunikaty w stylu: „Access to fetch at 'https://api.twoja-domena.pl/...' from origin 'https://twoja-domena.pl' has been blocked by CORS policy…”. To bezpośredni sygnał, że musisz skonfigurować CORS dla domeny produkcyjnej frontendu.
Nieprawidłowe adresy URL API po wdrożeniu
Kolejny klasyk, gdy pojawia się błąd „failed to fetch” po deployu, to po prostu zły adres URL API. Na lokalnym środowisku mogłeś używać adresu http://localhost:5000/api/users, który działa tylko na Twoim komputerze. Po wdrożeniu ten adres nie ma już sensu, a aplikacja nadal próbuje się z nim łączyć.
Częstym błędem jest „zakodowanie na sztywno” lokalnego URL-a API bez wykorzystania zmiennych środowiskowych. Brak odpowiedniej konfiguracji zmiennych dla produkcji powoduje, że React 18 w środowisku buildowym nadal korzysta z localhost, który jest niedostępny z poziomu przeglądarki użytkownika.
Jeśli Twoje żądania fetch lub axios są zbudowane na stałych, sprawdź, czy nie odwołują się do adresów, które mają sens tylko lokalnie. Prawidłowo skonfigurowane zmienne środowiskowe powinny rozwiązać ten typ problemu.
Backend nie działa lub jest niedostępny z zewnątrz
Zdarza się też, że wina nie leży ani po stronie Reacta, ani CORS, tylko… backend po prostu nie działa. Bywa, że serwer API nie został poprawnie uruchomiony po deployu, usługa się wysypała albo firewall blokuje ruch na konkretnym porcie.
W takiej sytuacji przeglądarka nie otrzymuje żadnej odpowiedzi, a jedynie informację, że połączenie nie mogło zostać nawiązane. To również może skutkować ogólnym komunikatem „failed to fetch” bez dodatkowych szczegółów. Dlatego zawsze warto sprawdzić, czy API odpowiada, wchodząc na jego adres bezpośrednio w przeglądarce lub testując je przez narzędzia typu Postman.
Konflikt HTTP/HTTPS i „mixed content”
Kolejna częsta przyczyna to problemy z konfiguracją HTTPS/HTTP. Jeśli Twoja aplikacja React 18 jest serwowana przez HTTPS (np. https://moja-aplikacja.pl), ale próbuje pobrać dane z API dostępnego tylko przez HTTP (http://api.moja-aplikacja.pl), przeglądarka może zablokować takie żądania jako tzw. „mixed content”.
Współczesne przeglądarki bardzo rygorystycznie podchodzą do mieszania treści szyfrowanych i nieszyfrowanych. Gdy frontend działa w HTTPS, wszystkie zasoby, w tym wywołania API, również powinny korzystać z HTTPS. W przeciwnym razie zobaczysz błędy bezpieczeństwa, a często także „failed to fetch” bez czytelnego komunikatu o przyczynie.
Problemy z uwierzytelnianiem i autoryzacją
Czasami ogólny błąd fetch maskuje problemy z autoryzacją. Jeśli Twój token uwierzytelniający wygasł, jest nieprawidłowy albo w ogóle nie jest przesyłany, serwer API może zwrócić błąd 401 (Unauthorized) lub 403 (Forbidden). W niektórych sytuacjach, szczególnie przy błędach w preflight i CORS, przeglądarka może zamienić to w bardziej ogólny komunikat.
Typowe kłopoty to:
- brak nagłówka
Authorization, - nieprawidłowy format tokenu,
- różnice w konfiguracji ciasteczek między lokalnym a produkcyjnym środowiskiem,
- inne domeny i ścieżki dla cookie używanych do logowania.
W takich przypadkach zawsze warto zobaczyć, czy backend faktycznie dostaje poprawne nagłówki i jakie kody statusu zwraca.
Błędne lub brakujące nagłówki HTTP
Niektóre żądania wymagają specyficznych nagłówków HTTP, bez których backend nie jest w stanie ich poprawnie obsłużyć. Typowe przykłady to:
Content-Type: application/jsonprzy wysyłaniu danych JSON,Authorization: Bearer <token>przy endpointach chronionych,- dodatkowe nagłówki wymagane przez API (np.
X-Requested-With).
Jeśli wysyłasz nieprawidłowe nagłówki albo ich brakuje, serwer może zwrócić błąd, który ostatecznie objawi się na froncie jako „failed to fetch”. Szczególnie wrażliwe są tu aplikacje, które różnie konfigurują nagłówki w zależności od środowiska.
Wpływ adblockerów i rozszerzeń przeglądarki
W rzadkich przypadkach komunikat „failed to fetch” może wynikać z działania adblockerów lub innych rozszerzeń przeglądarki. Dzieje się tak zwłaszcza wtedy, gdy adres URL API zawiera słowa kojarzone z reklamami lub śledzeniem. Nie jest to najczęstszy scenariusz, ale warto o nim pamiętać, gdy pojedynczy użytkownik zgłasza problem, a u innych wszystko działa poprawnie.
Typowym testem jest wtedy sprawdzenie działania aplikacji w trybie incognito albo w innej przeglądarce bez zainstalowanych rozszerzeń. Jeśli problem znika, łatwo ustalisz, że nie chodzi o CORS czy backend, lecz o konfigurację środowiska przeglądarki użytkownika.

Praktyczny przewodnik debugowania kroku po kroku
Kiedy widzisz „failed to fetch” w React 18 po deployu, najważniejsze jest metodyczne podejście. Zamiast zgadywać, warto krok po kroku zawęzić obszar poszukiwań. Poniżej znajdziesz praktyczny plan działania, który pozwoli Ci szybko namierzyć źródło problemu.
Korzystanie z narzędzi deweloperskich przeglądarki
Pierwszym miejscem, do którego powinieneś zajrzeć, są Narzędzia Deweloperskie przeglądarki. Otworzysz je klawiszem F12 lub Ctrl+Shift+I / Cmd+Option+I. Dwie najważniejsze zakładki to „Console” i „Network”.
W zakładce „Console” szukaj czerwonych wpisów dotyczących błędów. Jeśli problem dotyczy CORS, znajdziesz tu wyraźną informację o polityce CORS i blokadzie dostępu do zasobu. Komunikaty zwykle mówią, że brakuje nagłówka Access-Control-Allow-Origin lub że dana metoda nie jest dozwolona przez serwer.
W zakładce „Network” odśwież stronę i obserwuj listę żądań. Problematyczne pozycje będą oznaczone na czerwono lub opisane jako „failed”. Klikając konkretne żądanie, możesz sprawdzić:
- Status Code – czy to 200, 4xx, 5xx czy całkowita porażka bez kodu,
- sekcję „Headers” – szczególnie nagłówki CORS i adres docelowy,
- sekcję „Response” – jeśli serwer zwrócił treść błędu w odpowiedzi.
Jeśli w ogóle nie ma odpowiedzi, a status to „failed” bez kodu, najczęściej oznacza to problemy na poziomie sieci, CORS lub niedostępność serwera.
Analiza logów serwera backendu
Kiedy już wiesz, jak wygląda sytuacja po stronie przeglądarki, czas zajrzeć do logów backendu. Jeśli żądanie w ogóle nie dochodzi do serwera (brak śladu w logach), to prawdopodobnie problemem jest CORS, firewall lub błędny URL.
Gdy żądanie dociera, ale kończy się błędem 4xx lub 5xx, logi backendu zwykle pokażą więcej szczegółów. W zależności od platformy możesz ich szukać:
- na Heroku przy pomocy
heroku logs --tail, - w panelu administracyjnym Netlify Functions lub Vercel Functions,
- na serwerze VPS w katalogach typu
/var/log/nginx/lub/var/log/apache2/, - w konsoli lub plikach logów narzędzi takich jak
pm2czysystemd.
W logach szukaj wyjątków, błędów walidacji, informacji o braku autoryzacji albo komunikatów związanych z CORS. Dzięki temu precyzyjnie zobaczysz, co robi backend w odpowiedzi na wywołanie z Reacta.
Testowanie API niezależnie od Reacta
Aby upewnić się, że problem nie leży po stronie frontendu, warto przetestować API niezależnie od aplikacji React 18. Do tego służą narzędzia takie jak Postman, Insomnia, Thunder Client czy zwykły curl w terminalu.
Możesz np. wykonać żądanie:
curl -X GET https://api.twoja-domena.pl/users -H "Accept: application/json"
Jeśli odpowiedź z API jest poprawna, to wiesz, że backend działa, a problem leży raczej po stronie frontendu, CORS lub konfiguracji przeglądarki. Jeśli jednak i tutaj masz błąd, to znak, że trzeba skupić się na backendzie lub infrastrukturze.
To podejście pozwala szybko oddzielić problemy związane z Reactem od tych, które wynikają z działania samego API. Dzięki temu nie tracisz czasu na debugowanie kodu frontendu, gdy źródłem jest np. nieuruchomiony serwer.
Weryfikacja zmiennych środowiskowych
Kolejnym kluczowym krokiem jest dokładna kontrola zmiennych środowiskowych używanych przez aplikację React 18. W projektach stworzonych przez Create React App obowiązuje zasada, że wszystkie zmienne muszą zaczynać się od prefiksu REACT_APP_.
Na lokalnym środowisku możesz mieć plik .env z treścią:
REACT_APP_API_URL=http://localhost:5000/api
Na platformie deploymentowej, takiej jak Netlify, Vercel czy Heroku, musisz osobno zdefiniować zmienne środowiskowe dla produkcji. Tam ustawisz np.:
REACT_APP_API_URL=https://api.twoja-domena.pl/api
W samym kodzie odwołujesz się do nich poprzez process.env.REACT_APP_API_URL. Jeśli zapomnisz ustawić zmiennych na produkcji, React zbuduje aplikację bez nich albo z błędnymi wartościami, co od razu przełoży się na niewłaściwe URL-e API.
Konkretny zestaw rozwiązań, które usuwają „failed to fetch”
Gdy masz już diagnozę, czas przejść do konkretnych rozwiązań. Poniżej znajdziesz sprawdzone sposoby na usunięcie błędu „failed to fetch” w React 18 po deployu, w zależności od tego, co okazało się przyczyną.
Konfiguracja CORS na backendzie
Najczęstszym i najskuteczniejszym krokiem jest poprawna konfiguracja CORS na serwerze API. Musisz jasno poinformować backend, że zezwala na żądania z domeny Twojego frontendu.
Przykład w Node.js (Express.js) z użyciem pakietu cors:
const express = require('express');
const cors = require('cors');
const app = express();
// Dla konkretnej domeny (zalecane w produkcji)
app.use(cors({
origin: 'https://twoja-aplikacja.pl' // Zastąp adresem URL Twojej aplikacji React
}));
// Przykładowy endpoint API
app.get('/api/users', (req, res) => {
res.json([{ id: 1, name: 'Ania' }]);
});
app.listen(5000, () => console.log('API działa na porcie 5000'));
W bardziej złożonych przypadkach możesz dodać listę dozwolonych domen, metod, nagłówków oraz obsługę credentials. Pamiętaj tylko, aby nie zostawiać CORS otwartego na wszystkie domeny w produkcji, chyba że masz ku temu bardzo dobry powód.
Przykład w Python (Flask) z użyciem Flask-CORS:
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "https://twoja-aplikacja.pl"}})
@app.route('/api/users')
def get_users():
return jsonify([{'id': 1, 'name': 'Bartek'}])
if __name__ == '__main__':
app.run(debug=True)
Po każdej zmianie konfiguracji CORS koniecznie ponownie wdrażaj backend, aby nowe ustawienia zaczęły obowiązywać na produkcji.
Poprawne wykorzystanie zmiennych środowiskowych w React 18
Kolejny krok to pewność, że aplikacja React używa właściwego adresu API. W praktyce oznacza to poprawne przechowywanie i odczytywanie zmiennych środowiskowych.
Przykładowa konfiguracja w pliku .env lokalnie:
REACT_APP_API_URL=http://localhost:5000/api
Konfiguracja w środowisku produkcyjnym:
REACT_APP_API_URL=https://api.twoja-domena.pl/api
Fragment kodu korzystający z tej zmiennej:
const API_URL = process.env.REACT_APP_API_URL;
fetch(`${API_URL}/users`)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error fetching users:', error));
Dzięki temu nie musisz ręcznie zmieniać adresów między środowiskami. Wystarczy odpowiednio zdefiniować zmienne podczas builda, a React 18 sam podstawi właściwe wartości dla konkretnej wersji aplikacji.
Stosowanie bezwzględnych i poprawnych URL-i API
Na produkcji najlepiej jest zawsze używać bezwzględnych adresów URL API, np. https://api.twoja-domena.pl/users, a nie wyłącznie ścieżek typu /users. Pozwala to uniknąć sytuacji, w której przeglądarka próbuje dodać do ścieżki niewłaściwą domenę lub port.
Bezwzględne URL-e są szczególnie pomocne, gdy masz wiele środowisk (dev, staging, production) oraz chcesz jednoznacznie wskazać, z jakim serwerem API ma się komunikować frontend. W połączeniu ze zmiennymi środowiskowymi daje to elastyczną i czytelną konfigurację.
Zapewnienie spójności protokołu HTTPS
Jeśli Twoja aplikacja React 18 jest serwowana po HTTPS, API również musi działać w HTTPS. W przeciwnym razie przeglądarka potraktuje wywołania http:// jako niebezpieczne i może je zablokować.
Najważniejsze kroki to:
- zainstalowanie certyfikatu SSL na serwerze API,
- upewnienie się, że domena backendu wskazuje na serwer z poprawną konfiguracją HTTPS,
- używanie w kodzie adresów
https://zamiasthttp://.
Dzięki temu unikniesz błędów „mixed content” i niewidocznych blokad po stronie przeglądarki, które prowadzą do komunikatu „failed to fetch”, mimo że backend w rzeczywistości działa.
Wykorzystanie reverse proxy, aby uniknąć CORS
Jeśli z jakiegoś powodu nie możesz skonfigurować CORS na backendzie, alternatywą jest reverse proxy, np. w Nginx. Wtedy frontend i backend z punktu widzenia przeglądarki będą działać pod jedną domeną, a problem CORS przestaje istnieć.
Przykładowa konfiguracja Nginx:
server {
listen 80;
server_name twoja-aplikacja.pl;
location / {
root /var/www/twoja-aplikacja.pl/html; # Ścieżka do skompilowanej aplikacji React
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://twoj-backend:5000/api/; # Adres Twojego serwera API
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
W aplikacji React możesz wtedy odwoływać się do endpointów po prostu przez /api/users. Nginx przekaże te żądania dalej do backendu, ale dla przeglądarki wszystko wygląda jak komunikacja z tą samą domeną, więc CORS przestaje być problemem.
Rozwiązywanie problemów z tokenami i nagłówkami
Jeśli diagnoza wskazuje na problemy z autoryzacją, warto zwrócić szczególną uwagę na tokeny i nagłówki HTTP. Upewnij się, że:
- token jest poprawnie generowany po logowaniu,
- jest przechowywany w bezpiecznym miejscu (np. cookie zamiast localStorage),
- jest wysyłany przy każdym żądaniu do chronionych endpointów w nagłówku
Authorization, Content-Typejest prawidłowo ustawiany przy wysyłaniu danych JSON.
Dodatkowo sprawdź, czy konfiguracja backendu pozwala na odczyt tych nagłówków w kontekście CORS. Jeśli korzystasz z credentials i ciasteczek, pamiętaj o odpowiednich nagłówkach Access-Control-Allow-Credentials oraz Access-Control-Allow-Origin ustawionych na konkretną domenę frontendu.
Podsumowanie i dalsze kroki
Błąd „failed to fetch” w aplikacji React 18 po deployu nie jest niczym niezwykłym – prędzej czy później spotyka się z nim niemal każdy frontendowiec. Kluczem jest zrozumienie, że to jedynie objaw, a nie konkretna diagnoza. Prawdziwa przyczyna może tkwić w CORS, błędnych adresach API, niedziałającym backendzie, problemach z HTTPS, autoryzacją czy nagłówkami.
Metodyczne podejście pozwala szybko zawęzić obszar poszukiwań:
- Sprawdź konsolę i zakładkę „Network” w narzędziach deweloperskich.
- Zajrzyj do logów backendu i zobacz, jak serwer reaguje na żądania.
- Przetestuj API niezależnie, np. w Postmanie lub przez
curl. - Zweryfikuj zmienne środowiskowe i poprawność URL-i API.
- Skonfiguruj CORS, HTTPS i ewentualne reverse proxy.
Z każdą naprawioną usterką lepiej rozumiesz, jak działa komunikacja między frontendem a backendem w realnych warunkach produkcyjnych. To doświadczenie procentuje przy każdym kolejnym projekcie, czyniąc Twoje wdrożenia stabilniejszymi i mniej podatnymi na niespodzianki.