Progressive Web Apps (PWA) Geliştirme
Progressive Web Apps, web teknolojileri ile native app deneyimi sunar.
PWA Özellikleri
✅ Offline çalışma
✅ Push notifications
✅ Home screen’e ekleme
✅ App-like navigation
✅ Background sync
Manifest Dosyası
{
"name": "My PWA App",
"short_name": "PWA",
"description": "Awesome Progressive Web App",
"start_url": "/",
"display": "standalone",
"theme_color": "#3b82f6",
"background_color": "#ffffff",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Service Worker
// sw.js
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png'
];
// Install
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
// Fetch - Cache First Strategy
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) return response;
return fetch(event.request);
})
);
});
// Update
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
);
});
Register Service Worker
// main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered!', reg))
.catch(err => console.error('SW error:', err));
});
}
Push Notifications
// Request permission
async function requestNotificationPermission() {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('Notification permission granted');
}
}
// Subscribe to push
async function subscribeToPush() {
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY)
});
// Send subscription to server
await fetch('/api/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: { 'Content-Type': 'application/json' }
});
}
// Handle push event (in sw.js)
self.addEventListener('push', (event) => {
const data = event.data.json();
const options = {
body: data.body,
icon: '/icon-192.png',
badge: '/badge-72.png',
vibrate: [100, 50, 100]
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
Background Sync
// Register sync
async function registerBackgroundSync() {
const registration = await navigator.serviceWorker.ready;
await registration.sync.register('sync-messages');
}
// Handle sync (in sw.js)
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-messages') {
event.waitUntil(syncMessages());
}
});
async function syncMessages() {
const messages = await getUnsentMessages();
await Promise.all(
messages.map(msg => sendMessage(msg))
);
}
Install Prompt
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
// Show install button
installButton.style.display = 'block';
});
installButton.addEventListener('click', async () => {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
console.log(`User ${outcome} the install`);
deferredPrompt = null;
});
PWA ile modern, hızlı ve güvenilir uygulamalar!