Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1a68c56
Initial plan for issue
Copilot May 19, 2025
016492b
Add documentation for disablePageUnloadEvents to address jQuery 3.7.1…
Copilot May 19, 2025
8e317df
Add detailed documentation for disablePageUnloadEvents in docs folder
Copilot May 19, 2025
c4d3fe2
Update documentation URLs and add TypeScript examples for page events…
Copilot May 19, 2025
e358348
Update documentation for disablePageUnloadEvents and disablePageShowE…
Copilot May 19, 2025
8784a57
Add @example tag to TypeDoc for disablePageUnloadEvents and disablePa…
Copilot May 19, 2025
e344656
Add PageUnloadEvents.html link to docs/README.md FAQ section
Copilot May 19, 2025
499ca51
Update disablePageUnloadEvents and disablePageShowEvents links to use…
Copilot May 19, 2025
49cf4ee
Remove unnecessary lines and "Example usage:" heading
Copilot May 19, 2025
0e3b129
Update PageUnloadEvents link to use relative markdown path
Copilot May 19, 2025
5ec545b
Add details about handling missing events in PageUnloadEvents.md
Copilot May 19, 2025
7a1ac27
Update disablePageUnloadEvents and disablePageShowEvents with TypeDoc…
Copilot May 19, 2025
a9c0fef
Update disablePageUnloadEvents and disablePageShowEvents links to 1ds…
Copilot May 19, 2025
3f1ce44
Remove JavaScript examples from PageUnloadEvents.md
Copilot May 19, 2025
27c9800
Clarify Page Unload and Visibility Event Handling section in README.md
Copilot May 20, 2025
b90a7dd
Update README.md to clarify page unload event handling description
Copilot May 20, 2025
ac6106d
Merge branch 'main' into copilot/fix-2508
MSNev May 20, 2025
2812a59
Fix failing tests by correcting AITestClass import in Es5Rollup.Tests.ts
Copilot May 22, 2025
54b5570
Revert to using "@microsoft/ai-test-framework" as requested
Copilot May 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,39 @@ Most configuration fields are named such that they can be defaulted to falsey. A
| featureOptIn (#feature)<br/><sub>since 3.0.3</sub> | IFeatureOptIn | undefined | [Optional] Set Feature opt in details. |
| throttleMgrCfg <br/><sub>since 3.0.3</sub> | `{[key: number]: IThrottleMgrConfig}` | undefined | [Optional] Set throttle mgr configuration by key. |
| retryCodes | number[] | undefined | Identifies the status codes that will cause event batches to be resent, when `null` or `undefined` the SDK will use it's defaults `[401, 408, 429, 500, 502, 503, 504]`. `403` was removed in version 3.1.1. |
| [disablePageUnloadEvents](https://microsoft.github.io/ApplicationInsights-JS/webSdk/applicationinsights-core-js/interfaces/IConfiguration.html#disablePageUnloadEvents) | string[] | undefined | [Optional] An array of the page unload events that you would like to be ignored. [See detailed documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html). Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide". This can be used to avoid jQuery 3.7.1+ deprecation warnings by configuring as `disablePageUnloadEvents: ["unload"]`. |
| [disablePageShowEvents](https://microsoft.github.io/ApplicationInsights-JS/webSdk/applicationinsights-core-js/interfaces/IConfiguration.html#disablePageShowEvents) | string[] | undefined | [Optional] An array of page show events that you would like to be ignored. [See detailed documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html). Page Show events include "pageshow" and "visibilitychange" (with 'visible' state). |
| expCfg <br/><sub>since 3.3.1</sub>| [`IExceptionConfig`](https://github.com/microsoft/ApplicationInsights-JS/blob/main/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts) | undefined | Set additional configuration for exceptions, such as more scripts to include in the exception telemetry. |

### Page Unload and Visibility Event Handling
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new section is really confusing, visibility state is mentioned here, what does it mean? like what it was being displayed in the page?, for which telemetry types that is relevant?, what is this config actually doing? is it only for removing warnings or is it actually changing the way the telemetry is captured?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the actual new doc this make sense, but before that this text should be clear enough, this is in main readme so it should be as simple as possible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the section to clarify what "visibility state" means, explain which telemetry types are affected (all types), and describe what these configuration options actually do beyond just removing warnings. The explanation now includes details about how these events are used by the SDK for flushing telemetry and preventing data loss during page navigation or tab/browser closure. These changes are in commit 27c9800.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the README.md section with clearer language that explains what these configurations do and why they matter. The updated section now explicitly describes what "visibility state" means, explains which telemetry types are affected, and clarifies that these options control when telemetry data is flushed during page navigation. These changes are in commit 27c9800.


Application Insights SDK uses page lifecycle events to reliably send telemetry data before your page closes or navigates away. These events are essential for ensuring no telemetry data is lost during navigation, page refreshes, or tab/browser closures.

**What these configurations do:**
- Control which browser events the SDK uses to detect when the browser is about to unload, navigate away, become unresponsive, or get hibernated (especially on mobile)
- Ensure all batched events are sent and not lost due to the browser closing or the user navigating away
- Affect ALL telemetry types (page views, events, dependencies, exceptions, etc.)
- Allow you to avoid deprecated event warnings (from jQuery 3.7.1+ or Chrome) while maintaining functionality

**About visibility state:**
When a browser tab becomes hidden (switching to another tab) or visible (returning to the tab), the browser fires "visibilitychange" events with document.visibilityState changing to "hidden" or "visible". The SDK uses these events to optimize telemetry sending.

```js
const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
// Disable the deprecated 'unload' event to avoid jQuery 3.7.1+ deprecation warnings
// This also prevents Chrome's warnings about the unload event
disablePageUnloadEvents: ["unload"],
/* ...Other Configuration Options... */
}
});
appInsights.loadAppInsights();
appInsights.trackPageView();
```

For more detailed information about browser compatibility and configuration options, see the [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html).

### Feature

You can use the `featureOptIn` configuration to enable or customize specific SDK features.
Expand Down
141 changes: 141 additions & 0 deletions docs/PageUnloadEvents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Page Unload Event Handling

## Overview

Application Insights Web SDK tracks several page lifecycle events to ensure that telemetry data is sent before a page is unloaded, helping to prevent data loss during page navigation or browser closure. The SDK hooks into different unload and visibility change events depending on the browser environment.

## Unload Events

The SDK listens to the following events to detect when a page is being unloaded:

1. **beforeunload** - Fired when the window, document, and its resources are about to be unloaded
2. **unload** - Fired when the document or a child resource is being unloaded
3. **pagehide** - Fired when the browser hides the current page in the process of navigating to another page
4. **visibilitychange** (with 'hidden' state) - Fired when the content of a tab has become visible or hidden

## Modern Browser Compatibility

Modern browsers and frameworks are deprecating or changing how some page unload events work:

- **jQuery 3.7.1+** has deprecated the use of the `unload` event, showing warning messages when it's used.
- Some modern browsers are changing the behavior of `beforeunload` event for better performance and reduced tracking potential.
- The `pagehide` event and `visibilitychange` events are becoming the recommended alternatives.
- The SDK is designed to handle cases where certain events are unavailable or behave differently across browsers, gracefully adapting to the environment to ensure telemetry is sent.

## Configuration Options

The SDK provides configuration options to control which page lifecycle events are used:

### disablePageUnloadEvents

This configuration option allows you to specify which page unload events should not be used by the SDK.

**TypeScript Example:**
```typescript
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
disablePageUnloadEvents: ["unload"],
/* ...Other Configuration Options... */
}
});
```

**Important notes**:

- The SDK requires at least one functioning page unload event to ensure telemetry is sent when the page is closed.
- If all events are listed in `disablePageUnloadEvents` or if the only working events in the current browser environment are the ones you've disabled, the SDK will still use one of them to ensure functionality.
- This option is especially useful for avoiding jQuery 3.7.1+ deprecation warnings by excluding the "unload" event.

### disablePageShowEvents

Similarly, this configuration option controls which page show events are not used by the SDK. Page show events include:

1. **pageshow** - Fired when a page is shown, or when navigating to a page using browser's back/forward functionality
2. **visibilitychange** (with 'visible' state) - Fired when a tab becomes visible

**TypeScript Example:**
```typescript
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
disablePageShowEvents: ["pageshow"],
/* ...Other Configuration Options... */
}
});
```

## Fallback Mechanism

The SDK implements a robust fallback mechanism to ensure that telemetry can be sent before the page unloads:

1. The SDK first tries to use all available unload events except those listed in `disablePageUnloadEvents`.
2. If no events can be registered (either because all are disabled or not supported), the SDK will ignore the `disablePageUnloadEvents` setting and force registration of at least one event.
3. Even when the SDK attempts to hook events that may be missing in certain browsers, it's designed to gracefully handle these cases without errors.
4. The SDK includes internal logic to detect when hooked events aren't firing as expected and will utilize alternative approaches to send telemetry.
5. This ensures that critical telemetry data is always sent, even in constrained environments or when browser implementations change.

## Use Cases

### Avoiding jQuery 3.7.1+ Deprecation Warnings

If you're using jQuery 3.7.1 or newer, you'll encounter deprecation warnings when the 'unload' event is used. Configure the SDK to not use this deprecated event:

**TypeScript Example:**
```typescript
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
// Disable the deprecated 'unload' event to avoid jQuery deprecation warnings
disablePageUnloadEvents: ["unload"],
}
});
```

### Optimizing for Modern Browsers

For the best experience in modern browsers, you might want to prioritize newer events:

**TypeScript Example:**
```typescript
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
// Use only modern events
disablePageUnloadEvents: ["unload", "beforeunload"],
}
});
```

Note that the SDK will still use an older event if none of the modern events are supported in the browser environment.

### Using Both Configuration Options Together

You can configure both unload and show events simultaneously for fine-grained control:

**TypeScript Example:**
```typescript
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
// Disable specific unload events
disablePageUnloadEvents: ["unload"],
// Disable specific show events
disablePageShowEvents: ["pageshow"],
}
});
```

### Progressive Enhancement

The SDK's approach to page lifecycle events reflects a progressive enhancement strategy, ensuring that telemetry works across diverse browser environments while offering configuration options for optimal behavior in modern contexts.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ ES3 support has been removed from the latest version (v3.x), if required [see fo

- [Create an Issue](https://github.com/microsoft/ApplicationInsights-JS/issues/new/choose)
- [ES3 Support](./es3_Support.md)
- [Page Unload Event Handling](./PageUnloadEvents.md)
- [V2 Upgrade Guide](./upgrade/v2_UpgradeGuide.md)
- [V3 Breaking Changes](./upgrade/v3_BreakingChanges.md)

Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,11 @@
"@microsoft/rush": "5.153.1",
"@nevware21/grunt-eslint-ts": "^0.2.2",
"@nevware21/grunt-ts-plugin": "^0.4.3",
"@typescript-eslint/eslint-plugin": "^5.46.1",
"@typescript-eslint/parser": "^5.46.1",
"@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"rollup": "^3.20.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"@typescript-eslint/eslint-plugin": "^5.46.1",
"@typescript-eslint/parser": "^5.46.1",
"archiver": "^5.3.0",
"connect": "^3.7.0",
"eslint": "^7.29.0",
Expand All @@ -66,16 +63,19 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-security": "^1.4.0",
"eventemitter2": "6.4.9",
"grunt": "^1.5.3",
"grunt-cli": "^1.4.3",
"grunt-contrib-connect": "^3.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-uglify": "^5.2.1",
"eventemitter2": "6.4.9",
"puppeteer": "24.8.2",
"puppeteer": "^24.8.2",
"request": "^2.88.2",
"rollup": "^3.20.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"typedoc": "^0.26.6",
"typescript": "^4.9.3",
"whatwg-fetch": "^3.6.2",
"request": "^2.88.2"
"whatwg-fetch": "^3.6.2"
}
}
4 changes: 2 additions & 2 deletions shared/1ds-core-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ appInsightsCore.initialize(coreConfig, []);
| idLength | [Optional] Identifies the default length used to generate new random session and user id's. Defaults to 22, previous default value was 5 (v2.4.2 or less), if you need to keep the previous maximum length you should set this value to 5. | number<br />Default: 22
| disableEventTimings | [Optional] Disables additional internal event timings that are added during processing of events, the timings are not sent as part telemetry items to the server. | boolean<br/>Default: false
| enableCompoundKey | [Optional] Enables support for objects with compound keys which indirectly represent an object where the "key" of the object contains a "." as part of it's name.<br />Example: <code>event: { "somedata.embeddedvalue": 123 } </code> | boolean<br />Default: false
| disablePageUnloadEvents | [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.<br /> Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide"| string[]<br />Default: not specified
| disablePageShowEvents | [Optional] An array of page show events that you would like to be ignored, special note there must be at lease one valid show event hooked, if you list all or the runtime environment only supports a listed (disabled) event it will STILL be hooked, if required by the SDK.<br/> Page Show events include "pageshow" and "visibilitychange" (with 'visible' state)| string[]<br /> Default: not specified
| [disablePageUnloadEvents](https://microsoft.github.io/ApplicationInsights-JS/webSdk/1ds-core-js/interfaces/IConfiguration.html#disablePageUnloadEvents) | [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.<br /> Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide". See [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html) for details.| string[]<br />Default: not specified
| [disablePageShowEvents](https://microsoft.github.io/ApplicationInsights-JS/webSdk/1ds-core-js/interfaces/IConfiguration.html#disablePageShowEvents) | [Optional] An array of page show events that you would like to be ignored, special note there must be at lease one valid show event hooked, if you list all or the runtime environment only supports a listed (disabled) event it will STILL be hooked, if required by the SDK.<br/> Page Show events include "pageshow" and "visibilitychange" (with 'visible' state). See [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html) for details.| string[]<br /> Default: not specified

### [IPropertyStorageOverride](https://microsoft.github.io/ApplicationInsights-JS/webSdk/1ds-core-js/interfaces/IPropertyStorageOverride.html)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,33 @@ export interface IConfiguration {
/**
* [Optional] An array of the page unload events that you would like to be ignored, special note there must be at least one valid unload
* event hooked, if you list all or the runtime environment only supports a listed "disabled" event it will still be hooked, if required by the SDK.
* Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide"
* Unload events include "beforeunload", "unload", "visibilitychange" (with 'hidden' state) and "pagehide".
*
* This can be used to avoid jQuery 3.7.1+ deprecation warnings and Chrome warnings about the unload event:
* @example
* ```javascript
* {
* disablePageUnloadEvents: ["unload"]
* }
* ```
*
* For more details, see the [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html).
*/
disablePageUnloadEvents?: string[];

/**
* [Optional] An array of page show events that you would like to be ignored, special note there must be at lease one valid show event
* hooked, if you list all or the runtime environment only supports a listed (disabled) event it will STILL be hooked, if required by the SDK.
* Page Show events include "pageshow" and "visibilitychange" (with 'visible' state)
* Page Show events include "pageshow" and "visibilitychange" (with 'visible' state).
*
* @example
* ```javascript
* {
* disablePageShowEvents: ["pageshow"]
* }
* ```
*
* For more details, see the [Page Unload Events documentation](https://microsoft.github.io/ApplicationInsights-JS/docs/PageUnloadEvents.html).
*/
disablePageShowEvents?: string[];

Expand Down