A modern, production-ready web application demonstrating push notification implementation using OneSignal. Built with React 19, TypeScript, and Vite, this project provides a comprehensive example of integrating browser push notifications with real-time subscription management and user-friendly UI.
- Features
- Tech Stack
- Prerequisites
- Installation
- Configuration
- Running the Application
- Project Structure
- How It Works
- Usage Guide
- Building for Production
- Deployment
- Troubleshooting
- Contributing
- OneSignal Integration: Enterprise-grade push notification infrastructure supporting all major browsers
- Real-time Subscription Management: Track and display push subscription status with live updates
- Permission Handling: Graceful browser notification permission requests with status feedback
- Test Notification System: Built-in functionality to send and test notifications locally
- User Authentication: Simple username-based authentication with localStorage persistence
- Notification History: View all received notifications with timestamps in a scrollable feed
- Service Worker Integration: Proper service worker setup for background notifications
- Foreground Notifications: Handle notifications when the app is active
- Subscription Diagnostics: Check subscription ID and opt-in status
- Error Handling: Comprehensive error handling for OneSignal initialization and operations
- Responsive Design: Modern, mobile-friendly UI with gradient styling
- TypeScript: Full type safety throughout the application
- Modern Design: Beautiful gradient backgrounds with glassmorphism effects
- Status Indicators: Visual feedback for notification permissions and subscription state
- Real-time Updates: Instant notification display without page refresh
- User-friendly Interface: Clean, intuitive layout with clear action buttons
- React 19.1.1 - Latest React with improved performance and features
- TypeScript 5.8.3 - Static typing for enhanced developer experience
- Vite 7.1.7 - Fast build tool with HMR (Hot Module Replacement)
- react-onesignal 3.4.0 - Official OneSignal SDK for React
- TailwindCSS 3.4.17 - Utility-first CSS framework
- GSAP 3.13.0 - Professional-grade animation library
- ESLint 9.36.0 - Code linting with React-specific rules
- PostCSS 8.5.6 - CSS transformations
- Autoprefixer 10.4.21 - Automatic vendor prefixing
Before running this project, ensure you have:
- Node.js (v18 or higher) and npm installed
- OneSignal Account: Create a free account at OneSignal
- OneSignal App ID: Set up a web push app in OneSignal dashboard
- Modern Browser: Chrome, Firefox, Safari, or Edge with push notification support
-
Clone the repository
git clone <repository-url> cd react-push-notifs
-
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env # Edit .env with your OneSignal App ID
Create a .env file in the root directory:
VITE_ONESIGNAL_APP_ID=your-onesignal-app-id-hereHow to get your OneSignal App ID:
- Log in to OneSignal Dashboard
- Create a new Web Push app or select existing one
- Navigate to Settings → Keys & IDs
- Copy the "OneSignal App ID"
The project includes required OneSignal service worker files in the public/ directory:
OneSignalSDKWorker.js- Main service workerOneSignalSDK.sw.js- OneSignal SDK service workerOneSignalSDKUpdaterWorker.js- Update handler
These files are automatically served by Vite and enable background notification support.
The vite.config.ts includes special configuration for development:
export default defineConfig({
plugins: [react()],
server: {
allowedHosts: ['.ngrok-free.app', '.ngrok.io'],
},
})This allows testing with tunneling services like ngrok for testing push notifications on mobile devices.
npm run devThe application will start at http://localhost:5173 (or next available port).
Push notifications require HTTPS or localhost. To test on mobile devices:
# Start the dev server
npm run dev
# In another terminal, start ngrok
ngrok http 5173Use the provided ngrok URL to access the app from any device.
npm run lintnpm run build # This includes type checkingreact-push-notifs/
├── public/
│ ├── OneSignalSDKWorker.js # Service worker for OneSignal
│ ├── OneSignalSDK.sw.js # OneSignal SDK service worker
│ ├── OneSignalSDKUpdaterWorker.js # Service worker updater
│ └── vite.svg # App icon
├── src/
│ ├── components/
│ │ └── PushNotification.tsx # Notification component
│ ├── hooks/
│ │ └── useOneSignal.ts # OneSignal custom hook
│ ├── App.tsx # Main application component
│ ├── main.tsx # Application entry point
│ └── index.css # Global styles
├── .env # Environment variables
├── vite.config.ts # Vite configuration
├── tailwind.config.js # TailwindCSS configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies
- Initialization: On app load, OneSignal SDK initializes with your App ID
- Service Worker Registration: Browser registers OneSignal service workers
- Permission Request: User clicks "Enable Notifications" button
- Subscription: Browser requests permission and creates push subscription
- Token Generation: OneSignal generates a unique subscription ID
- Notification Delivery:
- Foreground: Notifications received while app is open
- Background: Service worker handles notifications when app is closed
Main application logic including:
- OneSignal initialization
- Subscription state management
- Notification permission handling
- User authentication flow
- UI rendering
The public service worker files handle:
- Background notification reception
- Notification click events
- Push subscription management
The app uses React hooks for state management:
useStatefor local component stateuseEffectfor OneSignal initialization and lifecycleuseRefto prevent duplicate initializationlocalStoragefor username persistence
- Access the Application: Open the app in your browser
- Enter Username: Provide a username to continue
- Enable Notifications: Click "Enable Notifications" and allow browser permission
- Check Status: View your subscription status in the sidebar
- Test Notifications: Use the test form to send local notifications
- View History: All notifications appear in the "Recent Notifications" panel
To send notifications from your server, use OneSignal's REST API:
const sendNotification = async (subscriptionId, title, message) => {
const response = await fetch('https://onesignal.com/api/v1/notifications', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic YOUR_REST_API_KEY'
},
body: JSON.stringify({
app_id: 'YOUR_APP_ID',
include_player_ids: [subscriptionId],
headings: { en: title },
contents: { en: message }
})
});
return response.json();
};// Foreground notifications
OneSignal.Notifications.addEventListener('foregroundWillDisplay', (event) => {
console.log('Notification received:', event.notification);
});
// Notification clicks
OneSignal.Notifications.addEventListener('click', (event) => {
console.log('Notification clicked:', event.notification);
});const subscriptionId = OneSignal.User.PushSubscription.id;
const optedIn = OneSignal.User.PushSubscription.optedIn;
const token = OneSignal.User.PushSubscription.token;npm run buildThis creates an optimized production build in the dist/ directory.
npm run preview- HTTPS Required: Push notifications only work on HTTPS domains (except localhost)
- Service Worker Scope: Ensure service workers are served from root domain
- Environment Variables: Set production OneSignal App ID
- CSP Headers: Configure Content Security Policy if needed
- Browser Compatibility: Test on all target browsers
- Vercel: Zero-config deployment for Vite apps
- Netlify: Simple continuous deployment
- AWS Amplify: Full-stack deployment
- Firebase Hosting: Google's hosting solution
# Install Vercel CLI
npm i -g vercel
# Deploy
vercelSet VITE_ONESIGNAL_APP_ID in your hosting platform's environment variable settings.
1. Notifications not working
- Verify HTTPS or localhost usage
- Check browser notification permissions
- Ensure OneSignal App ID is correct
- Check browser console for errors
2. Service Worker errors
- Clear browser cache and service workers
- Ensure service worker files are in
public/directory - Check network tab for 404 errors on worker files
3. Subscription not creating
- Wait a moment after permission grant
- Check OneSignal dashboard for subscription
- Verify browser supports push notifications
- Try in incognito mode to rule out extension conflicts
4. Permission already denied
- Guide users to browser settings
- Instructions vary by browser (Chrome: Site Settings → Notifications)
5. Build errors
- Clear node_modules and reinstall:
rm -rf node_modules && npm install - Check Node.js version compatibility
- Run
npm run lintto check for code issues
Check browser console for OneSignal debug logs. Enable verbose logging:
OneSignal.Debug.setLogLevel('trace');Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow TypeScript best practices
- Use ESLint configuration provided
- Write meaningful commit messages
- Test on multiple browsers before submitting
This project is open source and available under the MIT License.
For issues and questions:
- Check existing GitHub Issues
- Review OneSignal Support
- Check browser compatibility tables
Built with by [Your Name] | Powered by OneSignal