-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(v2): Plugin for Offline/PWA support #2205
Conversation
Hi codemonkey800! Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file.In order for us to review and merge your code, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
Deploy preview for docusaurus-2 ready! Built with commit 0e0b219 |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
This is pretty amazing, I recently tested oflline and noticed the site went down so this is ❤️ |
@codemonkey800 wow, I love this! One possible idea is to implement something like VuePress's plugin (https://vuepress.vuejs.org/plugin/official/plugin-pwa.html) that creates a popup when content has been refreshed. |
This is such amazing and great work from the community. We're shorthanded now and I'll only have time to review next weekend though. Thank you from the bottom of my heart ❤️ Maybe @lex111 can take a stab at reviewing it too. |
@nebrelbug great suggestion :) I'd love to add something like this, I'll see if it's something I can get around to implementing. I mostly wanted to get a foundation for offline/PWA functionality first |
@codemonkey800 This is HUGE and the long-awaited feature! Thanks a lot! I have no experience in PWA with Workbox, but how does the mobile application update when the documentation is updated? I also noticed that pictures from FB are not showed in offline mode, is this the way it should be? |
@lex111 thank you! UpdatingI need to verify this myself, but updating shouldn't be a problem when the documentation is updated. First off, the service worker URL should never change between application builds. You can read more about it here, but basically changing the URL will cause the outdated service worker to load if you cache your Now since the service worker URL will always point to the up-to-date service worker, whenever we update the documentation site, a new precache manifest will be generated at the top of the service worker for each build using the InjectManifest plugin: importScripts('/precache-manifest-server.[hash].js');
importScripts(
'/precache-manifest-client.[hash].js',
'/workbox-v[version]/workbox-sw.js',
); The
FB ImagesThe FB images (or more generally images from Markdown posts using A requirement for the precache list to work is that the resource URL has a way to identify different revisions (like a hash in the URL). Since the FB images aren't processed through Webpack and generated with a unique hash, we can't add them to the precache list. So instead, I added FB images as Workbox routes so that when you load it the first time over the network, it'll be cached by the service worker. But if you install the app offline before loading the FB images, they won't show up. I think one way we can fix this is by scanning all Lighthouse ErrorsYeah 😆 So these lighthouse errors are because some tags are missing for iOS and Android. Normally webpack-pwa-manifest would have generated all those tags for us, but because we don't use I think what I can do here instead is add those tags manually instead of having |
Just wanted to let y'all know I'll be a bit slow to responding to feedback and addressing it in my PR due to studying + work. I'm hoping we can get this merged eventually though 😄 |
@codemonkey800 how goes it? I am wondering if we can refuse to use external dependency (Workbox) for SW? For example, how is this done in VuePress? |
@lex111 i've been swamped with work but I'll push my remaining changes either tonight or tomorrow. It includes the PWA popup to reload the page and processes the service worker in Webpack. It is definitely possible to make this work without Workbox. The main things we use Workbox for is:
VuePress also uses workbox, specifically the |
@codemonkey800 I will check it soon, will I get recommendations on how to correctly check PWA? What could be the negative consequences of this? |
@lex111 You could run PWA Lighthouse audits in your dev tools on the preview website. You can also refer to the PWA checklist: https://web.dev/pwa-checklist/ To check the update popup, you'll need to:
Some possible negatives I can think of are:
There are definitely tradeoffs when making a PWA, but I think it should be up to the discretion of the user if they want to add it. However, whether we add it to the docusuaurs site itself is up for debate 😅 |
@codemonkey800 thanks for detail input. Hmm, maybe it makes sense to activate PWA only in certain cases? For example, if the user explicitly install the site as an application? If the user visited the site with mobile? I described these cases in this pseudocode: let forceOffline = location.search.includes('offline');
function initSW() {
navigator.serviceWorker.register('/sw.js')
}
function isSaveDate() {
let saveData = navigator.connection && navigator.connection.saveData
return window.innerWidth <= 940 || saveData
}
if ((forceOffline || !isSaveDate()) && navigator.serviceWorker) {
// init SW if the user turned on save data mode or they just went to a page from a mobile OR `force` option exists (for testing purposes)
// See https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/save-data/ for details
} else if (localStorage.appinstalled) {
// init SW if user installed site as an app and refresh a page
} else {
window.addEventListener('appinstalled', () => {
// init SW if installed site as an app
localStorage.appinstalled = true;
});
} What do you think? |
@lex111 For sure, I think that sounds like a good idea. How about we make this the default behavior and add an option like I will need to research and see if it's possible to install an app and run the service worker after because usually it's the other way around |
@codemonkey800 I’m not sure exactly whether this option is needed, because in my view PWA + Offline is only needed for certain cases (mobile devices, or if the site is implicitly using it as an application). I updated example above to show the init SW, isn’t this the case in reality? |
@lex111 Oh okay never mind I think I understand now. One thing I'm wondering is how should we let the user force offline mode? Aside from adding |
@codemonkey800 yep, something like "https://v2.docusaurus.io/?offline" ( |
@codemonkey800 will there be a way to specify the Workbox caching strategy in the https://developers.google.com/web/tools/workbox/modules/workbox-strategies |
@nebrelbug There's currently no way to specify the strategy for the precache manifest unfortunately. See GoogleChrome/workbox#1767 However, you can set up your own runtime strategies using the custom service worker but it won't be added to the cache at the very start like resources in the precache manifest |
@lex111 In order for the app install button to show, there needs to be a running service worker, so we can't do registration after 😢 An app will also not be installable unless it's available offline: |
@codemonkey800 too bad, are there any options to get around this? For example, check the conditions for the use of PWA in the service worker? |
@lex111 We could possibly pass an empty array into Then when the user installs the app, we can emit a An issue I see here is if the user uninstalls the app, I don't think there's currently a way to detect that, so the service worker will continue to precache files. Is this okay? |
Hey @codemonkey800 , I think this PR is ready. If you have some time to review my changes, so that I can merge it asap, that would be great. Otherwise I'll merge it tomorrow. As it's a plugin, and we are in alpha, we think it's better to get it merged, and see if we have some feedbacks and bug reports to improve it. Major changes:
Overall your code worked great, thanks for your work. Doc: https://deploy-preview-2205--docusaurus-2.netlify.app/docs/next/using-plugins/#docusaurusplugin-pwa |
@slorber wow, this is amazing work 😄 I'll take a look at all the code today, but from what I've seen it's looking very good. thank you so much for the help |
@slorber I finished reviewing the new code. I love all the new changes you added, it makes the PWA a lot more robust 😄 |
awesome @codemonkey800 , let's merge this finally! 🎉 |
Finally! Thanks @codemonkey800 @slorber @lex111! |
Nice work guys! Can't wait for the release :-) @codemonkey800 @slorber @lex111 |
Hey all, this is feature is now released! |
Changes
@docusaurus/plugin-pwa
@docusaurus/plugin-pwa
to v2 website, adding offline/PWA supportMotivation
Implements offline support as requested in #458. Having offline support is beneficial for a dev that needs documentation to work on a project where internet is slow or inaccessible (i.e. airplanes, trains, etc.)
Have you read the Contributing Guidelines on pull requests?
Yes 😄
Test Plan
I've manually tested offline support in the browser and as an installed app. I also ran a lighthouse audit.
Loading Offline
Installing as a Chrome App
Open app in
chrome://apps
Lighthouse Audit
Redirect HTTP to HTTPs is server dependent so it's checked off in the audit.
Update Popup
Related PRs