Dev.to WebDev 🛠 Dev 👁 0 📖 4 min read

Web APIs in Firefox: Notifications, Web Share, File System, Web Locks, and What's Missing

Firefox implements a large set of modern web APIs. Here's a practical overview of APIs that either work differently in Firefox vs Chrome, or that Firefox has ahead of Chrome. Notifications API // Request p

Firefox implements a large set of modern web APIs. Here's a practical overview of APIs that either work differently in Firefox vs Chrome, or that Firefox has ahead of Chrome.

Notifications API

// Request permission
const permission = await Notification.requestPermission();
if (permission === 'granted') {
  const notification = new Notification('Title', {
    body: 'Notification body',
    icon: '/icon.png',
    badge: '/badge.png',
    tag: 'unique-tag',  // Replace existing notifications with same tag
    requireInteraction: true  // Keep notification visible until dismissed
  });

  notification.onclick = () => {
    window.focus();
    notification.close();
  };
}

Firefox behavior: Notification permissions are per-site. Firefox doesn't show Chrome's "Should [site] send notifications?" for new sites — it waits for the site to request via requestPermission().

Firefox strict popup blocking: If you call requestPermission() outside of a user gesture (click, key press), Firefox blocks the permission prompt. Chrome shows it anyway.

Web Share API

// Share content to mobile apps
await navigator.share({
  title: 'Article title',
  text: 'Check out this article',
  url: 'https://example.com/article'
});

Firefox Android: Fully supported — shows Android share sheet.
Firefox Desktop: Support was added in Firefox 91+, but limited to supporting apps on the OS. On Windows, it integrates with Windows share. On Linux, share targets are limited.

// Check support
if (navigator.canShare && navigator.canShare({ url: 'https://example.com' })) {
  // Share supported for this content
}

Speech Recognition and Synthesis

Speech Synthesis (TTS)

// Text to speech
const utterance = new SpeechSynthesisUtterance('Hello, world!');
utterance.lang = 'en-US';
utterance.rate = 1.0;  // 0.1 to 10
utterance.pitch = 1.0;  // 0 to 2
utterance.volume = 1.0;

// List voices
const voices = speechSynthesis.getVoices();
utterance.voice = voices.find(v => v.name.includes('Google'));

speechSynthesis.speak(utterance);

Firefox TTS support: Uses OS voices. On Windows, uses Windows SAPI voices. On Linux, uses eSpeak if installed. Voice availability varies by OS.

Speech Recognition

const recognition = new webkitSpeechRecognition();  // Chrome
// Firefox: uses SpeechRecognition (no webkit prefix)
const recognition = new SpeechRecognition();

recognition.lang = 'en-US';
recognition.continuous = false;

recognition.onresult = (event) => {
  const transcript = event.results[0][0].transcript;
  console.log('Heard:', transcript);
};

recognition.start();

Firefox: Speech Recognition API requires an about:config flag to enable: media.webspeech.recognition.enable = true. Not enabled by default (privacy considerations — sends audio to a speech server).

File System API

File Picker (works in Firefox)

// Show file picker
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.multiple = true;

fileInput.addEventListener('change', () => {
  Array.from(fileInput.files).forEach(file => {
    console.log(file.name, file.size, file.type);
    const reader = new FileReader();
    reader.onload = (e) => console.log('Data:', e.target.result.slice(0, 100));
    reader.readAsDataURL(file);
  });
});

fileInput.click();

File System Access API (showOpenFilePicker)

// Modern API for reading/writing local files
const [fileHandle] = await window.showOpenFilePicker({
  types: [{ 
    description: 'JSON files', 
    accept: { 'application/json': ['.json'] }
  }]
});

const file = await fileHandle.getFile();
const contents = await file.text();
console.log(contents);

// Write file
const writable = await fileHandle.createWritable();
await writable.write('new contents');
await writable.close();

Firefox 112+ support: Firefox added File System Access API in version 112. Older Firefox versions don't support showOpenFilePicker. Use a feature detection check.

Web Locks API

Prevent concurrent access to shared resources:

// Acquire an exclusive lock
await navigator.locks.request('resource-key', async (lock) => {
  // Only one tab runs this at a time
  await doExclusiveWork();
});

// Acquire with timeout
await navigator.locks.request('resource-key', { 
  ifAvailable: true  // Don't wait, return null if locked
}, async (lock) => {
  if (!lock) {
    console.log('Resource locked, skipping');
    return;
  }
  await doWork();
});

Firefox support: Full support in Firefox 96+. The Web Locks API is useful for preventing duplicate work in multi-tab applications.

Payment Request API

const request = new PaymentRequest(
  [{ supportedMethods: 'basic-card' }],  // Payment methods
  {
    total: { label: 'Total', amount: { currency: 'USD', value: '10.00' } },
    displayItems: [
      { label: 'Item', amount: { currency: 'USD', value: '10.00' } }
    ]
  }
);

const response = await request.show();
const { methodName, details } = response;
await response.complete('success');

Firefox: Supports Payment Request API. In practice, the "basic-card" method shows a Firefox-native payment form. Third-party payment methods (Google Pay, Apple Pay) require merchant integration.

Idle Detection API

const detector = new IdleDetector();

detector.addEventListener('change', () => {
  console.log('User state:', detector.userState);  // 'active' or 'idle'
  console.log('Screen state:', detector.screenState);  // 'locked' or 'unlocked'
});

await detector.start({ threshold: 60_000 });  // Detect after 60s of idle

Firefox 94+: Supports Idle Detection API. Useful for apps that should stop polling or showing notifications when user is away.

Contact Picker API

Pick contacts from the device's contact list:

const contacts = await navigator.contacts.select(
  ['name', 'email', 'tel'],
  { multiple: true }
);

contacts.forEach(contact => {
  console.log(contact.name, contact.email);
});

Firefox: Not yet implemented (as of 2024). This is primarily a mobile API (Android Chrome, iOS Safari support it). Firefox Android doesn't support it.

Badging API

Show a notification badge on the PWA icon:

// Set badge with count
await navigator.setAppBadge(5);

// Clear badge
await navigator.clearAppBadge();

Firefox: Not supported. This API primarily works in Chrome/Edge on desktop and mobile.

Keyboard Map API

// Get physical key names for current keyboard layout
const map = await navigator.keyboard.getLayoutMap();
const key = map.get('KeyQ');  // Returns 'q' for US, 'a' for AZERTY, etc.

Firefox: Supported. Useful for games that should use physical keyboard positions rather than character values.

Summary: Firefox API Support Status

API Firefox
Notifications Full
Web Share Desktop (91+), Full on Android
Speech Synthesis Full
Speech Recognition Experimental (flag)
File System Access 112+
Web Locks 96+
Payment Request Full
Idle Detection 94+
Contact Picker Not supported
Badging API Not supported
Keyboard Map Full
Web Bluetooth Not supported
Web USB Not supported
Web NFC Not supported

Mozilla's stance on sensor APIs (Bluetooth, USB, NFC): Security and privacy concerns. Mozilla hasn't shipped these; they require being near untrusted hardware. This is a deliberate policy difference from Chrome's "ship everything" approach.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.