包详细信息

react-pwa-hazhtech

hazhtech0MIT1.0.1

A React library for Progressive Web App (PWA) functionality with install prompts and status tracking

react, pwa, progressive-web-app, install

自述文件

react-pwa-hazhtech

A React library for Progressive Web App (PWA) functionality with install prompts, status tracking, and standalone mode detection.

Features

  • 🚀 PWA Install Prompts: Easy-to-use install prompt functionality
  • 📱 Status Tracking: Track PWA installation and standalone mode status
  • 🎯 TypeScript Support: Full TypeScript support with type definitions
  • Lightweight: Minimal bundle size with tree-shaking support
  • 🔧 Easy Integration: Simple React context-based API

Installation

npm install react-pwa-hazhtech

Quick Start

1. Wrap your app with PWAProvider

import React from 'react';
import { PWAProvider } from 'react-pwa-hazhtech';
import App from './App';

function Root() {
  return (
    <PWAProvider>
      <App />
    </PWAProvider>
  );
}

export default Root;

2. Use the PWA hook in your components

import React from 'react';
import { usePWA } from 'react-pwa-hazhtech';

function InstallButton() {
  const { isInstallable, isInstalled, isStandalone, promptInstall } = usePWA();

  const handleInstall = async () => {
    try {
      const result = await promptInstall();
      if (result?.outcome === 'accepted') {
        console.log('PWA installed successfully');
      }
    } catch (error) {
      console.error('Installation failed:', error);
    }
  };

  if (isInstalled || isStandalone) {
    return <div>App is already installed</div>;
  }

  if (!isInstallable) {
    return <div>App is not installable</div>;
  }

  return (
    <button onClick={handleInstall}>
      Install App
    </button>
  );
}

export default InstallButton;

API Reference

PWAProvider

The PWAProvider component provides PWA context to your application.

<PWAProvider>
  {/* Your app components */}
</PWAProvider>

usePWA Hook

The usePWA hook provides access to PWA functionality and state.

const {
  isInstallable,
  isInstalled,
  isStandalone,
  promptInstall,
  installPromptEvent
} = usePWA();

Properties

Property Type Description
isInstallable boolean Whether the app can be installed
isInstalled boolean Whether the app has been installed
isStandalone boolean Whether the app is running in standalone mode
promptInstall `() => Promise<{outcome: 'accepted' \ 'dismissed'} \ null>` Function to trigger the install prompt
installPromptEvent `BeforeInstallPromptEvent \ null` Raw browser install prompt event

Methods

promptInstall()

Triggers the PWA installation prompt.

const result = await promptInstall();
if (result?.outcome === 'accepted') {
  // User accepted the installation
} else if (result?.outcome === 'dismissed') {
  // User dismissed the installation
} else {
  // Install prompt not available
}

Returns: Promise<{outcome: 'accepted' | 'dismissed'} | null>

Standalone Functions

These utility functions can be used without the PWA context:

triggerPWAInstall()

Triggers PWA installation without using the hook context.

import { triggerPWAInstall } from 'react-pwa-hazhtech';

const handleInstall = async () => {
  const result = await triggerPWAInstall();
  if (result?.outcome === 'accepted') {
    console.log('Installation successful');
  }
};

Returns: Promise<{outcome: 'accepted' | 'dismissed'} | null>

isPWAInstallAvailable()

Checks if PWA installation is available.

import { isPWAInstallAvailable } from 'react-pwa-hazhtech';

if (isPWAInstallAvailable()) {
  // Show install button
}

Returns: boolean

isPWAMode()

Checks if the app is running as a PWA (standalone mode).

import { isPWAMode } from 'react-pwa-hazhtech';

if (isPWAMode()) {
  // App is running as PWA
}

Returns: boolean

TypeScript Support

This library includes full TypeScript support. The BeforeInstallPromptEvent type is automatically available when using the library.

import { PWAContextType } from 'react-pwa-hazhtech';

// PWAContextType includes all the hook properties and methods

Advanced Usage

Using the Hook in Components

import { usePWA } from 'react-pwa-hazhtech';

function PWAStatus() {
  const { isInstalled, isInstallable, isStandalone } = usePWA();

  return (
    <div>
      <p>Installable: {isInstallable ? 'Yes' : 'No'}</p>
      <p>Installed: {isInstalled ? 'Yes' : 'No'}</p>
      <p>Standalone: {isStandalone ? 'Yes' : 'No'}</p>
    </div>
  );
}

Using Standalone Functions

For cases where you need to trigger installation outside of the React context:

import { triggerPWAInstall, isPWAInstallAvailable } from 'react-pwa-hazhtech';

// In any JavaScript function
const installApp = async () => {
  if (isPWAInstallAvailable()) {
    const result = await triggerPWAInstall();
    if (result?.outcome === 'accepted') {
      console.log('App installed successfully!');
    }
  }
};

// Can be called from anywhere
document.getElementById('install-btn')?.addEventListener('click', installApp);

Custom Install Flow

import { usePWA } from 'react-pwa-hazhtech';

function CustomInstallFlow() {
  const { isInstallable, promptInstall, installPromptEvent } = usePWA();
  const [showPrompt, setShowPrompt] = useState(false);

  useEffect(() => {
    if (isInstallable && !localStorage.getItem('installPromptShown')) {
      setShowPrompt(true);
    }
  }, [isInstallable]);

  const handleInstall = async () => {
    try {
      const result = await promptInstall();
      if (result?.outcome === 'accepted') {
        console.log('Installation successful');
      }
      setShowPrompt(false);
      localStorage.setItem('installPromptShown', 'true');
    } catch (error) {
      console.error('Installation error:', error);
    }
  };

  const handleDismiss = () => {
    setShowPrompt(false);
    localStorage.setItem('installPromptShown', 'true');
  };

  if (!showPrompt) return null;

  return (
    <div className="install-prompt">
      <h3>Install Our App</h3>
      <p>Install our app for the best experience!</p>
      <button onClick={handleInstall}>Install</button>
      <button onClick={handleDismiss}>Maybe Later</button>
    </div>
  );
}

PWA Setup Requirements

To use this library effectively, your app needs to meet PWA requirements:

1. Service Worker

Create a public/sw.js file:

const CACHE_NAME = 'my-app-v1';

self.addEventListener('install', (event) => {
  console.log('[Service Worker] Installed');
  self.skipWaiting();
});

self.addEventListener('activate', (event) => {
  console.log('[Service Worker] Activated');
  event.waitUntil(clients.claim());
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        return response || fetch(event.request);
      })
  );
});

2. Register Service Worker

In your main app file:

// Register service worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then((registration) => {
        console.log('SW registered: ', registration);
      })
      .catch((registrationError) => {
        console.log('SW registration failed: ', registrationError);
      });
  });
}

3. Web App Manifest

Create a public/manifest.json file:

{
  "name": "My PWA App",
  "short_name": "MyApp",
  "description": "My Progressive Web App",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "icons": [
    {
      "src": "icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

Add to your HTML head:

<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#000000">

Browser Support

This library supports all modern browsers that implement the PWA standards:

  • Chrome 68+
  • Edge 79+
  • Safari 14.1+ (iOS 14.5+)
  • Firefox 85+ (Android only)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © HazhTech

Support

If you have any questions or issues, please open an issue on GitHub.-worker.jsTo enable basic service worker behavior in the consuming app, add the followingservice-worker.js`:

self.addEventListener('install', (event) => {
  console.log('[Service Worker] Installed');
});

self.addEventListener('activate', (event) => {
  console.log('[Service Worker] Activated');
});

self.addEventListener('fetch', (event) => {
  event.respondWith(fetch(event.request));
});

Register the service worker in your app’s index.tsx:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(registration => console.log('SW registered:', registration))
      .catch(err => console.error('SW registration failed:', err));
  });
}

💖 Support

If you find this package helpful, consider supporting me:

Donate