4

I'm having a issue while using vue router. When I click on the Navbar to change between views/pages, the website works fine, but when I try to go directly to a specific page through the domain/url, I get an error through Firebase (where the website is hosted) saying that the file does not exist in the root index.html.

enter image description here

Here's the code of the index.js file from routes:

import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import Courses from "../views/Courses.vue";
import LandingPageTechSession from "../views/LandingPageTechSession.vue";
import VueMeta from "vue-meta";
Vue.use(VueMeta);

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home,
  },
  {
    path: "/muddy-match",
    name: "MuddyMatch",
    component: MuddyMatch,
  },
  {
    path: "/courses",
    name: "Courses",
    component: Courses,
  },
  {
    path: "/techsession",
    name: "TechSession",
    component: LandingPageTechSession,
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;

Here's the code of the App.vue:

  <div id="app">
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.2.0/css/all.css"
      integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ"
      crossorigin="anonymous"
    />
    <navbar></navbar>
    <router-view />
    <bottom></bottom>
  </div>
</template>

<script>
import Navbar from "./components/Navbar.vue";
import Bottom from "./components/Footer.vue";

export default {
  name: "App",
  components: {
    Navbar,
    Bottom,
  },
};

And the Navbar item. (The courses route is with router-link but it still gives the same error):

<template>
  <b-container fluid>
    <b-navbar toggleable="sm" id="navbar" type="light">
      <b-navbar-brand :to="{ name: 'Home' }">
        <img id="logo" src="../assets/S2Plogo.png" alt="S2Plogo" />
      </b-navbar-brand>

      <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>

      <b-collapse id="nav-collapse" class="collapse" is-nav>
        <b-navbar-nav align="end" class=" ml-auto">
          <b-nav-item size="sm" class="navbar-item"
            ><router-link class="navbar-item" :to="{ path: 'Courses' }">{{
              $t("nav.courses")
            }}</router-link>
          </b-nav-item>
          <b-nav-item
            size="sm"
            class="navbar-item"
            :to="{ name: 'TechSession' }"
            >{{ $t("nav.techsessions") }}</b-nav-item
          >
          <b-nav-item
            size="sm"
            class="navbar-item"
            href="https://teespring.com/"
            target="_blank"
            >{{ $t("nav.merchandise") }}</b-nav-item
          >
          <b-nav-item size="sm" class="navbar-item" href="/#contact-us">{{
            $t("nav.contactus")
          }}</b-nav-item>
          <b-nav-item
            size="sm"
            v-on:click="switchLocale()"
            class="navbar-item"
            >{{ displayLocale }}</b-nav-item
          >
        </b-navbar-nav>
      </b-collapse>
    </b-navbar>
  </b-container>
</template>

Thank you advance guys!

2
  • Yeah because it looks for the URL (resource) on the server directly. It doesn't refer to the internal route of the application. Did you try with hash location strategy? Commented Jun 26, 2021 at 16:55
  • @AbhinavKumar tried it but doesn't seem to work as well. It redirects to the "/" route. Commented Jun 26, 2021 at 17:08

2 Answers 2

9

The answer about this has nothing to do with Vue Router or Vue actually, but with Firebase.

If you want to be able to navigate through url directly, just add the "rewrites" array on your firebase.json:

{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  },
}

You shouldn't have any issue now. Happy coding!

Sign up to request clarification or add additional context in comments.

2 Comments

It works like a charm, thanks! Do you have an explanation for this solution?
@BruMasRibera the documentation is at: firebase.google.com/docs/hosting/full-config#rewrites
0

It seems like the issue you're facing is connected to the vue-router history mode.

mode: "history",

When using createWebHistory(), the URL will look "normal," e.g. https://example.com/user/id. Beautiful!

Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access https://example.com/user/id directly in their browser. Now that's ugly.

Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in. Beautiful, again!

Please find more details in the documentation of vue-router: vue-router history mode

Hope this helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.