Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

isSafari

Determines if the current browser is Safari.

TypeScript
Copied!
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, and Android 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 and window 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

TypeScript
Copied!
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.

Codebase: Utilities -> Platforms -> isSafari | Yevhen Klymentiev