Skip to content

Commit cfdd6f6

Browse files
Merge pull request #71 from simpleanalytics/codex/implement-fix-for-sendbeacon-error
Handle sendBeacon edge cases
2 parents c256994 + f37e4ee commit cfdd6f6

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

dist/latest/latest.dev.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-05-30; 1686; v12) */
1+
/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-05-30; bf05; v12) */
22
/* eslint-env browser */
33

44
(function (
@@ -559,7 +559,13 @@
559559
// sendData will assign payload to request
560560
sendData(append, undefinedVar, trueVar);
561561
} else {
562-
nav.sendBeacon(fullApiUrl + "/append", stringify(append));
562+
try {
563+
nav.sendBeacon
564+
.bind(nav)(fullApiUrl + "/append", stringify(append));
565+
} catch (e) {
566+
// Fallback for browsers throwing "Illegal invocation" when the URL is invalid
567+
sendData(append, undefinedVar, trueVar);
568+
}
563569
}
564570
};
565571

package-lock.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/default.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,12 @@
638638
// sendData will assign payload to request
639639
sendData(append, undefinedVar, trueVar);
640640
} else {
641-
nav.sendBeacon(fullApiUrl + "/append", stringify(append));
641+
try {
642+
nav.sendBeacon.bind(nav)(fullApiUrl + "/append", stringify(append));
643+
} catch (e) {
644+
// Fallback for browsers throwing "Illegal invocation" when the URL is invalid
645+
sendData(append, undefinedVar, trueVar);
646+
}
642647
}
643648
};
644649

test/unit/pageview.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,34 @@ describe("pageview", function () {
3434
done();
3535
}, 10);
3636
});
37+
38+
it("falls back to pixel when sendBeacon fails", function (done) {
39+
const dom = createDOM({ navigationType: "reload" });
40+
41+
dom.window.navigator.sendBeacon = function () {
42+
throw new TypeError("Illegal invocation");
43+
};
44+
45+
dom.window.sa_event("unit_test");
46+
47+
if (!("onpagehide" in dom.window)) {
48+
dom.window.document.hidden = true;
49+
dom.window.document.dispatchEvent(
50+
new dom.window.Event("visibilitychange")
51+
);
52+
} else {
53+
dom.window.dispatchEvent(new dom.window.Event("pagehide"));
54+
}
55+
56+
setTimeout(() => {
57+
const beacon = dom.sent.find((r) => r.type === "beacon");
58+
const appendGif = dom.sent.find(
59+
(r) => r.type === "image" && /type=append/.test(r.url)
60+
);
61+
62+
expect(beacon, "append beacon request").to.not.exist;
63+
expect(appendGif, "append gif request").to.exist;
64+
done();
65+
}, 10);
66+
});
3767
});

0 commit comments

Comments
 (0)