В React всё открывается, но F5 даёт 404: где потерян маршрут
Если переход внутри React-приложения работает, а обновление страницы даёт 404, сравните клиентский переход с прямым запросом того же адреса к серверу. Для статической SPA обычно требуется выдача оболочки приложения на допустимых интерфейсных путях. Ресурсы и API должны обрабатываться отдельно: главная HTML-страница не заменяет отсутствующий CSS или ответ данных.
Один адрес открывается двумя способами
При переходе внутри уже загруженного приложения маршрутизатор может показать экран без нового запроса основного документа по этому пути. При обновлении браузер обращается к адресу напрямую. Если веб-сервер ищет там только физический файл, существование клиентского экрана не поможет ему найти такой файл.
Возьмите один воспроизводимый пример. Сохраните адрес после перехода внутри приложения, затем откройте его в новой вкладке и обновите. Сравните именно запрос документа, а не ответ одного из последующих API-вызовов. Сообщение «404» внутри интерфейса и HTTP-ответ веб-сервера тоже требуют различения.
Сначала подтвердите тип приложения
Инструкция относится к статическому клиентскому приложению с соответствующей схемой маршрутов. React сам по себе не устанавливает, как работает сервер: проект может использовать серверную обработку, предварительно подготовленные страницы или другую архитектуру. Не меняйте её на SPA только потому, что встретили совет добавить fallback.
В справке React Router о SPA для описанного режима нужно направлять интерфейсные адреса к index.html клиентской сборки. Там же 404 на допустимых маршрутах связывается с настройкой хостинга. Это не универсальное правило конфигурации каждого приложения, использующего React.
Матрица адресов для приёмки
| Учебный адрес или объект | Переход внутри приложения | Прямое обращение | Ожидаемый результат | Что проверять |
|---|---|---|---|---|
| Известный экран списка | Экран появляется | Сейчас серверный 404 | Оболочка и нужный клиентский экран | Назначение интерфейсного пути |
| Известная карточка | Работает из списка | Обновление не проходит | Та же карточка после загрузки приложения | Документ, затем её отдельные данные |
| Реальный CSS-файл выпуска | Уже мог быть загружен | Доступен отдельным ресурсом | Содержимое стилей с подходящим типом | Файл и маршрут статики |
| Отсутствующий статический файл | Не обязан участвовать в переходе | Запрошен напрямую | Ошибка отсутствия ресурса, а не оболочка | Никакого общего HTML вместо файла |
| API-запрос данных | Нужен экрану | Обслуживается как API | Ответ данных или предусмотренная ошибка | Отдельная граница API |
| Неизвестный интерфейсный путь | Экран не определён | Может получить SPA-оболочку | Согласованное поведение страницы ошибки | Не показывается чужая успешная карточка |
Все строки — сценарии для будущей проверки, а не результаты испытания готового проекта. Для настоящего приложения замените их согласованными адресами. Не выдавайте успешную загрузку оболочки на случайном пути за доказательство существования такого маршрута.
Что означает fallback на уровне сервера
Это запасной способ получить документ приложения, когда путь относится к его интерфейсу, а не к отдельному физическому файлу. В описании try_files Nginx объясняется проверка файлов по порядку и следующий переход при отсутствии совпадения. Корректность зависит от контекста обработки и корневого пути.
Поэтому одной строки из чужого конфига недостаточно. Нужно знать, где опубликована сборка, какое приложение обслуживает имя и где проходят границы API и статических файлов. Если этим управляет панель, учитывайте её способ настройки, чтобы ручная правка не расходилась с действующим размещением.
Почему нельзя отдавать index.html на любой отказ
Представим учебный сбой: документ загрузился, но запрошенный JS-файл старого выпуска уже отсутствует. Если сервер вместо него отправит HTML оболочки, основной симптом станет менее понятным. Код успешного ответа не сделает HTML исполняемым JavaScript и не восстановит отсутствующий файл.
Тот же принцип относится к API: клиент ожидает данные или понятную ошибку своего протокола. HTML главной в таком ответе маскирует исходный маршрут и может породить ошибку разбора. Настройку при поддержке сайта нужно проверять на нескольких типах запросов, а не только на красивом экране главной.
Приложение установлено не в корне
Если интерфейс размещён в подкаталоге, запишите его базовый публичный путь и сравните с путями ресурсов. Ошибка может касаться не только маршрута карточки, но и адреса сборки. Не назначайте одной оболочке все пути домена, если рядом работают другие сайты, API или служебные разделы.
При разработке веб-приложения договоритесь о схеме публикации ещё до приёмки. В ней должны совпасть публичный адрес, клиентское понимание маршрутов и обработка сервера. Перенос одной папки на другой уровень не подтверждает автоматически готовность всех этих частей.
Проверка исправления
- Подтвердите архитектуру приложения и выберите известный интерфейсный маршрут.
- Сравните переход внутри приложения, прямое открытие и перезагрузку по одному адресу.
- Согласуйте отдельные правила для документа SPA, статики и API.
- Внесите изменение способом, подходящим вашей системе управления, и проверьте его применение.
- Пройдите матрицу адресов, включая отсутствующий файл и неизвестный интерфейсный путь.
Проверка должна включать новый сеанс, где приложение ещё не загружено. Успех перехода в уже открытой вкладке не подтверждает работу прямой ссылки. Если требуется авторизация, отдельно согласуйте, какой результат ожидается для гостя; страницу входа нельзя бездумно считать потерянным React-маршрутом.
Настоящие ошибки должны оставаться различимыми
Исправление F5 не означает отмену всех 404 в проекте. Для неизвестного интерфейсного адреса согласуйте страницу ошибки и HTTP-поведение с учётом выбранной архитектуры. Для отсутствующих файлов и API сохраняйте их собственные понятные результаты, а не одинаковую успешную главную.
При сопровождении сервера закрепите эти сценарии рядом с процедурой выкладки. После следующего выпуска проверяйте прямую ссылку на существующий экран и отдельные ресурсы. Это короткая, воспроизводимая приёмка, которая проверяет исходную проблему и не требует менять весь стек приложения.
Вопросы и ответы
Почему React Router даёт 404 при refresh страницы?
Допустимый клиентский маршрут может не иметь отдельного физического файла на сервере. При прямом открытии нужно получить документ приложения подходящим для его архитектуры способом. Сначала подтвердите, что речь именно о статической SPA.
Как работает nginx try_files для такого случая?
Директива проверяет существование заданных файлов и определяет следующую обработку, если они не найдены. Итог зависит от контекста и путей размещения. Не распространяйте SPA-fallback на API и отсутствующую статику без разделения правил.
Нужно ли делать отдельный 404 route в React?
Неизвестные интерфейсные пути должны иметь согласованное поведение ошибки. Но клиентский экран не исправляет серверный отказ при прямой загрузке известного маршрута. Эти два случая включите в приёмку отдельно.
Читайте также
Оплаты и вебхуки при сбое сервера: как не потерять заказы
ПоддержкаПо домену открывается другой сайт: DNS, хостинг или редирект
ПоддержкаПосле настройки POP3 исчезают письма: как остановить потерю
ПоддержкаПосле смены DNS домен даёт SERVFAIL: проверить DNSSEC
ПоддержкаУстаревшая ОС на сервере: обновлять или переносить
ПоддержкаРассылки: свой сервер или сервис — как выбрать