diff --git a/.changeset/sixty-teachers-tap.md b/.changeset/sixty-teachers-tap.md new file mode 100644 index 000000000000..122557751ff0 --- /dev/null +++ b/.changeset/sixty-teachers-tap.md @@ -0,0 +1,26 @@ +--- +'@astrojs/vercel': minor +--- + +Enable Vercel Speed Insights and Vercel Web Analytics individually. +Deprecates the `analytics` property in `astro.config.mjs` in favor of `speedInsights` and `webAnalytics`. + +If you're using the `analytics` property, you'll need to update your config to use the new properties: + +```diff +// astro.config.mjs +export default defineConfig({ + adapter: vercel({ +- analytics: true, ++ webAnalytics: { ++ enabled: true ++ }, ++ speedInsights: { ++ enabled: true ++ } + }) +}); +``` + +Allow configuration of Web Analytics with all available configuration options. +Bumps @vercel/analytics package to the latest version. diff --git a/packages/integrations/vercel/README.md b/packages/integrations/vercel/README.md index 00c2a18cfe0b..f2be2cd48f89 100644 --- a/packages/integrations/vercel/README.md +++ b/packages/integrations/vercel/README.md @@ -85,13 +85,36 @@ vercel deploy --prebuilt To configure this adapter, pass an object to the `vercel()` function call in `astro.config.mjs`: -### analytics +### Web Analytics -**Type:** `boolean`
-**Available for:** Serverless, Static
-**Added in:** `@astrojs/vercel@3.1.0` +**Type:** `VercelWebAnalyticsConfig`
+**Available for:** Serverless, Edge, Static
+**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. + +```js +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel/serverless'; + +export default defineConfig({ + output: 'server', + adapter: vercel({ + webAnalytics: { + enabled: true, + }, + }), +}); +``` + +### Speed Insights -You can enable [Vercel Analytics](https://vercel.com/analytics) (including Web Vitals and Audiences) by setting `analytics: true`. This will inject Vercel’s tracking scripts into all your pages. +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. + +**Type:** `VercelSpeedInsightsConfig`
+**Available for:** Serverless, Edge, Static
+**Added in:** `@astrojs/vercel@3.8.0` ```js // astro.config.mjs @@ -101,7 +124,9 @@ import vercel from '@astrojs/vercel/serverless'; export default defineConfig({ output: 'server', adapter: vercel({ - analytics: true, + speedInsights: { + enabled: true, + }, }), }); ``` diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json index de6b929be31d..704ddb88b465 100644 --- a/packages/integrations/vercel/package.json +++ b/packages/integrations/vercel/package.json @@ -22,7 +22,7 @@ "./serverless": "./dist/serverless/adapter.js", "./serverless/entrypoint": "./dist/serverless/entrypoint.js", "./static": "./dist/static/adapter.js", - "./analytics": "./dist/analytics.js", + "./speed-insights": "./dist/speed-insights.js", "./build-image-service": "./dist/image/build-service.js", "./dev-image-service": "./dist/image/dev-service.js", "./package.json": "./package.json" diff --git a/packages/integrations/vercel/src/lib/speed-insights.ts b/packages/integrations/vercel/src/lib/speed-insights.ts new file mode 100644 index 000000000000..24402cb5f7c2 --- /dev/null +++ b/packages/integrations/vercel/src/lib/speed-insights.ts @@ -0,0 +1,15 @@ +import { exposeEnv } from './env'; + +export type VercelSpeedInsightsConfig = { + enabled: boolean; +}; + +export function getSpeedInsightsViteConfig(enabled?: boolean) { + if (enabled) { + return { + define: exposeEnv(['VERCEL_ANALYTICS_ID']), + }; + } + + return {}; +} diff --git a/packages/integrations/vercel/src/lib/web-analytics.ts b/packages/integrations/vercel/src/lib/web-analytics.ts new file mode 100644 index 000000000000..d6ee4d78d677 --- /dev/null +++ b/packages/integrations/vercel/src/lib/web-analytics.ts @@ -0,0 +1,30 @@ +export type VercelWebAnalyticsConfig = { + enabled: boolean; +}; + +export async function getInjectableWebAnalyticsContent({ + mode, +}: { + mode: 'development' | 'production'; +}) { + const base = `window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };`; + + if (mode === 'development') { + return ` + ${base} + var script = document.createElement('script'); + script.defer = true; + script.src = 'https://cdn.vercel-insights.com/v1/script.debug.js'; + var head = document.querySelector('head'); + head.appendChild(script); + `; + } + + return `${base} + var script = document.createElement('script'); + script.defer = true; + script.src = '/_vercel/insights/script.js'; + var head = document.querySelector('head'); + head.appendChild(script); + `; +} diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 1c0eb9530d8b..6f9021c69e7d 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -14,10 +14,17 @@ import { getDefaultImageConfig, type VercelImageConfig, } from '../image/shared.js'; -import { exposeEnv } from '../lib/env.js'; import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js'; import { copyDependenciesToFunction } from '../lib/nft.js'; import { getRedirects } from '../lib/redirects.js'; +import { + getSpeedInsightsViteConfig, + type VercelSpeedInsightsConfig, +} from '../lib/speed-insights.js'; +import { + getInjectableWebAnalyticsContent, + type VercelWebAnalyticsConfig, +} from '../lib/web-analytics.js'; import { generateEdgeMiddleware } from './middleware.js'; const PACKAGE_NAME = '@astrojs/vercel/serverless'; @@ -63,9 +70,14 @@ function getAdapter({ } export interface VercelServerlessConfig { + /** + * @deprecated + */ + analytics?: boolean; + webAnalytics?: VercelWebAnalyticsConfig; + speedInsights?: VercelSpeedInsightsConfig; includeFiles?: string[]; excludeFiles?: string[]; - analytics?: boolean; imageService?: boolean; imagesConfig?: VercelImageConfig; edgeMiddleware?: boolean; @@ -73,9 +85,11 @@ export interface VercelServerlessConfig { } export default function vercelServerless({ + analytics, + webAnalytics, + speedInsights, includeFiles, excludeFiles, - analytics, imageService, imagesConfig, functionPerRoute = true, @@ -128,12 +142,25 @@ export default function vercelServerless({ return { name: PACKAGE_NAME, hooks: { - 'astro:config:setup': ({ command, config, updateConfig, injectScript }) => { - if (command === 'build' && analytics) { - injectScript('page', 'import "@astrojs/vercel/analytics"'); + 'astro:config:setup': async ({ command, config, updateConfig, injectScript, logger }) => { + if (webAnalytics?.enabled || analytics) { + if (analytics) { + logger.warn( + `The \`analytics\` property is deprecated. Please use the new \`webAnalytics\` and \`speedInsights\` properties instead.` + ); + } + + injectScript( + 'head-inline', + await getInjectableWebAnalyticsContent({ + mode: command === 'dev' ? 'development' : 'production', + }) + ); + } + if (command === 'build' && (speedInsights?.enabled || analytics)) { + injectScript('page', 'import "@astrojs/vercel/speed-insights"'); } const outDir = getVercelOutput(config.root); - const viteDefine = exposeEnv(['VERCEL_ANALYTICS_ID']); updateConfig({ outDir, build: { @@ -142,7 +169,7 @@ export default function vercelServerless({ server: new URL('./dist/', config.root), }, vite: { - define: viteDefine, + ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), ssr: { external: ['@vercel/nft'], }, diff --git a/packages/integrations/vercel/src/analytics.ts b/packages/integrations/vercel/src/speed-insights.ts similarity index 60% rename from packages/integrations/vercel/src/analytics.ts rename to packages/integrations/vercel/src/speed-insights.ts index 95dee83e37a7..cd2ae7fe8d70 100644 --- a/packages/integrations/vercel/src/analytics.ts +++ b/packages/integrations/vercel/src/speed-insights.ts @@ -1,8 +1,7 @@ -import { inject } from '@vercel/analytics'; import type { Metric } from 'web-vitals'; -import { getCLS, getFCP, getFID, getLCP, getTTFB } from 'web-vitals'; +import { onCLS, onFCP, onFID, onLCP, onTTFB } from 'web-vitals'; -const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals'; +const SPEED_INSIGHTS_INTAKE = 'https://vitals.vercel-analytics.com/v1/vitals'; type Options = { path: string; analyticsId: string }; @@ -14,7 +13,7 @@ const getConnectionSpeed = () => { : ''; }; -const sendToAnalytics = (metric: Metric, options: Options) => { +const sendToSpeedInsights = (metric: Metric, options: Options) => { const body = { dsn: options.analyticsId, id: metric.id, @@ -28,9 +27,9 @@ const sendToAnalytics = (metric: Metric, options: Options) => { type: 'application/x-www-form-urlencoded', }); if (navigator.sendBeacon) { - navigator.sendBeacon(vitalsUrl, blob); + navigator.sendBeacon(SPEED_INSIGHTS_INTAKE, blob); } else - fetch(vitalsUrl, { + fetch(SPEED_INSIGHTS_INTAKE, { body: blob, method: 'POST', credentials: 'omit', @@ -38,27 +37,29 @@ const sendToAnalytics = (metric: Metric, options: Options) => { }); }; -function webVitals() { +function collectWebVitals() { const analyticsId = (import.meta as any).env.PUBLIC_VERCEL_ANALYTICS_ID; + if (!analyticsId) { - console.error('[Analytics] VERCEL_ANALYTICS_ID not found'); + console.error('[Speed Insights] 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)); + onFID((metric) => sendToSpeedInsights(metric, options)); + onTTFB((metric) => sendToSpeedInsights(metric, options)); + onLCP((metric) => sendToSpeedInsights(metric, options)); + onCLS((metric) => sendToSpeedInsights(metric, options)); + onFCP((metric) => sendToSpeedInsights(metric, options)); } catch (err) { - console.error('[Analytics]', err); + console.error('[Speed Insights]', err); } } const mode = (import.meta as any).env.MODE as 'development' | 'production'; -inject({ mode }); if (mode === 'production') { - webVitals(); + collectWebVitals(); } diff --git a/packages/integrations/vercel/src/static/adapter.ts b/packages/integrations/vercel/src/static/adapter.ts index 2908dbf58529..43beba86f845 100644 --- a/packages/integrations/vercel/src/static/adapter.ts +++ b/packages/integrations/vercel/src/static/adapter.ts @@ -5,10 +5,17 @@ import { getDefaultImageConfig, type VercelImageConfig, } from '../image/shared.js'; -import { exposeEnv } from '../lib/env.js'; import { emptyDir, getVercelOutput, writeJson } from '../lib/fs.js'; import { isServerLikeOutput } from '../lib/prerender.js'; import { getRedirects } from '../lib/redirects.js'; +import { + getSpeedInsightsViteConfig, + type VercelSpeedInsightsConfig, +} from '../lib/speed-insights.js'; +import { + getInjectableWebAnalyticsContent, + type VercelWebAnalyticsConfig, +} from '../lib/web-analytics.js'; const PACKAGE_NAME = '@astrojs/vercel/static'; @@ -33,13 +40,20 @@ function getAdapter(): AstroAdapter { } export interface VercelStaticConfig { + /** + * @deprecated + */ analytics?: boolean; + webAnalytics?: VercelWebAnalyticsConfig; + speedInsights?: VercelSpeedInsightsConfig; imageService?: boolean; imagesConfig?: VercelImageConfig; } export default function vercelStatic({ analytics, + webAnalytics, + speedInsights, imageService, imagesConfig, }: VercelStaticConfig = {}): AstroIntegration { @@ -48,12 +62,25 @@ export default function vercelStatic({ return { name: '@astrojs/vercel', hooks: { - 'astro:config:setup': ({ command, config, injectScript, updateConfig }) => { - if (command === 'build' && analytics) { - injectScript('page', 'import "@astrojs/vercel/analytics"'); + 'astro:config:setup': async ({ command, config, injectScript, updateConfig, logger }) => { + if (webAnalytics?.enabled || analytics) { + if (analytics) { + logger.warn( + `The \`analytics\` property is deprecated. Please use the new \`webAnalytics\` and \`speedInsights\` properties instead.` + ); + } + + injectScript( + 'head-inline', + await getInjectableWebAnalyticsContent({ + mode: command === 'dev' ? 'development' : 'production', + }) + ); + } + if (command === 'build' && (speedInsights?.enabled || analytics)) { + injectScript('page', 'import "@astrojs/vercel/speed-insights"'); } const outDir = new URL('./static/', getVercelOutput(config.root)); - const viteDefine = exposeEnv(['VERCEL_ANALYTICS_ID']); updateConfig({ outDir, build: { @@ -61,7 +88,7 @@ export default function vercelStatic({ redirects: false, }, vite: { - define: viteDefine, + ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), }, ...getAstroImageConfig(imageService, imagesConfig, command, config.image), }); diff --git a/packages/integrations/vercel/src/types.d.ts b/packages/integrations/vercel/src/types.d.ts new file mode 100644 index 000000000000..1c5b8d2db11f --- /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/fixtures/with-speed-insights-enabled/output-as-server/astro.config.mjs b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/astro.config.mjs new file mode 100644 index 000000000000..b505034ce483 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/astro.config.mjs @@ -0,0 +1,10 @@ +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel/serverless'; + +export default defineConfig({ + adapter: vercel({ + speedInsights: { + enabled: true + } + }) +}); diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/package.json b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/package.json new file mode 100644 index 000000000000..4c6867fd353a --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/astro-vercel-with-speed-insights-enabled-output-as-server", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/vercel": "workspace:*", + "astro": "workspace:*" + } +} \ No newline at end of file diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/one.astro b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/one.astro new file mode 100644 index 000000000000..0c7fb90a735e --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/one.astro @@ -0,0 +1,8 @@ + + + One + + +

One

+ + diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/two.astro b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/two.astro new file mode 100644 index 000000000000..e7ba9910e2a6 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server/src/pages/two.astro @@ -0,0 +1,8 @@ + + + Two + + +

Two

+ + diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/astro.config.mjs b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/astro.config.mjs new file mode 100644 index 000000000000..a38f1e939b80 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/astro.config.mjs @@ -0,0 +1,10 @@ +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel/static'; + +export default defineConfig({ + adapter: vercel({ + speedInsights: { + enabled: true + } + }) +}); diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/package.json b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/package.json new file mode 100644 index 000000000000..0022e1e925c1 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/astro-vercel-with-speed-insights-enabled-output-as-static", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/vercel": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/one.astro b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/one.astro new file mode 100644 index 000000000000..0c7fb90a735e --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/one.astro @@ -0,0 +1,8 @@ + + + One + + +

One

+ + diff --git a/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/two.astro b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/two.astro new file mode 100644 index 000000000000..e7ba9910e2a6 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static/src/pages/two.astro @@ -0,0 +1,8 @@ + + + Two + + +

Two

+ + diff --git a/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/astro.config.mjs b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/astro.config.mjs new file mode 100644 index 000000000000..395cc94784ff --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/astro.config.mjs @@ -0,0 +1,10 @@ +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel/static'; + +export default defineConfig({ + adapter: vercel({ + webAnalytics: { + enabled: true + } + }) +}); diff --git a/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/package.json b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/package.json new file mode 100644 index 000000000000..c54ef16c759b --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/astro-vercel-with-web-analytics-enabled-output-as-static", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/vercel": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/one.astro b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/one.astro new file mode 100644 index 000000000000..0c7fb90a735e --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/one.astro @@ -0,0 +1,8 @@ + + + One + + +

One

+ + diff --git a/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/two.astro b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/two.astro new file mode 100644 index 000000000000..e7ba9910e2a6 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static/src/pages/two.astro @@ -0,0 +1,8 @@ + + + Two + + +

Two

+ + diff --git a/packages/integrations/vercel/test/speed-insights.test.js b/packages/integrations/vercel/test/speed-insights.test.js new file mode 100644 index 000000000000..7cf2ae7781a5 --- /dev/null +++ b/packages/integrations/vercel/test/speed-insights.test.js @@ -0,0 +1,46 @@ +import { loadFixture } from './test-utils.js'; +import { expect } from 'chai'; + +describe('Vercel Speed Insights', () => { + describe('output: server', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/with-speed-insights-enabled/output-as-server/', + output: 'server', + }); + await fixture.build(); + }); + + it('ensures that Vercel Speed Insights is present in the bundle', async () => { + const [page] = await fixture.readdir('../.vercel/output/static/_astro'); + + const bundle = await fixture.readFile(`../.vercel/output/static/_astro/${page}`); + + expect(bundle).to.contain('https://vitals.vercel-analytics.com/v1/vitals'); + }); + }); + + describe('output: static', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/with-speed-insights-enabled/output-as-static/', + output: 'static', + }); + await fixture.build(); + }); + + it('ensures that Vercel Speed Insights is present in the bundle', async () => { + const [page] = await fixture.readdir('../.vercel/output/static/_astro'); + + const bundle = await fixture.readFile(`../.vercel/output/static/_astro/${page}`); + + expect(bundle).to.contain('https://vitals.vercel-analytics.com/v1/vitals'); + }); + }); +}); diff --git a/packages/integrations/vercel/test/web-analytics.test.js b/packages/integrations/vercel/test/web-analytics.test.js new file mode 100644 index 000000000000..b728fae4caae --- /dev/null +++ b/packages/integrations/vercel/test/web-analytics.test.js @@ -0,0 +1,25 @@ +import { loadFixture } from './test-utils.js'; +import { expect } from 'chai'; + +describe('Vercel Web Analytics', () => { + describe('output: static', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/with-web-analytics-enabled/output-as-static/', + output: 'static', + }); + await fixture.build(); + }); + + it('ensures that Vercel Web Analytics is present in the header', async () => { + const pageOne = await fixture.readFile('../.vercel/output/static/one/index.html'); + const pageTwo = await fixture.readFile('../.vercel/output/static/two/index.html'); + + expect(pageOne).to.contain('/_vercel/insights/script.js'); + expect(pageTwo).to.contain('/_vercel/insights/script.js'); + }); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec37f2a0f9f5..3616defe65e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4843,6 +4843,42 @@ importers: specifier: workspace:* version: link:../../../../../astro + packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-server: + dependencies: + '@astrojs/vercel': + specifier: workspace:* + version: link:../../../.. + astro: + specifier: workspace:* + version: link:../../../../../../astro + + packages/integrations/vercel/test/fixtures/with-speed-insights-enabled/output-as-static: + dependencies: + '@astrojs/vercel': + specifier: workspace:* + version: link:../../../.. + astro: + specifier: workspace:* + version: link:../../../../../../astro + + packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-server: + dependencies: + '@astrojs/vercel': + specifier: workspace:* + version: link:../../../.. + astro: + specifier: workspace:* + version: link:../../../../../../astro + + packages/integrations/vercel/test/fixtures/with-web-analytics-enabled/output-as-static: + dependencies: + '@astrojs/vercel': + specifier: workspace:* + version: link:../../../.. + astro: + specifier: workspace:* + version: link:../../../../../../astro + packages/integrations/vercel/test/hosted/hosted-astro-project: dependencies: '@astrojs/vercel':