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 following
service-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: