Когда я открываю страницу на localhost/, все работает корректно, однако после перезагрузки на адресе /sign/in я получаю ошибку 404. <br/><br/><b>Роуты на React Router Dom</b> <br/><pre><code class="javascript">import axios from 'axios';
import { createRoot } from 'react-dom/client';
import './styles.css';
import 'react-toastify/ReactToastify.min.css';
import { QueryClient, QueryClientProvider } from 'react-query';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';
import { Error } from './pages/error';
import { List } from './pages/list';
import { Sign } from './pages/sign';
import { SignIn } from './pages/sign/in';
import { SignUp } from './pages/sign/up';
import { RedirectPage } from './redirectPage';
const client = new QueryClient();
axios.defaults.baseURL = 'http://localhost:8080/api/';
createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={client}>
<ToastContainer
theme="dark"
pauseOnHover={false}
position="top-center"
autoClose={5000}
closeButton={false}
closeOnClick
/>
<BrowserRouter>
<Routes>
<Route path="*" element={<Error />} />
<Route index element={<RedirectPage />} />
<Route path="sign" element={<Sign />}>
<Route path="in" element={<SignIn />} />
<Route path="up" element={<SignUp />} />
</Route>
<Route path="list" element={<List />} />
</Routes>
</BrowserRouter>
</QueryClientProvider>,
);</code></pre> <br/><br/><b>nginx.conf</b> <br/><pre><code>server {
listen 80 default_server;
li
Для правильной работы с React Router, особенно в приложениях, использующих History API (например, в вашем случае с `BrowserRouter`), вам нужно настроить Nginx так, чтобы он перенаправлял все запросы к вашему приложению на `index.html`. Это позволит React Router корректно обрабатывать маршруты, такие как `/sign/in`, при перезагрузке страницы.
Вот пример того, как можно настроить ваш `nginx.conf` для подобной ситуации:
```nginx
server {
listen 80 default_server;
server_name localhost;
location / {
root /usr/share/nginx/html; # Путь до вашего скомпилированного приложения (например, Vite Build Output)
try_files $uri $uri/ /index.html; # Добавлено для поддержки истории в React Router
}
location /api {
proxy_pass http://backend:8080; # Проксируем 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;
}
error_page 404 /404.html; # Настройка страницы ошибок
}
```
### Объяснение изменений:
1. **`try_files $uri $uri/ /index.html;`**: Эта строка позволяет Nginx сначала искать файл по указанному URI. Если файл не найден (например, при обращении к `/sign/in`), Nginx будет знать, что нужно отдать `index.html`, и позволит React Router взять управление отображением маршрутов.
2. **Прямые указания для API**: Если у вас есть отдельно запущенный бэкенд, стоит настроить проксирование, как показано выше, чтобы все запросы к `/api` направлялись на ваш бэкенд.
### Docker
Если вы используете Docker, убедитесь, что ваша конфигурация Nginx включена в Docker-контейнер. Вот пример Dockerfile и docker-compose.yml для Nginx и вашего приложения:
**Dockerfile для вашего фронтенд-приложения:**
```Dockerfile
# Stage 1 - Build
FROM node:16 as build
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build # Предполагаем, что у вас есть скрипт для сборки
# Stage 2 - Nginx
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf # копируем наш конфиг в контейнер
EXPOSE 80
```
**docker-compose.yml:**
```yaml
version: '3.8'
services:
frontend:
build:
context: .
dockerfile: Dockerfile
ports:
- "80:80"
backend:
image: your-backend-image
ports:
- "8080:8080"
networks:
- app-network
networks:
app-network:
driver: bridge
```
### Запуск
Теперь вы можете запустить ваше приложение при помощи Docker:
```bash
docker-compose up --build
```
После того как ваши контейнеры запустятся, вы сможете открывать различные руты на вашем приложении, включая `/sign/in`, без возникновения ошибки 404.
перенесите
<Route path="*" element={<Error />} />
в конец
import axios from 'axios'; import { createRoot } from 'react-dom/client'; import './styles.css'; import 'react-toastify/ReactToastify.min.css'; import { QueryClient, QueryClientProvider } from 'react-query'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { ToastContainer } from 'react-toastify'; import { Error } from './pages/error'; import { List } from './pages/list'; import { Sign } from './pages/sign'; import { SignIn } from './pages/sign/in'; import { SignUp } from './pages/sign/up'; import { RedirectPage } from './redirectPage'; const client = new QueryClient(); axios.defaults.baseURL = 'http://localhost:8080/api/'; createRoot(document.getElementById('root')!).render( <QueryClientProvider client={client}> <ToastContainer theme="dark" pauseOnHover={false} position="top-center" autoClose={5000} closeButton={false} closeOnClick /> <BrowserRouter> <Routes> <Route index element={<RedirectPage />} /> <Route path="sign" element={<Sign />}> <Route path="in" element={<SignIn />} /> <Route path="up" element={<SignUp />} /> </Route> <Route path="list" element={<List />} /> <Route path="*" element={<Error />} /> </Routes> </BrowserRouter> </QueryClientProvider>, );