diff --git a/website/index.js b/website/index.js index 09fec8e..ac54c28 100644 --- a/website/index.js +++ b/website/index.js @@ -5,6 +5,8 @@ import noUiSlider from 'nouislider'; import {version} from '../package'; import dogeSeed from '..'; +import reportWebVitals from './vercel-vitals'; + Array.from(document.querySelectorAll('[data-latex]')).forEach(element => { console.log(element.dataset.latex) element.innerHTML = teXToSVG(element.dataset.latex) @@ -50,3 +52,5 @@ regenerateSeedButton.addEventListener('click', generateSeed); bitSlider.on('update', generateSeed); generateSeed(); + +reportWebVitals(); \ No newline at end of file diff --git a/website/package-lock.json b/website/package-lock.json index 95980ea..5c8bfcb 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -12,7 +12,8 @@ "@fontsource/comic-neue": "^4.5.10", "modern-normalize": "^0.5.0", "nouislider": "^12.1.0", - "tex-to-svg": "^0.2.0" + "tex-to-svg": "^0.2.0", + "web-vitals": "^3.1.1" }, "devDependencies": { "buffer": "^5.7.1", @@ -2930,6 +2931,11 @@ "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", "dev": true }, + "node_modules/web-vitals": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.1.1.tgz", + "integrity": "sha512-qvllU+ZeQChqzBhZ1oyXmWsjJ8a2jHYpH8AMaVuf29yscOPZfTQTjQFRX6+eADTdsDE8IanOZ0cetweHMs8/2A==" + }, "node_modules/wicked-good-xpath": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", @@ -4864,6 +4870,11 @@ "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", "dev": true }, + "web-vitals": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.1.1.tgz", + "integrity": "sha512-qvllU+ZeQChqzBhZ1oyXmWsjJ8a2jHYpH8AMaVuf29yscOPZfTQTjQFRX6+eADTdsDE8IanOZ0cetweHMs8/2A==" + }, "wicked-good-xpath": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", diff --git a/website/package.json b/website/package.json index 0ec3cb6..42656d0 100644 --- a/website/package.json +++ b/website/package.json @@ -14,7 +14,8 @@ "@fontsource/comic-neue": "^4.5.10", "modern-normalize": "^0.5.0", "nouislider": "^12.1.0", - "tex-to-svg": "^0.2.0" + "tex-to-svg": "^0.2.0", + "web-vitals": "^3.1.1" }, "devDependencies": { "buffer": "^5.7.1", diff --git a/website/vercel-vitals.js b/website/vercel-vitals.js new file mode 100644 index 0000000..44a6c79 --- /dev/null +++ b/website/vercel-vitals.js @@ -0,0 +1,57 @@ +/* eslint-env browser */ +import { getCLS, getFCP, getFID, getLCP, getTTFB } from 'web-vitals'; + +const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals'; + +function getConnectionSpeed() { + return 'connection' in navigator && + navigator['connection'] && + 'effectiveType' in navigator['connection'] + ? navigator['connection']['effectiveType'] + : ''; +} + +export function sendToVercelAnalytics(metric) { + const analyticsId = process.env.REACT_APP_VERCEL_ANALYTICS_ID; + if (!analyticsId) { + return; + } + + const body = { + dsn: analyticsId, + id: metric.id, + page: window.location.pathname, + href: window.location.href, + event_name: metric.name, + value: metric.value.toString(), + speed: getConnectionSpeed(), + }; + + const blob = new Blob([new URLSearchParams(body).toString()], { + // This content type is necessary for `sendBeacon` + type: 'application/x-www-form-urlencoded', + }); + if (navigator.sendBeacon) { + navigator.sendBeacon(vitalsUrl, blob); + } else + fetch(vitalsUrl, { + body: blob, + method: 'POST', + credentials: 'omit', + keepalive: true, + }); +} + +const reportWebVitals = () => { + try { + getFID(sendToVercelAnalytics); + getTTFB(sendToVercelAnalytics); + getLCP(sendToVercelAnalytics); + getCLS(sendToVercelAnalytics); + getFCP(sendToVercelAnalytics); + } catch (err) { + console.error('[Analytics]', err); + } + }; + + export default reportWebVitals; \ No newline at end of file