- vừa được xem lúc

Building an Offline-Ready Web App with Qwik: A Step-by-Step Guide

0 0 7

Người đăng: Nguyễn Hữu Kim

Theo Viblo Asia

In today's fast-paced digital world, we often take connectivity for granted. We assume that our devices will always be online, allowing us to access the web and use apps without interruption. However, there are many situations where a reliable internet connection is not available, such as remote areas or during network outages. This is where building offline-capable apps becomes crucial.

If you are a big fan of Qwik, you may see many people discuss about PWA offline mode with Qwik.

In this article, I'll share my experience of building an offline app with Qwik, a JavaScript framework designed for instant-loading web apps. My app is named CueX.

CueX Teleprompter

Welcome back to Dev Success 101, and I'm Kim. CueX is a free online teleprompter that runs on smartphones, tablets, and desktops, making it your ideal companion for smooth and professional script delivery. It is built with Qwik and TailwindCSS.

I aim to make CueX installable, with an app icon on the home screen, and usable as a native app on mobile/tablet, even offline. That's why it is a PWA.

I attempted to use the Vite PWA plugin to generate a service worker for PWA. This plugin offers various features for PWAs, such as:

  • Generating manifest.json
  • Generating a service worker
  • Auto-update
  • Workbox, etc.

However, it didn't work as expected. I had to set up PWA offline mode by integrating Workbox manually. 😟

Why not Vite PWA plugin?

Vite PWA plugin was my initial choice. Following the plugin's instructions, I installed it using:

yarn add -D vite-plugin-pwa

Subsequently, I updated vite.config.js as follows:

import { defineConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
import tsconfigPaths from "vite-tsconfig-paths";
import { partytownVite } from "@builder.io/partytown/utils";
import { join } from "path";
import { VitePWA } from 'vite-plugin-pwa' export default defineConfig(() => { return { plugins: [ qwikCity(), qwikVite(), tsconfigPaths(), partytownVite({ dest: join(__dirname, "dist", "~partytown") }), // Add VitePWA plugin: VitePWA({ manifest: false, registerType: 'autoUpdate', injectRegister: 'script', // injectRegister need to register service worker by adding the script into `root.tsx` file: // <script src="/registerSW.js"></script> workbox: { globPatterns: ['**/*.{js,css,ico,png,jpg,svg}'] } }), ], preview: { headers: { "Cache-Control": "public, max-age=600", }, }, };
});

Any files matching the globPatterns regex will be cached into the cache storage (note that globPatterns is only for files, not routes).

Unfortunately, I encountered the following error:

Uncaught (in promise) non-precached-url: non-precached-url :: [{"url":"index.html"}]

I attempted to fix this error using some workarounds mentioned in this issue, such as:

 // ... workbox: { globPatterns: ['**/*.{js,css,ico,png,jpg,svg}'], // Don't fallback on document based (e.g. `/some-page`) requests // Even though this says `null` by default, I had to set this specifically to `null` to make it work navigateFallback: null, }

After applying this fix, the error was resolved.

image.png

Checking the generated file sw.js (at the end of the file):

  • Before fix:
// ...
e.cleanupOutdatedCaches()
e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));
  • After fix:
// ...
e.cleanupOutdatedCaches()}));

The error was eliminated because the PWA plugin didn't register the Workbox Navigation Route to /index.html. This means the app didn't precache any route into the cache storage, leading to no offline mode.

image.png

I modified the Workbox config from navigateFallback: null to navigateFallback: '/' with hope. I thought Workbox would create a navigation route /, and then the offline mode would work. However...

image.png

There is no way to register a navigation route manually when using the Vite PWA plugin. Therefore, I believe I need to create a service worker manually, without the Vite PWA plugin.

Building an Offline App with Qwik (Configuring Workbox Manually)

Getting started with this approach is quite straightforward. Qwik has already defined a service worker in the file /src/routes/service-worker.ts, so we can write our code in that file.

As a first step, I will need to install additional dependencies to use Workbox:

yarn add workbox-precaching workbox-routing workbox-strategies

Next, I precache the necessary routes for offline mode. For example, the home page /, logo images, and other assets for which I already know the exact URL.

const revision = import.meta.env.VITE_GIT_COMMIT_HASH; precacheAndRoute([ { url: "/", revision }, { url: "/icon/icon-192x192.png", revision }, { url: "/icon/icon-256x256.png", revision }, { url: "/icon/icon-384x384.png", revision }, { url: "/icon/icon-512x512.png", revision }, { url: "https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js", revision: "1.6.0", },
]); cleanupOutdatedCaches(); // ...

The application also requires CSS, images, and other assets for which I don't know the exact URL. I use workbox-routing to intercept network requests for those files and cache them.

registerRoute(new NavigationRoute(createHandlerBoundToURL("/")));
registerRoute(new NavigationRoute(createHandlerBoundToURL("/?pwa=true"))); // intercept network requests of CSS, Image
registerRoute( ({ request }) => request.destination === "style" || request.destination === "image", new CacheFirst(),
);

There's no need to intercept network requests for JS files because Qwik's service worker already handles that.

Now, the app is ready for offline use!

Conclusion

In conclusion, while I faced challenges with the Vite PWA plugin, the manual configuration of Workbox enabled the seamless implementation of offline mode for the Qwik app. Don't forget to subscribe to the channel for more updates on Qwik and web development tips. Happy coding!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt project Vue với Vue 3 + Vite + Typescript + Tailwind

Là một tác phẩm của Evan You ra mắt cùng với Vue 3, Vite được sinh ra như là một sự thay thế cho Webpack. Bài viết này sẽ giới thiệu tới mọi người một combo mới với tốc độ build cực lý nhanh chóng và

0 0 337

- vừa được xem lúc

[CLI] Trong Vue CLI có gì? Tại sao newbie không nên bỏ qua?

Trong bài viết này mình hướng đến đối tượng là các bạn newbie. Các bạn mới hoặc chưa có nhiều kinh nghiệm làm việc với Vue và các framework khác nói chung.

0 0 56

- vừa được xem lúc

Build Vaccine Passport System | Chapter 2 - Admin Panel | ReactJS Material-UI ViteJS React Router v6

Build Vaccine Passport System | Chapter 2 - Admin Panel | ReactJS Material-UI ViteJS React Router v6. .

0 0 56

- vừa được xem lúc

[Series] Setup Source Template for Vue 3 - Phần 2

Giới thiệu. Chào tất cả các bạn, phần 1 mình đã giới thiệu tổng quát về source code và setup cơ bản về Vue 3 + Vite.

0 0 19

- vừa được xem lúc

Offline fallback page - Unpacking the Workbox

With service workers it is possible to implement an offline experience for our web app, but there are cases, when the user is offline, that all our app does is display a message letting the user know

0 0 24

- vừa được xem lúc

Tạo SSL Certificate Authority cho HTTPS trên local

Trên đây cũng có khá nhiều bài viết làm sao để tạo self-signed SSL cho localhost để có thể test thử HTTPS. Nhưng những cách đó đều có một nhược điểm là khi vào trang sẽ có cảnh báo NET::ERR_CERT_AUTHO

0 0 32