Skip to content

Add PWA support to vitepress with offline capabilities#337

Merged
jinzhongjia merged 4 commits into
mainfrom
vite-pwa-vitepress
Jun 24, 2026
Merged

Add PWA support to vitepress with offline capabilities#337
jinzhongjia merged 4 commits into
mainfrom
vite-pwa-vitepress

Conversation

@jinzhongjia

Copy link
Copy Markdown
Member

Summary

Adds Progressive Web App (PWA) support to the VitePress documentation site, enabling offline access and app-like experience for users.

Changes

  • Installed @vite-pwa/vitepress (1.1.0) and vite-plugin-pwa (1.3.0) dependencies
  • Wrapped VitePress config with withPwa() to enable PWA integration
  • Configured manifest with app metadata (name, icons, theme colors, display mode)
  • Set up Workbox for aggressive static asset caching (all JS, CSS, HTML, images, fonts)
  • Configured auto-update strategy for service worker updates

Benefits

  • Users can read the entire course offline after first visit (all assets < 2 MiB, full site is just a few MB)
  • Installable as a standalone app on supported platforms
  • Improved performance with service worker caching
  • Automatic updates when new content is deployed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds Progressive Web App (PWA) support to the VitePress site by integrating @vite-pwa/vitepress and configuring manifest and caching options. The review feedback suggests critical improvements for deployment portability and user experience: changing the PWA registration type to prompt to avoid dynamic chunk loading errors, removing hardcoded root paths for scope, start URL, and icons to support subpath deployments, and optimizing the Workbox caching strategy by expanding cached file patterns and preventing redundant cache-busting on hashed assets.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

themeConfig: themeConfig,
cleanUrls: true,
pwa: {
registerType: "autoUpdate",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using registerType: "autoUpdate" in a Single Page Application (SPA) like VitePress can lead to ChunkLoadError (or Failed to fetch dynamically imported module) for active users when a new version of the site is deployed.

When a new service worker automatically activates, it deletes the old cached assets (including old JS chunks). If a user is currently browsing the site and navigates to a new page, VitePress will attempt to dynamically import the old JS chunk, which no longer exists in the cache or on the server, causing the navigation to fail.

Changing this to "prompt" is highly recommended for SPAs as it allows you to prompt the user to reload the page to apply updates, avoiding abrupt cache deletion during an active session.

      registerType: "prompt",

Comment thread course/.vitepress/config.mts Outdated
Comment on lines +30 to +32
display: "standalone",
start_url: "/",
scope: "/",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding start_url and scope to "/" breaks PWA portability if the site is ever deployed to a subpath (for example, GitHub Pages under https://<username>.github.io/<repository>/).

By default, vite-plugin-pwa automatically inherits the base path configured in VitePress for both scope and start_url. Removing these hardcoded properties ensures that the PWA will work seamlessly regardless of whether it is deployed to the root domain or a subdirectory.

        display: "standalone",

Comment on lines +34 to +43
{
src: "/android-chrome-192x192.png",
sizes: "192x192",
type: "image/png",
},
{
src: "/android-chrome-512x512.png",
sizes: "512x512",
type: "image/png",
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using absolute paths starting with a leading slash (e.g., "/android-chrome-192x192.png") for manifest icons will cause them to fail to load if the site is deployed to a subpath (e.g., GitHub Pages).

Removing the leading slash makes these paths relative to the manifest file, ensuring they resolve correctly in both root and subpath deployments.

          {
            src: "android-chrome-192x192.png",
            sizes: "192x192",
            type: "image/png",
          },
          {
            src: "android-chrome-512x512.png",
            sizes: "512x512",
            type: "image/png",
          },

Comment on lines +48 to 51
workbox: {
// 全站静态资源仅几 MB,单文件均 < 2 MiB,可全量预缓存 → 离线可读全部章节
globPatterns: ["**/*.{js,css,html,svg,png,ico,woff2}"],
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To ensure a complete and optimized offline experience, we should make two improvements to the Workbox configuration:

  1. Expand globPatterns: Include other common image formats (like .jpg, .jpeg, .webp) and data files (like .json for search index) so that all content is fully available offline.
  2. Add dontCacheBustURLsMatching: VitePress assets under assets/ already contain content hashes in their filenames (e.g., index.d7a8f8b9.js). Configuring dontCacheBustURLsMatching prevents Workbox from appending redundant cache-busting query parameters when fetching these assets, saving bandwidth and improving build/load efficiency.
      workbox: {
        // 全站静态资源仅几 MB,单文件均 < 2 MiB,可全量预缓存 → 离线可读全部章节
        globPatterns: ["**/*.{js,css,html,svg,png,jpg,jpeg,webp,json,ico,woff2}"],
        dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
      },

@jinzhongjia jinzhongjia merged commit ac92dc1 into main Jun 24, 2026
5 checks passed
@jinzhongjia jinzhongjia deleted the vite-pwa-vitepress branch June 24, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant