CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vite-plugin-pwa

Zero-config PWA plugin for Vite that enables offline functionality, service workers, and web app manifest generation.

Pending
Overview
Eval results
Files

virtual-modules.mddocs/

Virtual Module Registration

Framework-specific service worker registration modules that provide seamless integration with React, Vue, Svelte, SolidJS, Preact, and vanilla JavaScript applications.

Capabilities

Vanilla JavaScript Registration

Basic service worker registration for vanilla JavaScript and non-reactive applications.

// Virtual module: virtual:pwa-register
/**
 * Registers the service worker and returns an update function
 * @param options - Registration options including callbacks for SW events
 * @returns Promise-based function to trigger service worker updates
 */
function registerSW(options?: RegisterSWOptions): (reloadPage?: boolean) => Promise<void>;

interface RegisterSWOptions {
  immediate?: boolean;
  onNeedRefresh?: () => void;
  onOfflineReady?: () => void;
  onRegistered?: (registration?: ServiceWorkerRegistration) => void;
  onRegisteredSW?: (swScriptUrl: string, registration?: ServiceWorkerRegistration) => void;
  onRegisterError?: (error: any) => void;
}

Usage Example:

import { registerSW } from "virtual:pwa-register";

const updateSW = registerSW({
  immediate: true,
  onNeedRefresh() {
    if (confirm("New content available. Reload?")) {
      updateSW(true);
    }
  },
  onOfflineReady() {
    console.log("App ready to work offline");
  },
  onRegisterError(error) {
    console.error("SW registration error", error);
  },
});

React Hook Registration

React hook-based service worker registration with state management.

// Virtual module: virtual:pwa-register/react
/**
 * React hook for service worker registration with reactive state
 * @param options - Registration options
 * @returns Object with reactive state and update function
 */
function useRegisterSW(options?: RegisterSWOptions): {
  needRefresh: [boolean, Dispatch<SetStateAction<boolean>>];
  offlineReady: [boolean, Dispatch<SetStateAction<boolean>>];
  updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};

Usage Example:

import React from "react";
import { useRegisterSW } from "virtual:pwa-register/react";

function PWABadge() {
  const {
    needRefresh: [needRefresh, setNeedRefresh],
    offlineReady: [offlineReady, setOfflineReady], 
    updateServiceWorker,
  } = useRegisterSW({
    onRegisteredSW(swUrl, r) {
      console.log(`Service Worker at: ${swUrl}`);
    },
    onRegisterError(error) {
      console.log("SW registration error", error);
    },
  });

  const close = () => {
    setOfflineReady(false);
    setNeedRefresh(false);
  };

  return (
    <div className="pwa-toast" role="alert">
      {(offlineReady || needRefresh) && (
        <div className="pwa-message">
          {offlineReady ? (
            <span>App ready to work offline</span>
          ) : (
            <span>New content available, click to update.</span>
          )}
          <div>
            {needRefresh && (
              <button onClick={() => updateSW(true)}>Reload</button>
            )}
            <button onClick={close}>Close</button>
          </div>
        </div>
      )}
    </div>
  );
}

Vue Composable Registration

Vue 3 composable for service worker registration with reactive refs.

// Virtual module: virtual:pwa-register/vue
/**
 * Vue composable for service worker registration with reactive state
 * @param options - Registration options
 * @returns Object with reactive refs and update function
 */
function useRegisterSW(options?: RegisterSWOptions): {
  needRefresh: Ref<boolean>;
  offlineReady: Ref<boolean>;
  updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};

Usage Example:

<template>
  <div v-if="offlineReady || needRefresh" class="pwa-toast" role="alert">
    <div class="message">
      <span v-if="offlineReady">App ready to work offline</span>
      <span v-else>New content available, click to update.</span>
    </div>
    <div class="buttons">
      <button v-if="needRefresh" @click="updateServiceWorker(true)">
        Reload
      </button>
      <button @click="close">Close</button>
    </div>
  </div>
</template>

<script setup>
import { useRegisterSW } from "virtual:pwa-register/vue";

const { needRefresh, offlineReady, updateServiceWorker } = useRegisterSW({
  onRegisteredSW(swUrl, r) {
    console.log(`Service Worker at: ${swUrl}`);
  },
  onRegisterError(error) {
    console.log("SW registration error", error);
  },
});

function close() {
  offlineReady.value = false;
  needRefresh.value = false;
}
</script>

Svelte Store Registration

Svelte store-based service worker registration with writable stores.

// Virtual module: virtual:pwa-register/svelte
/**
 * Svelte store-based service worker registration
 * @param options - Registration options
 * @returns Object with writable stores and update function
 */
function useRegisterSW(options?: RegisterSWOptions): {
  needRefresh: Writable<boolean>;
  offlineReady: Writable<boolean>;
  updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};

Usage Example:

<script>
  import { useRegisterSW } from "virtual:pwa-register/svelte";

  const { needRefresh, offlineReady, updateServiceWorker } = useRegisterSW({
    onRegisteredSW(swUrl, r) {
      console.log(`Service Worker at: ${swUrl}`);
    },
    onRegisterError(error) {
      console.log("SW registration error", error);
    },
  });

  function close() {
    $offlineReady = false;
    $needRefresh = false;
  }
</script>

{#if $offlineReady || $needRefresh}
  <div class="pwa-toast" role="alert">
    <div class="message">
      {#if $offlineReady}
        <span>App ready to work offline</span>
      {:else}
        <span>New content available, click to update.</span>
      {/if}
    </div>
    <div class="buttons">
      {#if $needRefresh}
        <button on:click={() => updateServiceWorker(true)}>Reload</button>
      {/if}
      <button on:click={close}>Close</button>
    </div>
  </div>
{/if}

SolidJS Signal Registration

SolidJS signal-based service worker registration with accessor/setter pairs.

// Virtual module: virtual:pwa-register/solid
/**
 * SolidJS signal-based service worker registration
 * @param options - Registration options  
 * @returns Object with signal accessor/setter pairs and update function
 */
function useRegisterSW(options?: RegisterSWOptions): {
  needRefresh: [Accessor<boolean>, Setter<boolean>];
  offlineReady: [Accessor<boolean>, Setter<boolean>];
  updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};

Usage Example:

import { Component, Show } from "solid-js";
import { useRegisterSW } from "virtual:pwa-register/solid";

const PWABadge: Component = () => {
  const {
    needRefresh: [needRefresh, setNeedRefresh],
    offlineReady: [offlineReady, setOfflineReady],
    updateServiceWorker,
  } = useRegisterSW({
    onRegisteredSW(swUrl, r) {
      console.log(`Service Worker at: ${swUrl}`);
    },
    onRegisterError(error) {
      console.log("SW registration error", error);
    },
  });

  const close = () => {
    setOfflineReady(false);
    setNeedRefresh(false);
  };

  return (
    <Show when={offlineReady() || needRefresh()}>
      <div class="pwa-toast" role="alert">
        <div class="message">
          <Show
            when={offlineReady()}
            fallback={<span>New content available, click to update.</span>}
          >
            <span>App ready to work offline</span>
          </Show>
        </div>
        <div class="buttons">
          <Show when={needRefresh()}>
            <button onClick={() => updateServiceWorker(true)}>Reload</button>
          </Show>
          <button onClick={close}>Close</button>
        </div>
      </div>
    </Show>
  );
};

Preact Hook Registration

Preact hook-based service worker registration with state updaters.

// Virtual module: virtual:pwa-register/preact
/**
 * Preact hook for service worker registration with state management
 * @param options - Registration options
 * @returns Object with state values/updaters and update function
 */
function useRegisterSW(options?: RegisterSWOptions): {
  needRefresh: [boolean, StateUpdater<boolean>];
  offlineReady: [boolean, StateUpdater<boolean>];
  updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};

Usage Example:

import { h } from "preact";
import { useRegisterSW } from "virtual:pwa-register/preact";

function PWABadge() {
  const {
    needRefresh: [needRefresh, setNeedRefresh],
    offlineReady: [offlineReady, setOfflineReady],
    updateServiceWorker,
  } = useRegisterSW({
    onRegisteredSW(swUrl, r) {
      console.log(`Service Worker at: ${swUrl}`);
    },
    onRegisterError(error) {
      console.log("SW registration error", error);
    },
  });

  const close = () => {
    setOfflineReady(false);
    setNeedRefresh(false);
  };

  return (
    (offlineReady || needRefresh) && (
      <div className="pwa-toast" role="alert">
        <div className="message">
          {offlineReady ? (
            <span>App ready to work offline</span>
          ) : (
            <span>New content available, click to update.</span>
          )}
        </div>
        <div className="buttons">
          {needRefresh && (
            <button onClick={() => updateServiceWorker(true)}>Reload</button>
          )}
          <button onClick={close}>Close</button>
        </div>
      </div>
    )
  );
}

Registration Options

Service Worker Registration Configuration

Common options available across all framework integrations.

interface RegisterSWOptions {
  /** Register service worker immediately on load */
  immediate?: boolean;
  /** Called when new content is available and user confirmation is needed */
  onNeedRefresh?: () => void;
  /** Called when app is ready to work offline */
  onOfflineReady?: () => void;
  /** 
   * Called after service worker registration (deprecated)
   * @deprecated Use onRegisteredSW instead
   */
  onRegistered?: (registration?: ServiceWorkerRegistration) => void;
  /** Called after service worker registration with SW URL and registration */
  onRegisteredSW?: (swScriptUrl: string, registration?: ServiceWorkerRegistration) => void;
  /** Called when service worker registration fails */
  onRegisterError?: (error: any) => void;
}

Update Service Worker Function

Function signature for triggering service worker updates across all frameworks.

/**
 * Triggers service worker update and page reload
 * @param reloadPage - Whether to reload page after update (deprecated parameter)
 * @returns Promise that resolves when update is complete
 */
type UpdateServiceWorker = (reloadPage?: boolean) => Promise<void>;

Virtual Module Access Patterns

Import Patterns

Different ways to import virtual modules based on your setup:

// Standard imports
import { registerSW } from "virtual:pwa-register";
import { useRegisterSW } from "virtual:pwa-register/react";
import { useRegisterSW } from "virtual:pwa-register/vue";

// With type imports
import type { RegisterSWOptions } from "virtual:pwa-register";
import type { RegisterSWOptions } from "virtual:pwa-register/react";

// Re-exported from main package
import type { RegisterSWOptions } from "vite-plugin-pwa";

Conditional Registration

Pattern for conditional service worker registration:

import { registerSW } from "virtual:pwa-register";

if ("serviceWorker" in navigator) {
  const updateSW = registerSW({
    immediate: false,
    onNeedRefresh() {
      // Show update prompt to user
      showUpdatePrompt(() => updateSW(true));
    },
    onOfflineReady() {
      // Notify user app works offline
      showOfflineNotification();
    },
  });
}

Install with Tessl CLI

npx tessl i tessl/npm-vite-plugin-pwa

docs

index.md

plugin-configuration.md

pwa-info-assets.md

virtual-modules.md

tile.json