From 97511dd71450d1d44884e7b91dbf91eb541573f3 Mon Sep 17 00:00:00 2001 From: Chris <7249920+chriswdmr@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:12:00 +0200 Subject: [PATCH] Move `beforeSend` out of config --- packages/integrations/vercel/README.md | 36 +++++++++----- .../integrations/vercel/src/edge/adapter.ts | 13 +++-- .../vercel/src/lib/web-analytics.ts | 47 +++++++++++++++++-- .../vercel/src/serverless/adapter.ts | 13 +++-- .../integrations/vercel/src/static/adapter.ts | 13 +++-- packages/integrations/vercel/src/types.d.ts | 3 ++ ...analtics.test.js => web-analytics.test.js} | 0 7 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 packages/integrations/vercel/src/types.d.ts rename packages/integrations/vercel/test/{web-analtics.test.js => web-analytics.test.js} (100%) diff --git a/packages/integrations/vercel/README.md b/packages/integrations/vercel/README.md index 3f712a424..ce1ffb910 100644 --- a/packages/integrations/vercel/README.md +++ b/packages/integrations/vercel/README.md @@ -92,7 +92,7 @@ To configure this adapter, pass an object to the `vercel()` function call in `as **Added in:** `@astrojs/vercel@3.8.0` You can enable [Vercel Web Analytics](https://vercel.com/docs/concepts/analytics) by setting `webAnalytics: { enabled: true }`. This will inject Vercel’s tracking scripts into all of your pages. -Alternatively, you can pass all [available configuration options](https://vercel.com/docs/concepts/analytics/package) via the `config` property inside `webAnalytics`. +Alternatively, you can also pass [configuration options](https://vercel.com/docs/concepts/analytics/package) (except functions like `beforeSend`) via the `config` property inside `webAnalytics`. ```js // astro.config.mjs @@ -104,20 +104,32 @@ export default defineConfig({ adapter: vercel({ webAnalytics: { enabled: true, - config: { - beforeSend: (event) => { - // Ignore all events that have a `/private` inside the URL - if (event.url.includes('/private')) { - return null; - } - return event; - } - } - } + }, }), }); ``` +#### `beforeSend` + +Since functions can't be passed down via `astro.config.mjs`, you need to export the `beforeSend` function in a separate file inside your root called `vercel-web-analytics.ts`. +If you're not using TypeScript, you can define the function inside `vercel-web-analytics.js`. + +```js +// vercel-web-analytics.ts +import type { VercelWebAnalyticsBeforeSend } from '@astrojs/vercel'; + +export const beforeSend: VercelWebAnalyticsBeforeSend = (event) => { + // Ignore all events that have a `/private` inside the URL + if (event.url.includes('/private')) { + return null; + } + return event; + } +} +``` + +````js + ### Speed Insights You can enable [Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) by setting `speedInsights: { enabled: true }`. This will collect and send Web Vital data to Vercel. @@ -138,7 +150,7 @@ export default defineConfig({ } }), }); -``` +```` ### imagesConfig diff --git a/packages/integrations/vercel/src/edge/adapter.ts b/packages/integrations/vercel/src/edge/adapter.ts index bad7da2d2..e919bad1a 100644 --- a/packages/integrations/vercel/src/edge/adapter.ts +++ b/packages/integrations/vercel/src/edge/adapter.ts @@ -55,14 +55,17 @@ export default function vercelEdge({ return { name: PACKAGE_NAME, hooks: { - 'astro:config:setup': ({ command, config, updateConfig, injectScript }) => { + 'astro:config:setup': async ({ command, config, updateConfig, injectScript }) => { if (webAnalytics?.enabled) { injectScript( 'page', - getInjectableWebAnalyticsContent({ - ...webAnalytics.config, - mode: command === 'dev' ? 'development' : 'production', - }) + await getInjectableWebAnalyticsContent( + { + ...webAnalytics.config, + mode: command === 'dev' ? 'development' : 'production', + }, + config.root + ) ); } if (command === 'build' && speedInsights?.enabled) { diff --git a/packages/integrations/vercel/src/lib/web-analytics.ts b/packages/integrations/vercel/src/lib/web-analytics.ts index 0679aa771..31cc22fbd 100644 --- a/packages/integrations/vercel/src/lib/web-analytics.ts +++ b/packages/integrations/vercel/src/lib/web-analytics.ts @@ -1,15 +1,56 @@ import type { AnalyticsProps } from '@vercel/analytics'; +import { fileURLToPath } from 'url'; export type VercelWebAnalyticsConfig = { enabled: boolean; - config?: AnalyticsProps; + config?: Omit; }; -export function getInjectableWebAnalyticsContent(config?: AnalyticsProps) { +async function getWebAnalyticsFunctions(root: URL) { + try { + const files = await Promise.all([ + import(/* @vite-ignore */ fileURLToPath(new URL('./vercel-web-analytics.ts', root))).catch( + () => undefined + ), + import(/* @vite-ignore */ fileURLToPath(new URL('./vercel-web-analytics.js', root))).catch( + () => undefined + ), + ]); + + const functions = files[0] || files[1]; + + if (functions?.default) { + if (typeof functions.default.beforeSend !== 'function') { + throw new Error( + `@astrojs/vercel: ./vercel-web-analytics.js should export a \`beforeSend\` function.` + ); + } + + return { + beforeSend: functions.default.beforeSend, + }; + } + + return { + beforeSend: undefined, + }; + } catch (e) { + return { + beforeSend: undefined, + }; + } +} + +export async function getInjectableWebAnalyticsContent( + config: Omit | undefined, + root: URL +) { + const { beforeSend } = await getWebAnalyticsFunctions(root); + return `import { inject } from '@vercel/analytics'; inject({ mode: ${config?.mode}, - beforeSend: ${config?.beforeSend}, + beforeSend: ${beforeSend}, debug: ${config?.debug} });`; } diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index b63071c19..2659e7703 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -116,14 +116,17 @@ export default function vercelServerless({ return { name: PACKAGE_NAME, hooks: { - 'astro:config:setup': ({ command, config, updateConfig, injectScript }) => { + 'astro:config:setup': async ({ command, config, updateConfig, injectScript }) => { if (webAnalytics?.enabled) { injectScript( 'page', - getInjectableWebAnalyticsContent({ - ...webAnalytics.config, - mode: command === 'dev' ? 'development' : 'production', - }) + await getInjectableWebAnalyticsContent( + { + ...webAnalytics.config, + mode: command === 'dev' ? 'development' : 'production', + }, + config.root + ) ); } if (command === 'build' && speedInsights?.enabled) { diff --git a/packages/integrations/vercel/src/static/adapter.ts b/packages/integrations/vercel/src/static/adapter.ts index 50e7cbae2..d723063d5 100644 --- a/packages/integrations/vercel/src/static/adapter.ts +++ b/packages/integrations/vercel/src/static/adapter.ts @@ -37,14 +37,17 @@ export default function vercelStatic({ return { name: '@astrojs/vercel', hooks: { - 'astro:config:setup': ({ command, config, injectScript, updateConfig }) => { + 'astro:config:setup': async ({ command, config, injectScript, updateConfig }) => { if (webAnalytics?.enabled) { injectScript( 'page', - getInjectableWebAnalyticsContent({ - ...webAnalytics.config, - mode: command === 'dev' ? 'development' : 'production', - }) + await getInjectableWebAnalyticsContent( + { + ...webAnalytics.config, + mode: command === 'dev' ? 'development' : 'production', + }, + config.root + ) ); } if (command === 'build' && speedInsights?.enabled) { diff --git a/packages/integrations/vercel/src/types.d.ts b/packages/integrations/vercel/src/types.d.ts new file mode 100644 index 000000000..1c5b8d2db --- /dev/null +++ b/packages/integrations/vercel/src/types.d.ts @@ -0,0 +1,3 @@ +import type { AnalyticsProps } from '@vercel/analytics'; + +export type VercelWebAnalyticsBeforeSend = AnalyticsProps['beforeSend']; diff --git a/packages/integrations/vercel/test/web-analtics.test.js b/packages/integrations/vercel/test/web-analytics.test.js similarity index 100% rename from packages/integrations/vercel/test/web-analtics.test.js rename to packages/integrations/vercel/test/web-analytics.test.js