isSafari
Determines if the current browser is Safari.
1/**
2 * Determines if the current browser is Safari.
3 *
4 * @returns True if running in Safari, false otherwise.
5 */
6export function isSafari(): boolean {
7 if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;
8
9 const ua = navigator.userAgent;
10 return /Safari/.test(ua) && !/Chrome|Chromium|Edg|Android/.test(ua);
11}
Clear Differentiation from Chromium Browsers
Uses explicit negative checks for
Chrome
,Chromium
,Edg
, andAndroid
to avoid false positives common in Safari detection.Cross-Platform Awareness
Correctly excludes Android-based browsers that might include “Safari” in their user agent string.
Safe in Non-Browser Environments
Includes guards for
navigator
andwindow
to prevent runtime errors in server-side or non-browser contexts.No Dependency on Browser-Specific APIs
Relies only on user agent string parsing, making it lightweight and broadly compatible.
Tests | Examples
1const originalNavigator = global.navigator;
2
3afterEach(() => {
4 global.navigator = originalNavigator;
5});
6
7test('returns true for Safari userAgent', () => {
8 // @ts-ignore
9 global.navigator = {
10 userAgent:
11 'Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ' +
12 'Version/15.0 Safari/605.1.15'
13 };
14 expect(isSafari()).toBe(true);
15});
16
17test('returns false for Chrome userAgent', () => {
18 // @ts-ignore
19 global.navigator = {
20 userAgent:
21 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' +
22 'Chrome/96.0.4664.45 Safari/537.36'
23 };
24 expect(isSafari()).toBe(false);
25});
26
27test('returns false for Edge userAgent', () => {
28 // @ts-ignore
29 global.navigator = {
30 userAgent:
31 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' +
32 'Chrome/90.0.818.62 Safari/537.36 Edg/90.0.818.62'
33 };
34 expect(isSafari()).toBe(false);
35});
36
37test('returns false if navigator is undefined', () => {
38 // @ts-ignore
39 delete global.navigator;
40 expect(isSafari()).toBe(false);
41});
Common Use Cases
Safari-Specific CSS or JS Fixes
Apply platform-specific workarounds for known Safari quirks (e.g., flexbox bugs, input styling).
Feature Detection Fallbacks
Trigger alternate behavior when Safari lacks support for modern APIs (e.g.,
WebP
,backdrop-filter
).Conditional Analytics or Logging
Adjust tracking or debugging output based on browser identity.
WebKit Behavior Adjustments
Handle cases where Safari behaves differently due to its WebKit engine, such as scroll handling or event bubbling.