Vue Nginx History Mode Setup
Vue + Nginx history mode setup
Suyash Singh
Posted by Suyash Singh
on November 13, 2022
Photo by paul on Unsplash

This one is a very small post outlining how to make direct link access for a Vue project work with nginx.

The Problem

Imagine a scenario wherein you’d like our app users to be able to access nested routes within the application with direct links in the browser. Maybe a feature in your application allows users to share urls which can be opened directly in the application. To handle such scenarios, a very simple nginx is required to serve the static assets.

The solution

Assuming the Vue router config looks something like this

//routes/routes.js
export const routes = [
  {
    path: "/path1",
    component: Component1,
  },
  {
    path: "/path2",
    component: Component2,
    children: [
      { path: "path3", component: Component3 },
      { path: "path4", component: Component4 },
      { path: "path5", component: Component5 },
      { path: "path6", component: Component6 },
    ],
  },
];
//routes/index.js
import { createRouter, createWebHistory } from "vue-router";
import { routes } from "./Routes";
 
export const router = createRouter({
  history: createWebHistory(),
  routes,
});

Note: Using a hash based routing solution in an application should be avoided as part of good SEO techniques, but if the use case warrants hash based routing for some portions of the application it’s okay to use it for applications not rendered server side. Here in this case we are not using the hash based vue router.

A straightforward solution with the webHistory routing is to have the following config in nginx:

# /etc/nginx/sites-available/yourapp
...
 
       server_name app.suyashsingh.in www.app.suyashsingh.in;
       root /var/www/html/app/dist/;
       index index.html;

       location / {
               try_files $uri $uri/ /index.html;
       }

...

Important bit to notice here is the location block to make nginx either find the correspoding files associated with the request or pass the request to vue project’s index.html as a catch-all. This would make direct access to links work for Vue or similar frontend solutions like angular or react.