В приложениях на Vue с использованием Vue Router часто возникает необходимость корректной обработки маршрутов, которые не существуют. Несмотря на клиентский роутинг, сервер также должен быть настроен так, чтобы возвращать правильный ответ при прямом обращении к несуществующему пути. Это особенно важно для SPA (Single Page Application), где клиентский роутинг управляет отображением компонентов, но сервер по умолчанию может возвращать ошибку 404.
Для корректной работы Vue Router необходимо настроить сервер так,
чтобы все запросы на маршруты приложения возвращали один и тот же
HTML-файл (index.html). Исключение составляют реальные
статические ресурсы (например, изображения, CSS, JS-файлы). Это
позволяет клиентскому приложению перехватывать маршруты и отображать
соответствующие компоненты.
Пример конфигурации для разных серверов:
Nginx
server {
listen 80;
server_name example.com;
root /var/www/my-app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
$uri проверяет существование файла по запросу.index.html.Apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
!-f и !-d проверяют, что запрашиваемый
файл или директория не существует.index.html.Node.js с Express
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
app.listen(3000, () => {
console.log('Server started on http://localhost:3000');
});
express.static обслуживает статические файлы.index.html.На стороне клиента желательно иметь компонент для отображения ошибки
404. Для этого в routes добавляется универсальный
маршрут:
import { createRouter, createWebHistory } from 'vue-router';
import Home from './components/Home.vue';
import NotFound from './components/NotFound.vue';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: () => import('./components/About.vue') },
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
/:pathMatch(.*)* перехватывает все маршруты, которые не
были определены выше.index.html для несуществующих
маршрутов, если это не статический ресурс.NotFound.app.get('/api/*', (req, res) => {
res.status(404).json({ error: 'API endpoint not found' });
});
beforeEach хук
для логирования или аналитики попыток перехода на несуществующие
страницы:router.beforeEach((to, from, next) => {
if (to.name === 'NotFound') {
console.warn(`Попытка перехода на несуществующий маршрут: ${to.fullPath}`);
}
next();
});
Это позволяет вести статистику и улучшать UX, перенаправляя пользователей на актуальные страницы или показывая рекомендации.