Skip to content

Bind sendBeacon to navigator #26601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 12, 2021
17 changes: 15 additions & 2 deletions packages/next/client/performance-relayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,26 @@ function onReport(metric: Metric): void {
type: 'application/x-www-form-urlencoded',
})
const vitalsUrl = 'https://vitals.vercel-insights.com/v1/vitals'
;(navigator.sendBeacon && navigator.sendBeacon(vitalsUrl, blob)) ||
// Navigator has to be bound to ensure it does not error in some browsers
// https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
const send = navigator.sendBeacon && navigator.sendBeacon.bind(navigator)

function fallbackSend() {
fetch(vitalsUrl, {
body: blob,
method: 'POST',
credentials: 'omit',
keepalive: true,
})
// console.error is used here as when the fetch fails it does not affect functioning of the app
}).catch(console.error)
}

try {
// If send is undefined it'll throw as well. This reduces output code size.
send!(vitalsUrl, blob)
} catch (err) {
fallbackSend()
}
}
}

Expand Down