diff options
author | 2023-02-09 00:32:20 +0800 | |
---|---|---|
committer | 2023-02-08 13:32:20 -0300 | |
commit | 23c60cfa45d0c01c2a710de9c6a644cd91d1b3f3 (patch) | |
tree | f813e8cd50ee4959e37dd8734102c273a289c060 /packages/integrations/vercel/src/analytics.ts | |
parent | ec2f2a31dec78e5749cdea524ae926a19df300e3 (diff) | |
download | astro-23c60cfa45d0c01c2a710de9c6a644cd91d1b3f3.tar.gz astro-23c60cfa45d0c01c2a710de9c6a644cd91d1b3f3.tar.zst astro-23c60cfa45d0c01c2a710de9c6a644cd91d1b3f3.zip |
feat(vercel): Add support for analytics (Audiences & Web Vitals) (#6148)
* feat(intergration/vercel): add vercel analytics support
* docs(intergration/vercel): add vercel analytics prop
* docs(intergration/vercel): bump version to 3.1.0
* Update packages/integrations/vercel/README.md
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
* docs(intergration/vercel): add file name for example
* feat(intergration/vercel): convert analytics to ts and support in edge
* docs(intergration/vercel): move file names to code blocks as comments
* fix(intergration/vercel): remove unused import
* feat(intergration/vercel): add analytics support to static mode
* chore(intergration/vercel): revert version change
* style(intergration/vercel): add a blank line after astro import
* chore(intergration/vercel): generate file by changeset
* Update .changeset/eighty-bobcats-deliver.md
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
* Update packages/integrations/vercel/README.md
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
* Update packages/integrations/vercel/src/analytics.ts
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
* chore(intergration/vercel): simplify analytics script
---------
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Diffstat (limited to 'packages/integrations/vercel/src/analytics.ts')
-rw-r--r-- | packages/integrations/vercel/src/analytics.ts | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/packages/integrations/vercel/src/analytics.ts b/packages/integrations/vercel/src/analytics.ts new file mode 100644 index 000000000..95dee83e3 --- /dev/null +++ b/packages/integrations/vercel/src/analytics.ts @@ -0,0 +1,64 @@ +import { inject } from '@vercel/analytics'; +import type { Metric } from 'web-vitals'; +import { getCLS, getFCP, getFID, getLCP, getTTFB } from 'web-vitals'; + +const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals'; + +type Options = { path: string; analyticsId: string }; + +const getConnectionSpeed = () => { + return 'connection' in navigator && + navigator['connection'] && + 'effectiveType' in (navigator['connection'] as unknown as { effectiveType: string }) + ? (navigator['connection'] as unknown as { effectiveType: string })['effectiveType'] + : ''; +}; + +const sendToAnalytics = (metric: Metric, options: Options) => { + const body = { + dsn: options.analyticsId, + id: metric.id, + page: options.path, + href: location.href, + event_name: metric.name, + value: metric.value.toString(), + speed: getConnectionSpeed(), + }; + const blob = new Blob([new URLSearchParams(body).toString()], { + type: 'application/x-www-form-urlencoded', + }); + if (navigator.sendBeacon) { + navigator.sendBeacon(vitalsUrl, blob); + } else + fetch(vitalsUrl, { + body: blob, + method: 'POST', + credentials: 'omit', + keepalive: true, + }); +}; + +function webVitals() { + const analyticsId = (import.meta as any).env.PUBLIC_VERCEL_ANALYTICS_ID; + if (!analyticsId) { + console.error('[Analytics] VERCEL_ANALYTICS_ID not found'); + return; + } + const options: Options = { path: window.location.pathname, analyticsId }; + try { + getFID((metric) => sendToAnalytics(metric, options)); + getTTFB((metric) => sendToAnalytics(metric, options)); + getLCP((metric) => sendToAnalytics(metric, options)); + getCLS((metric) => sendToAnalytics(metric, options)); + getFCP((metric) => sendToAnalytics(metric, options)); + } catch (err) { + console.error('[Analytics]', err); + } +} + +const mode = (import.meta as any).env.MODE as 'development' | 'production'; + +inject({ mode }); +if (mode === 'production') { + webVitals(); +} |