or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-utilities.mddata-processing.mdenvelopes.mdenvironment.mderror-handling.mdindex.mdinstrumentation.mdlogging.mdstack-processing.mdtype-guards.md

environment.mddocs/

0

# Environment & Browser Detection

1

2

**DEPRECATED**: Import all functions from `@sentry/core` instead of `@sentry/utils`.

3

4

Environment detection utilities for determining runtime capabilities and platform-specific features across browsers and Node.js environments.

5

6

## Capabilities

7

8

### Runtime Environment Detection

9

10

Core functions for detecting the current JavaScript runtime environment.

11

12

```typescript { .api }

13

/**

14

* Detects if code is running in a browser environment

15

* @returns True if running in browser

16

*/

17

function isBrowser(): boolean;

18

19

/**

20

* Detects if code is running in Node.js environment

21

* @returns True if running in Node.js

22

*/

23

function isNodeEnv(): boolean;

24

25

/**

26

* Detects if code is running as a browser bundle (vs. server-side rendering)

27

* @returns True if running as browser bundle

28

*/

29

function isBrowserBundle(): boolean;

30

```

31

32

**Usage Examples:**

33

34

```typescript

35

import { isBrowser, isNodeEnv, isBrowserBundle } from "@sentry/core";

36

37

// Platform-specific initialization

38

if (isBrowser()) {

39

// Browser-only code

40

setupBrowserInstrumentation();

41

registerServiceWorker();

42

} else if (isNodeEnv()) {

43

// Node.js-only code

44

setupNodeInstrumentation();

45

loadServerConfig();

46

}

47

48

// Bundle detection for SSR

49

function initializeApp() {

50

if (isBrowserBundle()) {

51

// Client-side hydration

52

ReactDOM.hydrate(<App />, document.getElementById('root'));

53

} else {

54

// Server-side rendering

55

return ReactDOMServer.renderToString(<App />);

56

}

57

}

58

```

59

60

### Browser API Support Detection

61

62

Functions for detecting support for specific browser APIs and features.

63

64

```typescript { .api }

65

/**

66

* Checks if the Fetch API is available

67

* @returns True if fetch is supported

68

*/

69

function supportsFetch(): boolean;

70

71

/**

72

* Checks if native fetch is available (not polyfilled)

73

* @returns True if native fetch is supported

74

*/

75

function supportsNativeFetch(): boolean;

76

77

/**

78

* Checks if History API is available (pushState, replaceState)

79

* @returns True if History API is supported

80

*/

81

function supportsHistory(): boolean;

82

83

/**

84

* Checks if Referrer Policy is supported

85

* @returns True if referrer policy is supported

86

*/

87

function supportsReferrerPolicy(): boolean;

88

89

/**

90

* Checks if ReportingObserver API is available

91

* @returns True if ReportingObserver is supported

92

*/

93

function supportsReportingObserver(): boolean;

94

```

95

96

**Usage Examples:**

97

98

```typescript

99

import {

100

supportsFetch,

101

supportsNativeFetch,

102

supportsHistory

103

} from "@sentry/core";

104

105

// Conditional network request setup

106

function setupNetworkMonitoring() {

107

if (supportsFetch()) {

108

// Use fetch for network requests

109

addFetchInstrumentation();

110

} else {

111

// Fallback to XMLHttpRequest

112

addXHRInstrumentation();

113

}

114

115

// Prefer native fetch for better performance

116

if (supportsNativeFetch()) {

117

console.log('Using native fetch API');

118

} else {

119

console.log('Using fetch polyfill');

120

}

121

}

122

123

// History API for single-page apps

124

function setupRouting() {

125

if (supportsHistory()) {

126

// Use pushState/replaceState for routing

127

window.addEventListener('popstate', handleRouteChange);

128

} else {

129

// Fallback to hash-based routing

130

window.addEventListener('hashchange', handleHashChange);

131

}

132

}

133

```

134

135

### Error API Support Detection

136

137

Functions for detecting support for various error-related browser APIs.

138

139

```typescript { .api }

140

/**

141

* Checks if DOMError constructor is available

142

* @returns True if DOMError is supported

143

*/

144

function supportsDOMError(): boolean;

145

146

/**

147

* Checks if DOMException constructor is available

148

* @returns True if DOMException is supported

149

*/

150

function supportsDOMException(): boolean;

151

152

/**

153

* Checks if ErrorEvent constructor is available

154

* @returns True if ErrorEvent is supported

155

*/

156

function supportsErrorEvent(): boolean;

157

```

158

159

**Usage Example:**

160

161

```typescript

162

import {

163

supportsDOMError,

164

supportsDOMException,

165

supportsErrorEvent

166

} from "@sentry/core";

167

168

function setupErrorHandling() {

169

// Enhanced error categorization based on support

170

window.addEventListener('error', (event) => {

171

let errorType = 'generic';

172

173

if (supportsErrorEvent() && event instanceof ErrorEvent) {

174

errorType = 'ErrorEvent';

175

} else if (supportsDOMError() && event.error instanceof DOMError) {

176

errorType = 'DOMError';

177

} else if (supportsDOMException() && event.error instanceof DOMException) {

178

errorType = 'DOMException';

179

}

180

181

console.log(`Captured ${errorType}:`, event.error);

182

});

183

}

184

```

185

186

### Function Detection

187

188

Utilities for detecting native vs. wrapped functions.

189

190

```typescript { .api }

191

/**

192

* Checks if a function is a native browser/Node.js function (not wrapped or polyfilled)

193

* @param func - Function to check

194

* @returns True if function appears to be native

195

*/

196

function isNativeFunction(func: Function): boolean;

197

```

198

199

**Usage Example:**

200

201

```typescript

202

import { isNativeFunction } from "@sentry/core";

203

204

function analyzeFunction(fn: Function) {

205

if (isNativeFunction(fn)) {

206

console.log('Native function detected');

207

// Safe to instrument directly

208

return instrumentNative(fn);

209

} else {

210

console.log('Wrapped or polyfilled function detected');

211

// Use more careful instrumentation

212

return instrumentSafely(fn);

213

}

214

}

215

216

// Check if fetch is native or polyfilled

217

if (typeof fetch === 'function') {

218

const isNative = isNativeFunction(fetch);

219

console.log(`Fetch is ${isNative ? 'native' : 'polyfilled'}`);

220

}

221

```

222

223

## Environment Detection Patterns

224

225

### Feature Detection Strategy

226

227

Use feature detection instead of user agent parsing for reliable cross-browser support:

228

229

```typescript

230

import {

231

isBrowser,

232

supportsFetch,

233

supportsHistory,

234

supportsReportingObserver

235

} from "@sentry/core";

236

237

interface BrowserCapabilities {

238

hasNetworkAPI: boolean;

239

hasRouting: boolean;

240

hasReporting: boolean;

241

platform: 'browser' | 'node' | 'unknown';

242

}

243

244

function detectCapabilities(): BrowserCapabilities {

245

return {

246

hasNetworkAPI: isBrowser() && supportsFetch(),

247

hasRouting: isBrowser() && supportsHistory(),

248

hasReporting: isBrowser() && supportsReportingObserver(),

249

platform: isBrowser() ? 'browser' : (isNodeEnv() ? 'node' : 'unknown'),

250

};

251

}

252

```

253

254

### Progressive Enhancement

255

256

Use environment detection for progressive enhancement:

257

258

```typescript

259

import {

260

isBrowser,

261

supportsFetch,

262

supportsReportingObserver

263

} from "@sentry/core";

264

265

class MonitoringClient {

266

private capabilities = detectCapabilities();

267

268

init() {

269

// Base functionality always available

270

this.setupBasicErrorHandling();

271

272

// Progressive enhancement based on environment

273

if (this.capabilities.hasNetworkAPI) {

274

this.setupNetworkMonitoring();

275

}

276

277

if (this.capabilities.hasReporting) {

278

this.setupReportingObserver();

279

}

280

}

281

282

private setupNetworkMonitoring() {

283

if (supportsFetch()) {

284

// Enhanced network monitoring with fetch

285

addFetchInstrumentationHandler(this.handleNetworkEvent);

286

}

287

}

288

289

private setupReportingObserver() {

290

if (supportsReportingObserver()) {

291

// Modern reporting API for deprecations, violations, etc.

292

const observer = new ReportingObserver(this.handleReport);

293

observer.observe();

294

}

295

}

296

}

297

```

298

299

### Conditional Module Loading

300

301

Environment detection for conditional module loading:

302

303

```typescript

304

import { isNodeEnv, isBrowser } from "@sentry/core";

305

306

async function loadPlatformSpecificModules() {

307

if (isNodeEnv()) {

308

// Node.js-specific modules

309

const fs = await import('fs');

310

const path = await import('path');

311

return { fs, path };

312

} else if (isBrowser()) {

313

// Browser-specific modules

314

const { setupServiceWorker } = await import('./serviceWorker');

315

const { initializeAnalytics } = await import('./analytics');

316

return { setupServiceWorker, initializeAnalytics };

317

}

318

319

return {};

320

}

321

```

322

323

## Environment Constants

324

325

```typescript { .api }

326

// Global object reference (window in browser, global in Node.js)

327

declare const GLOBAL_OBJ: typeof globalThis;

328

329

/**

330

* Gets a global singleton instance

331

* @param name - Name of the singleton

332

* @param creator - Function to create the singleton if it doesn't exist

333

* @param obj - Global object to store the singleton (defaults to GLOBAL_OBJ)

334

* @returns The singleton instance

335

*/

336

function getGlobalSingleton<T>(

337

name: string,

338

creator: () => T,

339

obj?: any

340

): T;

341

```

342

343

**Usage Example:**

344

345

```typescript

346

import { getGlobalSingleton, GLOBAL_OBJ } from "@sentry/core";

347

348

// Create a global logger singleton

349

const logger = getGlobalSingleton('__SENTRY_LOGGER__', () => {

350

return new Logger({ level: 'info' });

351

});

352

353

// Access global object consistently

354

console.log('Global object:', GLOBAL_OBJ === window); // true in browser

355

console.log('Global object:', GLOBAL_OBJ === global); // true in Node.js

356

```

357

358

**Migration Note**: All environment detection functions have been moved from `@sentry/utils` to `@sentry/core`. Update your imports accordingly.