To get history mode working with Vue-Router you need to return the contents of your main page when trying to access a route that doesn't exist. For example when you visit mypwa.com/route1
your server checks if there is a resource at route1
and if there isn't, it returns the contents that is found at mypwa.com/
(but without redirecting you). This is great and works when you're online, but it requires your server to do the actual re-routing.
If you have a PWA that's meant to work offline, you need this re-routing to work without the server being available.
The problem is this: visiting mypwa.com/
when you're offline works. After loading it you can then navigate to mypwa.com/route1
from inside the app. However, if you try to navigate directly to mypwa.com/route1
whilst offline you will get a 404 error because mypwa.com/route1
is not cached, only /
is cached.
I suppose this means that you need some kind of fallback clause in your service worker? Does anyone know of a way to achieve this? Is there a common way to do it with sw-precache-webpack-plugin?
# HTML5 History Mode. The default mode for vue-router is hash mode - it uses the URL hash to simulate a full URL so that the page won't be reloaded when the URL changes. To get rid of the hash, we can use the router's history mode, which leverages the history.pushState API to achieve URL navigation without a page reload:
The default mode for vue-router is hash mode - it uses the URL hash to simulate a full URL so that the page won't be reloaded when the URL changes.
To get rid of the hash, we can use the router's history mode, which leverages the history.pushState API to achieve URL navigation without a page reload: const router = new VueRouter({ mode: 'history', routes: [...] })
Today we will create a progressive web app (PWA) based on Vue.js with Vue Router, featuring code splitting with webpack. Luckily, building progressive web apps has never been easier.
You need to set the navigateFallback option in your vue.config.js
file:
pwa: {
workboxOptions: {
navigateFallback: 'index.html'
}
}
It will automatically add the necessary code to your service worker:
workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("index.html"));
I had the same problem and I found the solution here: https://github.com/vuejs/vue-cli/issues/717#issuecomment-382079361
If your site is a single page app, you can use a NavigationRoute
to return a specific response for all navigation requests.
workbox.routing.registerNavigationRoute('/single-page-app.html')
In my case in vue :
workbox.routing.registerNavigationRoute('/index.html')
Whenever a user goes to your site in the browser, the request for the page will be a navigation request and will be served the cached page /single-page-app.html
.
Note: You should have the page cached via workbox-precaching or through your own installation step).
By default, this will respond to all navigation requests, if you want to restrict it to respond to a subset of URL’s you can use the whitelist and blacklist options to restrict which pages will match this route.
Update: Workbox V5
const handler = workbox.precaching.createHandlerBoundToURL("/index.html");
const navigationRoute = new workbox.routing.NavigationRoute(handler);
workbox.routing.registerRoute(navigationRoute);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With