Вы создали красивое React-приложение с клиентской маршрутизацией, собрали его в аккуратный бандл и загрузили на сервер. Но при обновлении страницы или прямом переходе по URL вместо вашего приложения появляется холодная ошибка 404. Знакомая ситуация? Это классическая проблема SPA с React Router, и решается она правильной настройкой веб-сервера. В этой статье мы разберем, как настроить Nginx для безупречной работы вашего React-приложения.
Почему React Router ломается на сервере?
React Router — это клиентский маршрутизатор. Когда пользователь заходит на главную страницу (/), сервер отдает index.html, React загружается, и Router берет управление на себя. Все переходы происходят без перезагрузки страницы. Но если пользователь обновит страницу на /about или перейдет по прямой ссылке, Nginx попытается найти файл /about/index.html (или просто about) в папке с билдом. Его там нет — отсюда и 404.
Ключевой принцип: при любом запросе (кроме запросов к статическим файлам) сервер должен возвращать один и тот же index.html. React Router сам разберется с URL и отрендерит нужный компонент.
Базовая конфигурация Nginx
Стандартная конфигурация для статики не подходит. Вот минимальный рабочий конфиг для сайта:
Основной server блок
server {
listen 80;
server_name yourdomain.com;
root /var/www/your-react-app/build;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control \"public, immutable\";
}
}
Директива try_files $uri $uri/ /index.html; — это сердце настройки. Nginx пытается найти запрошенный файл или папку, и если не находит — отдает index.html.
Продвинутые сценарии и оптимизация
Работа с API-проксированием
Часто фронтенд обращается к бэкенду на другом порту. Настроим проксирование:
location /api/ {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
Важно! Располагайте блок location /api/ выше блока location /. Nginx выбирает location по наиболее специфичному совпадению.
Поддержка HTML5 History API и хэш-роутинга
Если вы используете старый HashRouter (с # в URL), конфигурация проще — проблемы с 404 не возникает. Но для современного BrowserRouter (History API) наша настройка обязательна.
Настройка кэширования и gzip
Добавьте сжатие для ускорения загрузки:
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
Решение частых проблем
- Белый экран после деплоя: Проверьте, что
rootведет на папкуbuild, и в ней естьindex.html. Проверьте права доступа (частоchmod -R 755 /var/www/your-app). - Статические файлы не грузятся: Убедитесь, что блок для статики корректно настроен и файлы существуют.
- Ошибки 404 для API-запросов: Проверьте путь проксирования и работает ли бэкенд-сервер.
Проверка и перезагрузка конфигурации
- Проверьте синтаксис:
sudo nginx -t - Если ок — перезагрузите:
sudo systemctl reload nginxилиsudo nginx -s reload - Очистите кэш браузера при тестировании!
FAQ: Часто задаваемые вопросы
Нужно ли это для Create React App?
Да, если вы используете React Router и выкладываете билд на свой сервер. На хостингах вроде Vercel или Netlify это настраивается автоматически.
А как насчет Apache?
Для Apache нужен файл .htaccess с правилом RewriteRule, которое также перенаправляет все запросы на index.html.
Что делать с 404 ошибками для несуществующих путей?
React Router должен сам отображать компонент "Страница не найдена" (404). Сервер всегда отдает index.html, а роутинг на стороне клиента определяет, что такого маршрута нет.
Можно ли использовать с Docker?
Конечно. Поместите конфиг Nginx в контейнер и скопируйте в него папку build. Или используйте готовый образ, например, nginx:alpine.