Configuring Nginx for Vue History Mode with Nested Directory Support
Deploying a Vue application using the HTML5 History API requires specific synchronization between the frontend router and the web server. When serving an application from a non-root path (sub-directory), additional configuration is necessary to ensure the router correctly maps paths to the application entry point.
Vite & Vue 3 Configuraton
For modern projects using Vite and Vue Router 4, you must align the router's base path with the build output directory.
- Vue Router: Define the base path in the history instance. ```
// router/index.js
const router = createRouter({
history: createWebHistory('/app/'),
routes: [...]
});
- Vite Config: Ensure the build public path matches the deployment path. ```
// vite.config.js
export default defineConfig({
base: '/app/'
});
- Nginx Configuration: Map the specific location block to your build artifacts. ```
location /app/ {
alias /var/www/html/my-project/;
try_files $uri $uri/ /app/index.html;
}
Legacy Webpack (Vue 2) Configuration
If utilizing older versions of Vue CLI (Webpack), configuration involves setting the base property in the Vue Router constructor and updating the build target paths.
Router Settings
const router = new VueRouter({
mode: 'history',
base: '/prod/',
routes
});
Build Output
Update your vue.config.js or the equivalent configuration file to handle the public path and output directory:
module.exports = {
publicPath: '/prod/',
outputDir: 'dist/prod'
};
Server Mapping
Using alias is often more flexible when mapping specific URL segments to local filesystems:
location /prod/ {
alias /home/deploy/app/dist/prod/;
try_files $uri $uri/ /prod/index.html;
}
Technical Principles
The core challenge with History mode is that the browser requests a specific path (e.g., /app/user/profile) from the server. Since this file does not exist on the filesystem, Nginx returns a 404 error. The try_files directive acts as a fallback mechanism:
$uri: Checks if the requested file exists.$uri/: Checks if the requested directory exists./app/index.html: If the above fail, serve the single-page application's entry file. Vue Router then intercepts the URL and renders the corrresponding component.
Root vs. Alias
root: Appends the request URI to the provided directory path. Use this when your directory structure matches the URL structure.alias: Replaces the matched location block with the path specified in the alias. This is preferred for mapping sub-directories to specific deployment folders regardless of their parent path on the server.