Back to blog
EngineeringApr 6, 2026· min read

Fixing Voice Input on Safari: A Browser Compatibility Deep Dive

Safari treats voice recording differently than Chrome and Firefox. Here's how we fixed MIME type detection, stale closures, and error feedback to make voice input work reliably across all browsers.

Browser compatibility is one of those challenges that looks simple on the surface but reveals layers of complexity the moment you start shipping real features. This week we fixed three interconnected bugs in Sabine's voice recording system that only appeared in Safari.

What Shipped

Safari MIME type detection: Safari doesn't support the same audio codecs as Chrome and Firefox. When users tried to record voice input, the MediaRecorder API would fail silently because we were requesting a MIME type Safari couldn't handle. We added proper codec detection that checks what the browser actually supports before initializing recording.

Stale closure bugs: The voice recording component had event handlers that captured old state values, leading to race conditions where stopping a recording wouldn't properly update the UI or trigger the transcription pipeline. We refactored the state management to use refs and callbacks that always reference current values.

Visible error feedback: When recording failed, users had no idea what went wrong. The button would just stop responding. We added clear error states with specific messages - 'Microphone access denied,' 'Recording format not supported,' or 'Recording failed to start' - so users know exactly what happened and can take action.

Why It Matters

Voice input is a core interaction model for Sabine. When it fails silently, users lose trust in the product. Safari has significant market share, especially among the technical founders and product leaders who are Sabine's primary audience. These fixes mean voice recording now works consistently across Chrome, Firefox, and Safari - no browser-specific workarounds required on the user's end.

The stale closure issue was particularly insidious because it only manifested under specific timing conditions. A user could successfully record once, then find that subsequent recordings wouldn't process. Fixing this required rethinking how we manage component lifecycle and async operations in the recording flow.

What's Next

Now that the core recording pipeline is stable across browsers, we're turning our attention to the transcription quality and speed. We're also exploring progressive enhancement for browsers that support newer audio codecs - better compression means faster uploads and lower bandwidth costs without sacrificing transcription accuracy. The error handling patterns we built here will extend to other real-time features as we continue building out Sabine's voice-first interface.