NekR / offline-plugin

Offline plugin (ServiceWorker, AppCache) for webpack (https://webpack.js.org/)
MIT License
4.52k stars 294 forks source link

Offline support with AppCache.FALLBACK #442

Open ridvandev opened 5 years ago

ridvandev commented 5 years ago

I implemented Offline-Plugin to my .NET Core based React Single Page website.

Here is the config:

new OfflinePlugin({
    externals: [
        '/android-chrome-192x192.png',
        '/android-chrome-256x256.png',
        '/android-chrome-512x512.png',
        '/apple-touch-icon.png',
        '/favicon.ico',
        '/favicon-16x16.png',
        '/favicon-32x32.png',
        '/mstile-150x150.png',
        '/safari-pinned-tab.svg',
        '/dist/vendor.js',
        '/dist/vendor.css',
        '/offline.html'
    ],
    ServiceWorker: {
        publicPath: '/sw.js',
        output: '../sw.js',
        events: true
    },
    AppCache: {
        publicPath: '/',
        directory: '../',
        FALLBACK: {
            '/': '/offline.html'
        },
        events: true
    }
})

Here is the sw.js output's first part:

var __wpo = {
  "assets": {
    "main": [
      "dist/342def5bf48a3d2f30942eabfd2977c1.png",
      "dist/791e187172f527d4a27e4f817b9daa36.svg",
      "dist/db67a158afb18c2ba63fde1d7c0f51cb.svg",
      "dist/main.js",
      "/android-chrome-192x192.png",
      "/android-chrome-256x256.png",
      "/android-chrome-512x512.png",
      "/apple-touch-icon.png",
      "/favicon.ico",
      "/favicon-16x16.png",
      "/favicon-32x32.png",
      "/mstile-150x150.png",
      "/safari-pinned-tab.svg",
      "/dist/vendor.js",
      "/dist/vendor.css",
      "/offline.html"
    ],
    "additional": [],
    "optional": []
  },
  "externals": [
    "/android-chrome-192x192.png",
    "/android-chrome-256x256.png",
    "/android-chrome-512x512.png",
    "/apple-touch-icon.png",
    "/favicon.ico",
    "/favicon-16x16.png",
    "/favicon-32x32.png",
    "/mstile-150x150.png",
    "/safari-pinned-tab.svg",
    "/dist/vendor.js",
    "/dist/vendor.css",
    "/offline.html"
  ],
  "hashesMap": {
    "6121f03a2a104260168edb569dbb0fddda94a2ce": "dist/342def5bf48a3d2f30942eabfd2977c1.png",
    "eff7842d46163fd29cbae9c4ef2b9c8ac33bb171": "dist/791e187172f527d4a27e4f817b9daa36.svg",
    "c4f39b530e700377c978c292f2e015b1c5881f49": "dist/db67a158afb18c2ba63fde1d7c0f51cb.svg",
    "0c380215949704aaa1ec2b4af8d933d74c23b753": "dist/main.js"
  },
  "strategy": "changed",
  "responseStrategy": "cache-first",
  "version": "2019-2-21 15:17:15",
  "name": "webpack-offline",
  "pluginVersion": "5.0.6",
  "relativePaths": false
};

And last, manifest.appcache file:

CACHE MANIFEST
#ver:2019-2-21 15:17:15
#plugin:5.0.6

CACHE:
dist/342def5bf48a3d2f30942eabfd2977c1.png
dist/791e187172f527d4a27e4f817b9daa36.svg
dist/db67a158afb18c2ba63fde1d7c0f51cb.svg
dist/main.js
/android-chrome-192x192.png
/android-chrome-256x256.png
/android-chrome-512x512.png
/apple-touch-icon.png
/favicon.ico
/favicon-16x16.png
/favicon-32x32.png
/mstile-150x150.png
/safari-pinned-tab.svg
/dist/vendor.js
/dist/vendor.css
/offline.html

NETWORK:
*

FALLBACK:
/ /offline.html

So i am not sure my configs are true but it is working as expected except 'offline.html' fallback. When i tried developer tools offline mode, i see below:

image

I could not achieve to navigate to /offline.html. What should i do?

ridvandev commented 5 years ago

I realized that i don't cache the root '/'. And this document says i have to cache it. I don't know if it is the cause of my issue.

https://github.com/NekR/offline-plugin/blob/master/docs/examples/SPA.md

Here is the problem: If i cache root, my .Net Core Mvc controller action '/Home/Index' is not invoked when site loads. But i need to invoke it every first website load.

Any idea?

ridvandev commented 5 years ago

I tried ServiceWorker.navigateFallbackURL property but it doesn't work either.

Here is the latest Offline-Plugin config i tried:

new OfflinePlugin({
    externals: [
        '/android-chrome-192x192.png',
        '/android-chrome-256x256.png',
        '/android-chrome-512x512.png',
        '/apple-touch-icon.png',
        '/favicon.ico',
        '/favicon-16x16.png',
        '/favicon-32x32.png',
        '/mstile-150x150.png',
        '/safari-pinned-tab.svg',
        '/dist/vendor.js',
        '/dist/vendor.css',
        '/offline.html'
    ],
    ServiceWorker: {
        publicPath: '/sw.js',
        output: '../sw.js',
        navigateFallbackURL: '/offline.html',
        events: true
    },
    AppCache: {
        publicPath: '/',
        directory: '../',
        FALLBACK: {
            '/': '/offline.html'
        },
        events: true
    }
})
GGAlanSmithee commented 5 years ago

@rcturk Sorry for the late reply.

  1. You will need to cache your root route if you want it to work offline. If you do server-side rendering you will have to set it up in such a way that the server-rendered data is not cached. See this
  2. navigateFallbackURL is deprecated, see the appShell option instead. It should do what you need.

Please report back if it works or not.

ridvandev commented 5 years ago

Thanks for the reply @GGAlanSmithee

I tried appShell option. But, appShell navigates all requests to '/offline.html' instead of fallback requests when i configure appShell: '/offline.html' .

I can't achieve navigating to '/offline.html' when user doesn't have connection. Here is the latest plugin config.

new OfflinePlugin({
    externals: [
        '/android-chrome-192x192.png',
        '/android-chrome-256x256.png',
        '/android-chrome-512x512.png',
        '/apple-touch-icon.png',
        '/favicon.ico',
        '/favicon-16x16.png',
        '/favicon-32x32.png',
        '/mstile-150x150.png',
        '/safari-pinned-tab.svg',
        '/dist/vendor.js',
        '/dist/vendor.css',
        '/offline.html'
    ],
    ServiceWorker: {
        publicPath: '/sw.js',
        output: '../sw.js',
        events: true
    },
    appShell: '/',
    AppCache: {
        publicPath: '/',
        directory: '../',
        FALLBACK: {
            '/': '/offline.html'
        },
        events: true
    }
})