← Back to Tutorials Chapter 16

Detection & Integration

Feature Detection

Detecting browser capabilities is essential for building resilient PWAs. Use feature detection rather than browser sniffing.

// Comprehensive feature detection
const pwaSupport = {
  serviceWorker: 'serviceWorker' in navigator,
  manifest: document.querySelector('link[rel="manifest"]') !== null,
  notifications: 'Notification' in window,
  push: 'PushManager' in window,
  sync: 'SyncManager' in window,
  cache: 'caches' in window,
  indexedDB: 'indexedDB' in window,
  webShare: navigator.share !== undefined,
  webShareTarget: 'shareTarget' in (document.querySelector('link[rel="manifest"]') || {}),
  badging: navigator.setAppBadge !== undefined,
  credentials: 'credentials' in navigator,
  storage: navigator.storage !== undefined,
  connection: navigator.connection !== undefined,
  wakeLock: 'wakeLock' in navigator,
  screenWakeLock: 'wakeLock' in navigator,
  bluetooth: navigator.bluetooth !== undefined,
  usb: navigator.usb !== undefined,
  nfc: 'NDEFReader' in window,
  fileSystemAccess: 'showDirectoryPicker' in window,
  screenOrientation: screen.orientation !== undefined,
  clipboard: navigator.clipboard !== undefined,
  contacts: 'contacts' in navigator,
  geolocation: 'geolocation' in navigator,
  mediaDevices: navigator.mediaDevices !== undefined,
  internationalization: Intl !== undefined
};

// Use detection to show/hide features
if (pwaSupport.webShare) {
  document.getElementById('share-button').hidden = false;
}

Platform Detection

Detect the user's platform to provide platform-specific enhancements:

// Platform detection
const platform = {
  isAndroid: /android/i.test(navigator.userAgent),
  isIOS: /iphone|ipad|ipod/i.test(navigator.userAgent),
  isWindows: /windows nt/i.test(navigator.userAgent),
  isMacOS: /macintosh|mac os x/i.test(navigator.userAgent),
  isLinux: /linux/i.test(navigator.userAgent),
  isChromeOS: /cros/i.test(navigator.userAgent),
  isMobile: /mobile|android|iphone|ipad/i.test(navigator.userAgent),
  isStandalone: window.matchMedia('(display-mode: standalone)').matches
     || window.navigator.standalone === true,
  isInstalled: window.matchMedia('(display-mode: standalone)').matches
     || window.navigator.standalone === true
};

// Platform-specific adjustments
if (platform.isIOS) {
  // Add iOS-specific meta tags
  document.head.innerHTML += `
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  `;
}

if (platform.isStandalone) {
  // The app is running in standalone mode (installed)
  document.body.classList.add('is-installed');
}

Integration APIs

Web Share API

async function shareContent(title, text, url) {
  if (navigator.share) {
    try {
      await navigator.share({ title, text, url });
      console.log('Shared successfully');
    } catch (err) {
      console.error('Share failed:', err);
    }
  } else {
    // Fallback: copy to clipboard
    await navigator.clipboard.writeText(url);
    alert('Link copied to clipboard!');
  }
}

Credential Management

// Store credentials
async function storeCredentials(email, password) {
  if ('credentials' in navigator) {
    const cred = new PasswordCredential({
      id: email,
      password: password,
      name: 'My PWA'
    });
    await navigator.credentials.store(cred);
  }
}

// Auto-fill credentials
async function autoSignIn() {
  if ('credentials' in navigator) {
    const cred = await navigator.credentials.get({
      password: true,
      mediation: 'optional'
    });
    if (cred) {
      // Auto-fill the login form
      document.getElementById('email').value = cred.id;
      document.getElementById('password').value = cred.password;
    }
  }
}
Exercise: Create a feature detection dashboard that displays all supported PWA APIs on the user's browser. Use CSS grid to show each feature with a green checkmark (supported) or red X (not supported). Add the Web Share API as a share button on the page.