UNPKG

react-pwa-hazhtech

Version:

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

416 lines (311 loc) • 9.49 kB
# 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 ```bash npm install react-pwa-hazhtech ``` ## Quick Start ### 1. Wrap your app with PWAProvider ```tsx 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 ```tsx 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. ```tsx <PWAProvider> {/* Your app components */} </PWAProvider> ``` ### usePWA Hook The `usePWA` hook provides access to PWA functionality and state. ```tsx 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. ```tsx 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. ```tsx 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. ```tsx 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). ```tsx 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. ```tsx import { PWAContextType } from 'react-pwa-hazhtech'; // PWAContextType includes all the hook properties and methods ``` ## Advanced Usage ### Using the Hook in Components ```tsx 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: ```tsx 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 ```tsx 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: ```js 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: ```tsx // 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: ```json { "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: ```html <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](https://github.com/hazhtech/react-pwa-hazhtech) ## Support If you have any questions or issues, please [open an issue](https://github.com/hazhtech/react-pwa-hazhtech/issues) on GitHub.-worker.js` To enable basic service worker behavior in the consuming app, add the following `service-worker.js`: ```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`: ```ts 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](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Donate-yellow?logo=buy-me-a-coffee&style=for-the-badge)](https://buymeacoffee.com/sathish.hazhtech)