@vercel/speed-insights 1.3.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/astro/component.ts +1 -2
  2. package/dist/astro/index.astro +25 -10
  3. package/dist/index.d.mts +12 -10
  4. package/dist/index.d.ts +12 -10
  5. package/dist/index.js +58 -31
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +58 -31
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/next/index.d.mts +5 -5
  10. package/dist/next/index.d.ts +5 -5
  11. package/dist/next/index.js +84 -38
  12. package/dist/next/index.js.map +1 -1
  13. package/dist/next/index.mjs +84 -38
  14. package/dist/next/index.mjs.map +1 -1
  15. package/dist/nuxt/index.d.mts +5 -2
  16. package/dist/nuxt/index.d.ts +5 -2
  17. package/dist/nuxt/index.js +30 -182
  18. package/dist/nuxt/index.js.map +1 -1
  19. package/dist/nuxt/index.mjs +26 -171
  20. package/dist/nuxt/index.mjs.map +1 -1
  21. package/dist/nuxt/runtime/index.d.mts +40 -0
  22. package/dist/nuxt/runtime/index.d.ts +40 -0
  23. package/dist/nuxt/runtime/index.js +278 -0
  24. package/dist/nuxt/runtime/index.js.map +1 -0
  25. package/dist/nuxt/runtime/index.mjs +250 -0
  26. package/dist/nuxt/runtime/index.mjs.map +1 -0
  27. package/dist/react/index.d.mts +6 -5
  28. package/dist/react/index.d.ts +6 -5
  29. package/dist/react/index.js +76 -37
  30. package/dist/react/index.js.map +1 -1
  31. package/dist/react/index.mjs +76 -37
  32. package/dist/react/index.mjs.map +1 -1
  33. package/dist/remix/index.d.mts +5 -5
  34. package/dist/remix/index.d.ts +5 -5
  35. package/dist/remix/index.js +86 -41
  36. package/dist/remix/index.js.map +1 -1
  37. package/dist/remix/index.mjs +86 -41
  38. package/dist/remix/index.mjs.map +1 -1
  39. package/dist/sveltekit/index.d.mts +6 -6
  40. package/dist/sveltekit/index.d.ts +6 -6
  41. package/dist/sveltekit/index.js +77 -43
  42. package/dist/sveltekit/index.js.map +1 -1
  43. package/dist/sveltekit/index.mjs +77 -43
  44. package/dist/sveltekit/index.mjs.map +1 -1
  45. package/dist/vue/index.d.mts +36 -1
  46. package/dist/vue/index.d.ts +36 -1
  47. package/dist/vue/index.js +75 -36
  48. package/dist/vue/index.js.map +1 -1
  49. package/dist/vue/index.mjs +75 -36
  50. package/dist/vue/index.mjs.map +1 -1
  51. package/package.json +16 -6
  52. package/tsup.config.js +17 -2
  53. package/.eslintrc.cjs +0 -7
@@ -1,3 +1,2 @@
1
1
  // @ts-expect-error typescript doesn't handle ./index.astro properly, but it's needed to generate types
2
- // eslint-disable-next-line import/no-default-export, no-useless-rename -- Exporting everything doesn't yield the desired outcome
3
- export { default as default } from './index.astro';
2
+ export { default } from './index.astro';
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  // Since this file will not be bundled by Tsup, it is referencing bundled files relative to dist/astro/
3
3
  import type { SpeedInsightsProps } from '../index.d.ts';
4
+
4
5
  type Props = Omit<SpeedInsightsProps, 'framework' | 'beforeSend'>;
5
6
 
6
7
  const propsStr = JSON.stringify(Astro.props);
@@ -15,10 +16,11 @@ const paramsStr = JSON.stringify(Astro.params);
15
16
  <script>
16
17
  import { injectSpeedInsights, computeRoute } from '../index.mjs';
17
18
 
19
+ // !! important !!
20
+ // do not access env variables using import.meta.env[varname]
21
+ // some bundles won't replace the value at build time.
22
+
18
23
  function getBasePath(): string | undefined {
19
- // !! important !!
20
- // do not access env variables using import.meta.env[varname]
21
- // some bundles won't replace the value at build time.
22
24
  try {
23
25
  return import.meta.env.PUBLIC_VERCEL_OBSERVABILITY_BASEPATH as
24
26
  | string
@@ -28,6 +30,16 @@ const paramsStr = JSON.stringify(Astro.params);
28
30
  }
29
31
  }
30
32
 
33
+ function getConfigString(): string | undefined {
34
+ try {
35
+ return import.meta.env.PUBLIC_VERCEL_OBSERVABILITY_CLIENT_CONFIG as
36
+ | string
37
+ | undefined;
38
+ } catch {
39
+ return undefined;
40
+ }
41
+ }
42
+
31
43
  customElements.define(
32
44
  'vercel-speed-insights',
33
45
  class VercelSpeedInsights extends HTMLElement {
@@ -37,13 +49,16 @@ const paramsStr = JSON.stringify(Astro.params);
37
49
  const props = JSON.parse(this.dataset.props ?? '{}');
38
50
  const params = JSON.parse(this.dataset.params ?? '{}');
39
51
  const route = computeRoute(this.dataset.pathname ?? '', params);
40
- injectSpeedInsights({
41
- route,
42
- ...props,
43
- framework: 'astro',
44
- basePath: getBasePath(),
45
- beforeSend: window.speedInsightsBeforeSend,
46
- });
52
+ injectSpeedInsights(
53
+ {
54
+ route,
55
+ ...props,
56
+ framework: 'astro',
57
+ basePath: getBasePath(),
58
+ beforeSend: window.speedInsightsBeforeSend,
59
+ },
60
+ getConfigString(),
61
+ );
47
62
  } catch (err) {
48
63
  throw new Error(`Failed to parse SpeedInsights properties: ${err}`);
49
64
  }
package/dist/index.d.mts CHANGED
@@ -2,20 +2,24 @@ interface SpeedInsightsProps {
2
2
  dsn?: string;
3
3
  sampleRate?: number;
4
4
  route?: string | null;
5
- beforeSend?: BeforeSendMiddleware;
5
+ beforeSend?: BeforeSend;
6
6
  debug?: boolean;
7
7
  scriptSrc?: string;
8
8
  endpoint?: string;
9
9
  }
10
+ type InjectSpeedInsightsProps = SpeedInsightsProps & {
11
+ framework?: string;
12
+ basePath?: string;
13
+ };
10
14
  type EventTypes = 'vital';
11
- interface Event {
15
+ interface BeforeSendEvent {
12
16
  type: EventTypes;
13
17
  url: string;
14
18
  route?: string;
15
19
  }
16
- type BeforeSendMiddleware = (data: Event) => Event | null | undefined | false;
20
+ type BeforeSend = (event: BeforeSendEvent) => BeforeSendEvent | null | undefined | false;
17
21
  interface Functions {
18
- beforeSend?: BeforeSendMiddleware;
22
+ beforeSend?: BeforeSend;
19
23
  }
20
24
  interface SpeedInsights<T extends keyof Functions = keyof Functions> {
21
25
  queue: [T, Functions[T]][];
@@ -29,7 +33,7 @@ declare global {
29
33
  siq?: SpeedInsights['queue'];
30
34
  sil?: boolean;
31
35
  /** used by Astro component only */
32
- speedInsightsBeforeSend?: BeforeSendMiddleware;
36
+ speedInsightsBeforeSend?: BeforeSend;
33
37
  }
34
38
  }
35
39
 
@@ -43,11 +47,9 @@ declare function computeRoute(pathname: string | null, pathParams: Record<string
43
47
  * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.
44
48
  * @param [props.route] - The dynamic route of the page.
45
49
  * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.
50
+ * @param [confString] - an optional JSON string (InjectSpeedInsightsProps) containing the default configuration. Explicit props will take over any provided default.
46
51
  */
47
- declare function injectSpeedInsights(props?: SpeedInsightsProps & {
48
- framework?: string;
49
- basePath?: string;
50
- }): {
52
+ declare function injectSpeedInsights(props?: InjectSpeedInsightsProps, confString?: string): {
51
53
  setRoute: (route: string | null) => void;
52
54
  } | null;
53
55
 
@@ -56,4 +58,4 @@ declare const _default: {
56
58
  computeRoute: typeof computeRoute;
57
59
  };
58
60
 
59
- export { type BeforeSendMiddleware, type SpeedInsightsProps, computeRoute, _default as default, injectSpeedInsights };
61
+ export { type BeforeSend as BeforeSendMiddleware, type SpeedInsightsProps, computeRoute, _default as default, injectSpeedInsights };
package/dist/index.d.ts CHANGED
@@ -2,20 +2,24 @@ interface SpeedInsightsProps {
2
2
  dsn?: string;
3
3
  sampleRate?: number;
4
4
  route?: string | null;
5
- beforeSend?: BeforeSendMiddleware;
5
+ beforeSend?: BeforeSend;
6
6
  debug?: boolean;
7
7
  scriptSrc?: string;
8
8
  endpoint?: string;
9
9
  }
10
+ type InjectSpeedInsightsProps = SpeedInsightsProps & {
11
+ framework?: string;
12
+ basePath?: string;
13
+ };
10
14
  type EventTypes = 'vital';
11
- interface Event {
15
+ interface BeforeSendEvent {
12
16
  type: EventTypes;
13
17
  url: string;
14
18
  route?: string;
15
19
  }
16
- type BeforeSendMiddleware = (data: Event) => Event | null | undefined | false;
20
+ type BeforeSend = (event: BeforeSendEvent) => BeforeSendEvent | null | undefined | false;
17
21
  interface Functions {
18
- beforeSend?: BeforeSendMiddleware;
22
+ beforeSend?: BeforeSend;
19
23
  }
20
24
  interface SpeedInsights<T extends keyof Functions = keyof Functions> {
21
25
  queue: [T, Functions[T]][];
@@ -29,7 +33,7 @@ declare global {
29
33
  siq?: SpeedInsights['queue'];
30
34
  sil?: boolean;
31
35
  /** used by Astro component only */
32
- speedInsightsBeforeSend?: BeforeSendMiddleware;
36
+ speedInsightsBeforeSend?: BeforeSend;
33
37
  }
34
38
  }
35
39
 
@@ -43,11 +47,9 @@ declare function computeRoute(pathname: string | null, pathParams: Record<string
43
47
  * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.
44
48
  * @param [props.route] - The dynamic route of the page.
45
49
  * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.
50
+ * @param [confString] - an optional JSON string (InjectSpeedInsightsProps) containing the default configuration. Explicit props will take over any provided default.
46
51
  */
47
- declare function injectSpeedInsights(props?: SpeedInsightsProps & {
48
- framework?: string;
49
- basePath?: string;
50
- }): {
52
+ declare function injectSpeedInsights(props?: InjectSpeedInsightsProps, confString?: string): {
51
53
  setRoute: (route: string | null) => void;
52
54
  } | null;
53
55
 
@@ -56,4 +58,4 @@ declare const _default: {
56
58
  computeRoute: typeof computeRoute;
57
59
  };
58
60
 
59
- export { type BeforeSendMiddleware, type SpeedInsightsProps, computeRoute, _default as default, injectSpeedInsights };
61
+ export { type BeforeSend as BeforeSendMiddleware, type SpeedInsightsProps, computeRoute, _default as default, injectSpeedInsights };
package/dist/index.js CHANGED
@@ -26,18 +26,19 @@ __export(generic_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(generic_exports);
28
28
 
29
- // package.json
30
- var name = "@vercel/speed-insights";
31
- var version = "1.3.1";
32
-
33
29
  // src/queue.ts
34
30
  var initQueue = () => {
35
31
  if (window.si) return;
36
32
  window.si = function a(...params) {
37
- (window.siq = window.siq || []).push(params);
33
+ window.siq = window.siq || [];
34
+ window.siq.push(params);
38
35
  };
39
36
  };
40
37
 
38
+ // package.json
39
+ var name = "@vercel/speed-insights";
40
+ var version = "2.0.0";
41
+
41
42
  // src/utils.ts
42
43
  function isBrowser() {
43
44
  return typeof window !== "undefined";
@@ -48,7 +49,7 @@ function detectEnvironment() {
48
49
  if (env === "development" || env === "test") {
49
50
  return "development";
50
51
  }
51
- } catch (e) {
52
+ } catch {
52
53
  }
53
54
  return "production";
54
55
  }
@@ -79,7 +80,7 @@ function computeRoute(pathname, pathParams) {
79
80
  }
80
81
  }
81
82
  return result;
82
- } catch (e) {
83
+ } catch {
83
84
  return pathname;
84
85
  }
85
86
  }
@@ -91,7 +92,7 @@ function escapeRegExp(string) {
91
92
  }
92
93
  function getScriptSrc(props) {
93
94
  if (props.scriptSrc) {
94
- return props.scriptSrc;
95
+ return makeAbsolute(props.scriptSrc);
95
96
  }
96
97
  if (isDevelopment()) {
97
98
  return "https://va.vercel-scripts.com/v1/speed-insights/script.debug.js";
@@ -100,42 +101,68 @@ function getScriptSrc(props) {
100
101
  return "https://va.vercel-scripts.com/v1/speed-insights/script.js";
101
102
  }
102
103
  if (props.basePath) {
103
- return `${props.basePath}/speed-insights/script.js`;
104
+ return makeAbsolute(`${props.basePath}/speed-insights/script.js`);
104
105
  }
105
106
  return "/_vercel/speed-insights/script.js";
106
107
  }
107
-
108
- // src/generic.ts
109
- function injectSpeedInsights(props = {}) {
108
+ function loadProps(explicitProps, confString) {
110
109
  var _a;
111
- if (!isBrowser() || props.route === null) return null;
112
- initQueue();
113
- const src = getScriptSrc(props);
114
- if (document.head.querySelector(`script[src*="${src}"]`)) return null;
115
- if (props.beforeSend) {
116
- (_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
110
+ let props = explicitProps;
111
+ if (confString) {
112
+ try {
113
+ props = {
114
+ ...(_a = JSON.parse(confString)) == null ? void 0 : _a.speedInsights,
115
+ ...explicitProps
116
+ };
117
+ } catch {
118
+ }
117
119
  }
118
- const script = document.createElement("script");
119
- script.src = src;
120
- script.defer = true;
121
- script.dataset.sdkn = name + (props.framework ? `/${props.framework}` : "");
122
- script.dataset.sdkv = version;
120
+ const dataset = {
121
+ sdkn: name + (props.framework ? `/${props.framework}` : ""),
122
+ sdkv: version
123
+ };
123
124
  if (props.sampleRate) {
124
- script.dataset.sampleRate = props.sampleRate.toString();
125
+ dataset.sampleRate = props.sampleRate.toString();
125
126
  }
126
127
  if (props.route) {
127
- script.dataset.route = props.route;
128
+ dataset.route = props.route;
129
+ }
130
+ if (isDevelopment() && props.debug === false) {
131
+ dataset.debug = "false";
132
+ }
133
+ if (props.dsn) {
134
+ dataset.dsn = props.dsn;
128
135
  }
129
136
  if (props.endpoint) {
130
- script.dataset.endpoint = props.endpoint;
137
+ dataset.endpoint = makeAbsolute(props.endpoint);
131
138
  } else if (props.basePath) {
132
- script.dataset.endpoint = `${props.basePath}/speed-insights/vitals`;
139
+ dataset.endpoint = makeAbsolute(`${props.basePath}/speed-insights/vitals`);
133
140
  }
134
- if (props.dsn) {
135
- script.dataset.dsn = props.dsn;
141
+ return {
142
+ src: getScriptSrc(props),
143
+ beforeSend: props.beforeSend,
144
+ dataset
145
+ };
146
+ }
147
+ function makeAbsolute(url) {
148
+ return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("/") ? url : `/${url}`;
149
+ }
150
+
151
+ // src/generic.ts
152
+ function injectSpeedInsights(props = {}, confString) {
153
+ var _a;
154
+ if (!isBrowser() || props.route === null) return null;
155
+ initQueue();
156
+ const { beforeSend, src, dataset } = loadProps(props, confString);
157
+ if (document.head.querySelector(`script[src*="${src}"]`)) return null;
158
+ if (beforeSend) {
159
+ (_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
136
160
  }
137
- if (isDevelopment() && props.debug === false) {
138
- script.dataset.debug = "false";
161
+ const script = document.createElement("script");
162
+ script.src = src;
163
+ script.defer = true;
164
+ for (const [key, value] of Object.entries(dataset)) {
165
+ script.dataset[key] = value;
139
166
  }
140
167
  script.onerror = () => {
141
168
  console.log(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generic.ts","../package.json","../src/queue.ts","../src/utils.ts"],"sourcesContent":["import { name as packageName, version } from '../package.json';\nimport { initQueue } from './queue';\nimport type { SpeedInsightsProps, BeforeSendMiddleware } from './types';\nimport { computeRoute, getScriptSrc, isBrowser, isDevelopment } from './utils';\n\n/**\n * Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).\n * @param [props] - Speed Insights options.\n * @param [props.debug] - Whether to enable debug logging in development. Defaults to `true`.\n * @param [props.beforeSend] - A middleware function to modify events before they are sent. Should return the event object or `null` to cancel the event.\n * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.\n * @param [props.route] - The dynamic route of the page.\n * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.\n */\nfunction injectSpeedInsights(\n props: SpeedInsightsProps & {\n framework?: string;\n basePath?: string;\n } = {},\n): {\n setRoute: (route: string | null) => void;\n} | null {\n // When route is null, it means that pages router is not ready yet. Will resolve soon\n if (!isBrowser() || props.route === null) return null;\n\n initQueue();\n\n const src = getScriptSrc(props);\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return null;\n\n if (props.beforeSend) {\n window.si?.('beforeSend', props.beforeSend);\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n script.dataset.sdkn =\n packageName + (props.framework ? `/${props.framework}` : '');\n script.dataset.sdkv = version;\n\n if (props.sampleRate) {\n script.dataset.sampleRate = props.sampleRate.toString();\n }\n if (props.route) {\n script.dataset.route = props.route;\n }\n if (props.endpoint) {\n script.dataset.endpoint = props.endpoint;\n } else if (props.basePath) {\n script.dataset.endpoint = `${props.basePath}/speed-insights/vitals`;\n }\n if (props.dsn) {\n script.dataset.dsn = props.dsn;\n }\n if (isDevelopment() && props.debug === false) {\n script.dataset.debug = 'false';\n }\n\n script.onerror = (): void => {\n // eslint-disable-next-line no-console -- Logging is okay here\n console.log(\n `[Vercel Speed Insights] Failed to load script from ${src}. Please check if any content blockers are enabled and try again.`,\n );\n };\n\n document.head.appendChild(script);\n\n return {\n setRoute: (route: string | null): void => {\n script.dataset.route = route ?? undefined;\n },\n };\n}\n\nexport { injectSpeedInsights, computeRoute };\nexport type { SpeedInsightsProps, BeforeSendMiddleware };\n\n// eslint-disable-next-line import/no-default-export -- Allow default export\nexport default {\n injectSpeedInsights,\n computeRoute,\n};\n","{\n \"name\": \"@vercel/speed-insights\",\n \"version\": \"1.3.1\",\n \"description\": \"Speed Insights is a tool for measuring web performance and providing suggestions for improvement.\",\n \"keywords\": [\n \"speed-insights\",\n \"vercel\"\n ],\n \"repository\": {\n \"url\": \"github:vercel/speed-insights\",\n \"directory\": \"packages/web\"\n },\n \"license\": \"Apache-2.0\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": {\n \"browser\": \"./dist/index.mjs\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./astro\": {\n \"import\": \"./dist/astro/component.ts\"\n },\n \"./next\": {\n \"browser\": \"./dist/next/index.mjs\",\n \"import\": \"./dist/next/index.mjs\",\n \"require\": \"./dist/next/index.js\"\n },\n \"./nuxt\": {\n \"browser\": \"./dist/nuxt/index.mjs\",\n \"import\": \"./dist/nuxt/index.mjs\",\n \"require\": \"./dist/nuxt/index.js\"\n },\n \"./react\": {\n \"browser\": \"./dist/react/index.mjs\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./remix\": {\n \"browser\": \"./dist/remix/index.mjs\",\n \"import\": \"./dist/remix/index.mjs\",\n \"require\": \"./dist/remix/index.js\"\n },\n \"./sveltekit\": {\n \"types\": \"./dist/sveltekit/index.d.ts\",\n \"svelte\": \"./dist/sveltekit/index.mjs\"\n },\n \"./vue\": {\n \"browser\": \"./dist/vue/index.mjs\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"*\": [\n \"dist/index.d.ts\"\n ],\n \"react\": [\n \"dist/react/index.d.ts\"\n ],\n \"next\": [\n \"dist/next/index.d.ts\"\n ],\n \"nuxt\": [\n \"dist/nuxt/index.d.ts\"\n ],\n \"remix\": [\n \"dist/remix/index.d.ts\"\n ],\n \"sveltekit\": [\n \"dist/sveltekit/index.d.ts\"\n ],\n \"vue\": [\n \"dist/vue/index.d.ts\"\n ]\n }\n },\n \"scripts\": {\n \"build\": \"tsup && pnpm copy-astro\",\n \"copy-astro\": \"cp -R src/astro dist/\",\n \"dev\": \"pnpm copy-astro && tsup --watch\",\n \"lint\": \"eslint .\",\n \"lint-fix\": \"eslint . --fix\",\n \"test\": \"vitest\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@remix-run/react\": \"^2.14.0\",\n \"@sveltejs/kit\": \"^2.8.1\",\n \"@swc/core\": \"^1.9.2\",\n \"@testing-library/jest-dom\": \"^6.6.3\",\n \"@testing-library/react\": \"^16.0.1\",\n \"@types/node\": \"^22.9.1\",\n \"@types/react\": \"^18.3.12\",\n \"copyfiles\": \"^2.4.1\",\n \"jsdom\": \"^25.0.1\",\n \"next\": \"^14.0.4\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"svelte\": \"^5.2.7\",\n \"tsup\": \"8.3.5\",\n \"vitest\": \"^2.1.5\",\n \"vue\": \"^3.5.13\",\n \"vue-router\": \"^4.4.5\"\n },\n \"peerDependencies\": {\n \"@sveltejs/kit\": \"^1 || ^2\",\n \"next\": \">= 13\",\n \"react\": \"^18 || ^19 || ^19.0.0-rc\",\n \"svelte\": \">= 4\",\n \"vue\": \"^3\",\n \"vue-router\": \"^4\"\n },\n \"peerDependenciesMeta\": {\n \"@sveltejs/kit\": {\n \"optional\": true\n },\n \"next\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vue-router\": {\n \"optional\": true\n }\n }\n}\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.si) return;\n\n window.si = function a(...params): void {\n (window.siq = window.siq || []).push(params);\n };\n};\n","import type { SpeedInsightsProps } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n try {\n const env = process.env.NODE_ENV;\n if (env === 'development' || env === 'test') {\n return 'development';\n }\n } catch (e) {\n // do nothing, this is okay\n }\n return 'production';\n}\n\nexport function isProduction(): boolean {\n return detectEnvironment() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return detectEnvironment() === 'development';\n}\n\nexport function computeRoute(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (!pathname || !pathParams) {\n return pathname;\n }\n\n let result = pathname;\n try {\n const entries = Object.entries(pathParams);\n // simple keys must be handled first\n for (const [key, value] of entries) {\n if (!Array.isArray(value)) {\n const matcher = turnValueToRegExp(value);\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[${key}]`);\n }\n }\n }\n // array values next\n for (const [key, value] of entries) {\n if (Array.isArray(value)) {\n const matcher = turnValueToRegExp(value.join('/'));\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[...${key}]`);\n }\n }\n }\n return result;\n } catch (e) {\n return pathname;\n }\n}\n\nfunction turnValueToRegExp(value: string): RegExp {\n return new RegExp(`/${escapeRegExp(value)}(?=[/?#]|$)`);\n}\n\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getScriptSrc(\n props: SpeedInsightsProps & { basePath?: string },\n): string {\n if (props.scriptSrc) {\n return props.scriptSrc;\n }\n if (isDevelopment()) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.debug.js';\n }\n if (props.dsn) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.js';\n }\n if (props.basePath) {\n return `${props.basePath}/speed-insights/script.js`;\n }\n return '/_vercel/speed-insights/script.js';\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/generic.ts","../src/queue.ts","../package.json","../src/utils.ts"],"sourcesContent":["import { initQueue } from './queue';\nimport type {\n BeforeSend,\n InjectSpeedInsightsProps,\n SpeedInsightsProps,\n} from './types';\nimport { computeRoute, isBrowser, loadProps } from './utils';\n\n/**\n * Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).\n * @param [props] - Speed Insights options.\n * @param [props.debug] - Whether to enable debug logging in development. Defaults to `true`.\n * @param [props.beforeSend] - A middleware function to modify events before they are sent. Should return the event object or `null` to cancel the event.\n * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.\n * @param [props.route] - The dynamic route of the page.\n * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.\n * @param [confString] - an optional JSON string (InjectSpeedInsightsProps) containing the default configuration. Explicit props will take over any provided default.\n */\nfunction injectSpeedInsights(\n props: InjectSpeedInsightsProps = {},\n confString?: string,\n): {\n setRoute: (route: string | null) => void;\n} | null {\n // When route is null, it means that pages router is not ready yet. Will resolve soon\n if (!isBrowser() || props.route === null) return null;\n\n initQueue();\n\n const { beforeSend, src, dataset } = loadProps(props, confString);\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return null;\n\n if (beforeSend) {\n window.si?.('beforeSend', beforeSend);\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n // Apply all dataset attributes from loadProps\n for (const [key, value] of Object.entries(dataset)) {\n script.dataset[key] = value;\n }\n\n script.onerror = (): void => {\n console.log(\n `[Vercel Speed Insights] Failed to load script from ${src}. Please check if any content blockers are enabled and try again.`,\n );\n };\n\n document.head.appendChild(script);\n\n return {\n setRoute: (route: string | null): void => {\n script.dataset.route = route ?? undefined;\n },\n };\n}\n\nexport { injectSpeedInsights, computeRoute };\nexport type { SpeedInsightsProps, BeforeSend as BeforeSendMiddleware };\n\nexport default {\n injectSpeedInsights,\n computeRoute,\n};\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.si) return;\n\n window.si = function a(...params): void {\n window.siq = window.siq || [];\n window.siq.push(params);\n };\n};\n","{\n \"name\": \"@vercel/speed-insights\",\n \"version\": \"2.0.0\",\n \"description\": \"Speed Insights is a tool for measuring web performance and providing suggestions for improvement.\",\n \"keywords\": [\n \"speed-insights\",\n \"vercel\"\n ],\n \"repository\": {\n \"url\": \"github:vercel/speed-insights\",\n \"directory\": \"packages/web\"\n },\n \"license\": \"Apache-2.0\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": {\n \"browser\": \"./dist/index.mjs\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./astro\": {\n \"import\": \"./dist/astro/component.ts\"\n },\n \"./next\": {\n \"browser\": \"./dist/next/index.mjs\",\n \"import\": \"./dist/next/index.mjs\",\n \"require\": \"./dist/next/index.js\"\n },\n \"./nuxt\": {\n \"import\": \"./dist/nuxt/index.mjs\",\n \"require\": \"./dist/nuxt/index.js\"\n },\n \"./nuxt/runtime\": {\n \"browser\": \"./dist/nuxt/runtime/index.mjs\",\n \"import\": \"./dist/nuxt/runtime/index.mjs\",\n \"require\": \"./dist/nuxt/runtime/index.js\"\n },\n \"./react\": {\n \"browser\": \"./dist/react/index.mjs\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./remix\": {\n \"browser\": \"./dist/remix/index.mjs\",\n \"import\": \"./dist/remix/index.mjs\",\n \"require\": \"./dist/remix/index.js\"\n },\n \"./sveltekit\": {\n \"types\": \"./dist/sveltekit/index.d.ts\",\n \"svelte\": \"./dist/sveltekit/index.mjs\"\n },\n \"./vue\": {\n \"browser\": \"./dist/vue/index.mjs\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"*\": [\n \"dist/index.d.ts\"\n ],\n \"react\": [\n \"dist/react/index.d.ts\"\n ],\n \"next\": [\n \"dist/next/index.d.ts\"\n ],\n \"nuxt\": [\n \"dist/nuxt/index.d.ts\"\n ],\n \"nuxt/runtime\": [\n \"dist/nuxt/runtime/index.d.ts\"\n ],\n \"remix\": [\n \"dist/remix/index.d.ts\"\n ],\n \"sveltekit\": [\n \"dist/sveltekit/index.d.ts\"\n ],\n \"vue\": [\n \"dist/vue/index.d.ts\"\n ]\n }\n },\n \"scripts\": {\n \"build\": \"tsup && pnpm copy-astro\",\n \"copy-astro\": \"cp -R src/astro dist/\",\n \"dev\": \"pnpm copy-astro && tsup --watch\",\n \"test\": \"vitest\"\n },\n \"devDependencies\": {\n \"@nuxt/kit\": \"^4.2.0\",\n \"@nuxt/schema\": \"^4.2.0\",\n \"@remix-run/react\": \"^2.14.0\",\n \"@sveltejs/kit\": \"^2.8.1\",\n \"@swc/core\": \"^1.9.2\",\n \"@testing-library/jest-dom\": \"^6.6.3\",\n \"@testing-library/react\": \"^16.0.1\",\n \"@types/node\": \"^22.9.1\",\n \"@types/react\": \"^18.3.12\",\n \"copyfiles\": \"^2.4.1\",\n \"jsdom\": \"^25.0.1\",\n \"next\": \"^14.0.4\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"svelte\": \"^5.2.7\",\n \"tsup\": \"8.3.5\",\n \"vitest\": \"^2.1.5\",\n \"vue\": \"^3.5.13\",\n \"vue-router\": \"^4.4.5\"\n },\n \"peerDependencies\": {\n \"@sveltejs/kit\": \"^1 || ^2\",\n \"next\": \">= 13\",\n \"nuxt\": \">= 3\",\n \"react\": \"^18 || ^19 || ^19.0.0-rc\",\n \"svelte\": \">= 4\",\n \"vue\": \"^3\",\n \"vue-router\": \"^4\"\n },\n \"peerDependenciesMeta\": {\n \"@sveltejs/kit\": {\n \"optional\": true\n },\n \"next\": {\n \"optional\": true\n },\n \"nuxt\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vue-router\": {\n \"optional\": true\n }\n }\n}\n","import { name as packageName, version } from '../package.json';\nimport type {\n BeforeSend,\n InjectSpeedInsightsProps,\n SpeedInsightsProps,\n} from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n try {\n const env = process.env.NODE_ENV;\n if (env === 'development' || env === 'test') {\n return 'development';\n }\n } catch {\n // do nothing, this is okay\n }\n return 'production';\n}\n\nexport function isProduction(): boolean {\n return detectEnvironment() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return detectEnvironment() === 'development';\n}\n\nexport function computeRoute(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (!pathname || !pathParams) {\n return pathname;\n }\n\n let result = pathname;\n try {\n const entries = Object.entries(pathParams);\n // simple keys must be handled first\n for (const [key, value] of entries) {\n if (!Array.isArray(value)) {\n const matcher = turnValueToRegExp(value);\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[${key}]`);\n }\n }\n }\n // array values next\n for (const [key, value] of entries) {\n if (Array.isArray(value)) {\n const matcher = turnValueToRegExp(value.join('/'));\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[...${key}]`);\n }\n }\n }\n return result;\n } catch {\n return pathname;\n }\n}\n\nfunction turnValueToRegExp(value: string): RegExp {\n return new RegExp(`/${escapeRegExp(value)}(?=[/?#]|$)`);\n}\n\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction getScriptSrc(\n props: SpeedInsightsProps & { basePath?: string },\n): string {\n if (props.scriptSrc) {\n return makeAbsolute(props.scriptSrc);\n }\n if (isDevelopment()) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.debug.js';\n }\n if (props.dsn) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.js';\n }\n if (props.basePath) {\n return makeAbsolute(`${props.basePath}/speed-insights/script.js`);\n }\n return '/_vercel/speed-insights/script.js';\n}\n\nexport function loadProps(\n explicitProps: InjectSpeedInsightsProps,\n confString?: string,\n): {\n src: string;\n beforeSend?: BeforeSend;\n dataset: Record<string, string>;\n} {\n let props = explicitProps;\n if (confString) {\n try {\n props = {\n ...(JSON.parse(confString)\n ?.speedInsights as Partial<SpeedInsightsProps>),\n ...explicitProps,\n };\n } catch {\n // Invalid JSON, use only explicit props\n }\n }\n\n const dataset: Record<string, string> = {\n sdkn: packageName + (props.framework ? `/${props.framework}` : ''),\n sdkv: version,\n };\n\n if (props.sampleRate) {\n dataset.sampleRate = props.sampleRate.toString();\n }\n if (props.route) {\n dataset.route = props.route;\n }\n if (isDevelopment() && props.debug === false) {\n dataset.debug = 'false';\n }\n if (props.dsn) {\n dataset.dsn = props.dsn;\n }\n\n if (props.endpoint) {\n dataset.endpoint = makeAbsolute(props.endpoint);\n } else if (props.basePath) {\n // backward compatibility\n dataset.endpoint = makeAbsolute(`${props.basePath}/speed-insights/vitals`);\n }\n\n return {\n src: getScriptSrc(props),\n beforeSend: props.beforeSend,\n dataset,\n };\n}\n\nfunction makeAbsolute(url: string): string {\n return url.startsWith('http://') ||\n url.startsWith('https://') ||\n url.startsWith('/')\n ? url\n : `/${url}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO,GAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,WAAO,MAAM,OAAO,OAAO,CAAC;AAC5B,WAAO,IAAI,KAAK,MAAM;AAAA,EACxB;AACF;;;ACPE,WAAQ;AACR,cAAW;;;ACKN,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,oBAAkD;AACzD,MAAI;AACF,UAAM,MAAM,QAAQ,IAAI;AACxB,QAAI,QAAQ,iBAAiB,QAAQ,QAAQ;AAC3C,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAMO,SAAS,gBAAyB;AACvC,SAAO,kBAAkB,MAAM;AACjC;AAEO,SAAS,aACd,UACA,YACe;AACf,MAAI,CAAC,YAAY,CAAC,YAAY;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,MAAI;AACF,UAAM,UAAU,OAAO,QAAQ,UAAU;AAEzC,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,UAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,cAAM,UAAU,kBAAkB,KAAK;AACvC,YAAI,QAAQ,KAAK,MAAM,GAAG;AACxB,mBAAS,OAAO,QAAQ,SAAS,KAAK,GAAG,GAAG;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAEA,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAM,UAAU,kBAAkB,MAAM,KAAK,GAAG,CAAC;AACjD,YAAI,QAAQ,KAAK,MAAM,GAAG;AACxB,mBAAS,OAAO,QAAQ,SAAS,QAAQ,GAAG,GAAG;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,IAAI,OAAO,IAAI,aAAa,KAAK,CAAC,aAAa;AACxD;AAEA,SAAS,aAAa,QAAwB;AAC5C,SAAO,OAAO,QAAQ,uBAAuB,MAAM;AACrD;AAEA,SAAS,aACP,OACQ;AACR,MAAI,MAAM,WAAW;AACnB,WAAO,aAAa,MAAM,SAAS;AAAA,EACrC;AACA,MAAI,cAAc,GAAG;AACnB,WAAO;AAAA,EACT;AACA,MAAI,MAAM,KAAK;AACb,WAAO;AAAA,EACT;AACA,MAAI,MAAM,UAAU;AAClB,WAAO,aAAa,GAAG,MAAM,QAAQ,2BAA2B;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,UACd,eACA,YAKA;AAnGF;AAoGE,MAAI,QAAQ;AACZ,MAAI,YAAY;AACd,QAAI;AACF,cAAQ;AAAA,QACN,IAAI,UAAK,MAAM,UAAU,MAArB,mBACA;AAAA,QACJ,GAAG;AAAA,MACL;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,UAAkC;AAAA,IACtC,MAAM,QAAe,MAAM,YAAY,IAAI,MAAM,SAAS,KAAK;AAAA,IAC/D,MAAM;AAAA,EACR;AAEA,MAAI,MAAM,YAAY;AACpB,YAAQ,aAAa,MAAM,WAAW,SAAS;AAAA,EACjD;AACA,MAAI,MAAM,OAAO;AACf,YAAQ,QAAQ,MAAM;AAAA,EACxB;AACA,MAAI,cAAc,KAAK,MAAM,UAAU,OAAO;AAC5C,YAAQ,QAAQ;AAAA,EAClB;AACA,MAAI,MAAM,KAAK;AACb,YAAQ,MAAM,MAAM;AAAA,EACtB;AAEA,MAAI,MAAM,UAAU;AAClB,YAAQ,WAAW,aAAa,MAAM,QAAQ;AAAA,EAChD,WAAW,MAAM,UAAU;AAEzB,YAAQ,WAAW,aAAa,GAAG,MAAM,QAAQ,wBAAwB;AAAA,EAC3E;AAEA,SAAO;AAAA,IACL,KAAK,aAAa,KAAK;AAAA,IACvB,YAAY,MAAM;AAAA,IAClB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,WAAW,SAAS,KAC7B,IAAI,WAAW,UAAU,KACzB,IAAI,WAAW,GAAG,IAChB,MACA,IAAI,GAAG;AACb;;;AHrIA,SAAS,oBACP,QAAkC,CAAC,GACnC,YAGO;AAvBT;AAyBE,MAAI,CAAC,UAAU,KAAK,MAAM,UAAU,KAAM,QAAO;AAEjD,YAAU;AAEV,QAAM,EAAE,YAAY,KAAK,QAAQ,IAAI,UAAU,OAAO,UAAU;AAEhE,MAAI,SAAS,KAAK,cAAc,gBAAgB,GAAG,IAAI,EAAG,QAAO;AAEjE,MAAI,YAAY;AACd,iBAAO,OAAP,gCAAY,cAAc;AAAA,EAC5B;AAEA,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAGf,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,WAAO,QAAQ,GAAG,IAAI;AAAA,EACxB;AAEA,SAAO,UAAU,MAAY;AAC3B,YAAQ;AAAA,MACN,sDAAsD,GAAG;AAAA,IAC3D;AAAA,EACF;AAEA,WAAS,KAAK,YAAY,MAAM;AAEhC,SAAO;AAAA,IACL,UAAU,CAAC,UAA+B;AACxC,aAAO,QAAQ,QAAQ,SAAS;AAAA,IAClC;AAAA,EACF;AACF;AAKA,IAAO,kBAAQ;AAAA,EACb;AAAA,EACA;AACF;","names":[]}
package/dist/index.mjs CHANGED
@@ -1,15 +1,16 @@
1
- // package.json
2
- var name = "@vercel/speed-insights";
3
- var version = "1.3.1";
4
-
5
1
  // src/queue.ts
6
2
  var initQueue = () => {
7
3
  if (window.si) return;
8
4
  window.si = function a(...params) {
9
- (window.siq = window.siq || []).push(params);
5
+ window.siq = window.siq || [];
6
+ window.siq.push(params);
10
7
  };
11
8
  };
12
9
 
10
+ // package.json
11
+ var name = "@vercel/speed-insights";
12
+ var version = "2.0.0";
13
+
13
14
  // src/utils.ts
14
15
  function isBrowser() {
15
16
  return typeof window !== "undefined";
@@ -20,7 +21,7 @@ function detectEnvironment() {
20
21
  if (env === "development" || env === "test") {
21
22
  return "development";
22
23
  }
23
- } catch (e) {
24
+ } catch {
24
25
  }
25
26
  return "production";
26
27
  }
@@ -51,7 +52,7 @@ function computeRoute(pathname, pathParams) {
51
52
  }
52
53
  }
53
54
  return result;
54
- } catch (e) {
55
+ } catch {
55
56
  return pathname;
56
57
  }
57
58
  }
@@ -63,7 +64,7 @@ function escapeRegExp(string) {
63
64
  }
64
65
  function getScriptSrc(props) {
65
66
  if (props.scriptSrc) {
66
- return props.scriptSrc;
67
+ return makeAbsolute(props.scriptSrc);
67
68
  }
68
69
  if (isDevelopment()) {
69
70
  return "https://va.vercel-scripts.com/v1/speed-insights/script.debug.js";
@@ -72,42 +73,68 @@ function getScriptSrc(props) {
72
73
  return "https://va.vercel-scripts.com/v1/speed-insights/script.js";
73
74
  }
74
75
  if (props.basePath) {
75
- return `${props.basePath}/speed-insights/script.js`;
76
+ return makeAbsolute(`${props.basePath}/speed-insights/script.js`);
76
77
  }
77
78
  return "/_vercel/speed-insights/script.js";
78
79
  }
79
-
80
- // src/generic.ts
81
- function injectSpeedInsights(props = {}) {
80
+ function loadProps(explicitProps, confString) {
82
81
  var _a;
83
- if (!isBrowser() || props.route === null) return null;
84
- initQueue();
85
- const src = getScriptSrc(props);
86
- if (document.head.querySelector(`script[src*="${src}"]`)) return null;
87
- if (props.beforeSend) {
88
- (_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
82
+ let props = explicitProps;
83
+ if (confString) {
84
+ try {
85
+ props = {
86
+ ...(_a = JSON.parse(confString)) == null ? void 0 : _a.speedInsights,
87
+ ...explicitProps
88
+ };
89
+ } catch {
90
+ }
89
91
  }
90
- const script = document.createElement("script");
91
- script.src = src;
92
- script.defer = true;
93
- script.dataset.sdkn = name + (props.framework ? `/${props.framework}` : "");
94
- script.dataset.sdkv = version;
92
+ const dataset = {
93
+ sdkn: name + (props.framework ? `/${props.framework}` : ""),
94
+ sdkv: version
95
+ };
95
96
  if (props.sampleRate) {
96
- script.dataset.sampleRate = props.sampleRate.toString();
97
+ dataset.sampleRate = props.sampleRate.toString();
97
98
  }
98
99
  if (props.route) {
99
- script.dataset.route = props.route;
100
+ dataset.route = props.route;
101
+ }
102
+ if (isDevelopment() && props.debug === false) {
103
+ dataset.debug = "false";
104
+ }
105
+ if (props.dsn) {
106
+ dataset.dsn = props.dsn;
100
107
  }
101
108
  if (props.endpoint) {
102
- script.dataset.endpoint = props.endpoint;
109
+ dataset.endpoint = makeAbsolute(props.endpoint);
103
110
  } else if (props.basePath) {
104
- script.dataset.endpoint = `${props.basePath}/speed-insights/vitals`;
111
+ dataset.endpoint = makeAbsolute(`${props.basePath}/speed-insights/vitals`);
105
112
  }
106
- if (props.dsn) {
107
- script.dataset.dsn = props.dsn;
113
+ return {
114
+ src: getScriptSrc(props),
115
+ beforeSend: props.beforeSend,
116
+ dataset
117
+ };
118
+ }
119
+ function makeAbsolute(url) {
120
+ return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("/") ? url : `/${url}`;
121
+ }
122
+
123
+ // src/generic.ts
124
+ function injectSpeedInsights(props = {}, confString) {
125
+ var _a;
126
+ if (!isBrowser() || props.route === null) return null;
127
+ initQueue();
128
+ const { beforeSend, src, dataset } = loadProps(props, confString);
129
+ if (document.head.querySelector(`script[src*="${src}"]`)) return null;
130
+ if (beforeSend) {
131
+ (_a = window.si) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
108
132
  }
109
- if (isDevelopment() && props.debug === false) {
110
- script.dataset.debug = "false";
133
+ const script = document.createElement("script");
134
+ script.src = src;
135
+ script.defer = true;
136
+ for (const [key, value] of Object.entries(dataset)) {
137
+ script.dataset[key] = value;
111
138
  }
112
139
  script.onerror = () => {
113
140
  console.log(
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/queue.ts","../src/utils.ts","../src/generic.ts"],"sourcesContent":["{\n \"name\": \"@vercel/speed-insights\",\n \"version\": \"1.3.1\",\n \"description\": \"Speed Insights is a tool for measuring web performance and providing suggestions for improvement.\",\n \"keywords\": [\n \"speed-insights\",\n \"vercel\"\n ],\n \"repository\": {\n \"url\": \"github:vercel/speed-insights\",\n \"directory\": \"packages/web\"\n },\n \"license\": \"Apache-2.0\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": {\n \"browser\": \"./dist/index.mjs\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./astro\": {\n \"import\": \"./dist/astro/component.ts\"\n },\n \"./next\": {\n \"browser\": \"./dist/next/index.mjs\",\n \"import\": \"./dist/next/index.mjs\",\n \"require\": \"./dist/next/index.js\"\n },\n \"./nuxt\": {\n \"browser\": \"./dist/nuxt/index.mjs\",\n \"import\": \"./dist/nuxt/index.mjs\",\n \"require\": \"./dist/nuxt/index.js\"\n },\n \"./react\": {\n \"browser\": \"./dist/react/index.mjs\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./remix\": {\n \"browser\": \"./dist/remix/index.mjs\",\n \"import\": \"./dist/remix/index.mjs\",\n \"require\": \"./dist/remix/index.js\"\n },\n \"./sveltekit\": {\n \"types\": \"./dist/sveltekit/index.d.ts\",\n \"svelte\": \"./dist/sveltekit/index.mjs\"\n },\n \"./vue\": {\n \"browser\": \"./dist/vue/index.mjs\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"*\": [\n \"dist/index.d.ts\"\n ],\n \"react\": [\n \"dist/react/index.d.ts\"\n ],\n \"next\": [\n \"dist/next/index.d.ts\"\n ],\n \"nuxt\": [\n \"dist/nuxt/index.d.ts\"\n ],\n \"remix\": [\n \"dist/remix/index.d.ts\"\n ],\n \"sveltekit\": [\n \"dist/sveltekit/index.d.ts\"\n ],\n \"vue\": [\n \"dist/vue/index.d.ts\"\n ]\n }\n },\n \"scripts\": {\n \"build\": \"tsup && pnpm copy-astro\",\n \"copy-astro\": \"cp -R src/astro dist/\",\n \"dev\": \"pnpm copy-astro && tsup --watch\",\n \"lint\": \"eslint .\",\n \"lint-fix\": \"eslint . --fix\",\n \"test\": \"vitest\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@remix-run/react\": \"^2.14.0\",\n \"@sveltejs/kit\": \"^2.8.1\",\n \"@swc/core\": \"^1.9.2\",\n \"@testing-library/jest-dom\": \"^6.6.3\",\n \"@testing-library/react\": \"^16.0.1\",\n \"@types/node\": \"^22.9.1\",\n \"@types/react\": \"^18.3.12\",\n \"copyfiles\": \"^2.4.1\",\n \"jsdom\": \"^25.0.1\",\n \"next\": \"^14.0.4\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"svelte\": \"^5.2.7\",\n \"tsup\": \"8.3.5\",\n \"vitest\": \"^2.1.5\",\n \"vue\": \"^3.5.13\",\n \"vue-router\": \"^4.4.5\"\n },\n \"peerDependencies\": {\n \"@sveltejs/kit\": \"^1 || ^2\",\n \"next\": \">= 13\",\n \"react\": \"^18 || ^19 || ^19.0.0-rc\",\n \"svelte\": \">= 4\",\n \"vue\": \"^3\",\n \"vue-router\": \"^4\"\n },\n \"peerDependenciesMeta\": {\n \"@sveltejs/kit\": {\n \"optional\": true\n },\n \"next\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vue-router\": {\n \"optional\": true\n }\n }\n}\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.si) return;\n\n window.si = function a(...params): void {\n (window.siq = window.siq || []).push(params);\n };\n};\n","import type { SpeedInsightsProps } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n try {\n const env = process.env.NODE_ENV;\n if (env === 'development' || env === 'test') {\n return 'development';\n }\n } catch (e) {\n // do nothing, this is okay\n }\n return 'production';\n}\n\nexport function isProduction(): boolean {\n return detectEnvironment() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return detectEnvironment() === 'development';\n}\n\nexport function computeRoute(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (!pathname || !pathParams) {\n return pathname;\n }\n\n let result = pathname;\n try {\n const entries = Object.entries(pathParams);\n // simple keys must be handled first\n for (const [key, value] of entries) {\n if (!Array.isArray(value)) {\n const matcher = turnValueToRegExp(value);\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[${key}]`);\n }\n }\n }\n // array values next\n for (const [key, value] of entries) {\n if (Array.isArray(value)) {\n const matcher = turnValueToRegExp(value.join('/'));\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[...${key}]`);\n }\n }\n }\n return result;\n } catch (e) {\n return pathname;\n }\n}\n\nfunction turnValueToRegExp(value: string): RegExp {\n return new RegExp(`/${escapeRegExp(value)}(?=[/?#]|$)`);\n}\n\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getScriptSrc(\n props: SpeedInsightsProps & { basePath?: string },\n): string {\n if (props.scriptSrc) {\n return props.scriptSrc;\n }\n if (isDevelopment()) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.debug.js';\n }\n if (props.dsn) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.js';\n }\n if (props.basePath) {\n return `${props.basePath}/speed-insights/script.js`;\n }\n return '/_vercel/speed-insights/script.js';\n}\n","import { name as packageName, version } from '../package.json';\nimport { initQueue } from './queue';\nimport type { SpeedInsightsProps, BeforeSendMiddleware } from './types';\nimport { computeRoute, getScriptSrc, isBrowser, isDevelopment } from './utils';\n\n/**\n * Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).\n * @param [props] - Speed Insights options.\n * @param [props.debug] - Whether to enable debug logging in development. Defaults to `true`.\n * @param [props.beforeSend] - A middleware function to modify events before they are sent. Should return the event object or `null` to cancel the event.\n * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.\n * @param [props.route] - The dynamic route of the page.\n * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.\n */\nfunction injectSpeedInsights(\n props: SpeedInsightsProps & {\n framework?: string;\n basePath?: string;\n } = {},\n): {\n setRoute: (route: string | null) => void;\n} | null {\n // When route is null, it means that pages router is not ready yet. Will resolve soon\n if (!isBrowser() || props.route === null) return null;\n\n initQueue();\n\n const src = getScriptSrc(props);\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return null;\n\n if (props.beforeSend) {\n window.si?.('beforeSend', props.beforeSend);\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n script.dataset.sdkn =\n packageName + (props.framework ? `/${props.framework}` : '');\n script.dataset.sdkv = version;\n\n if (props.sampleRate) {\n script.dataset.sampleRate = props.sampleRate.toString();\n }\n if (props.route) {\n script.dataset.route = props.route;\n }\n if (props.endpoint) {\n script.dataset.endpoint = props.endpoint;\n } else if (props.basePath) {\n script.dataset.endpoint = `${props.basePath}/speed-insights/vitals`;\n }\n if (props.dsn) {\n script.dataset.dsn = props.dsn;\n }\n if (isDevelopment() && props.debug === false) {\n script.dataset.debug = 'false';\n }\n\n script.onerror = (): void => {\n // eslint-disable-next-line no-console -- Logging is okay here\n console.log(\n `[Vercel Speed Insights] Failed to load script from ${src}. Please check if any content blockers are enabled and try again.`,\n );\n };\n\n document.head.appendChild(script);\n\n return {\n setRoute: (route: string | null): void => {\n script.dataset.route = route ?? undefined;\n },\n };\n}\n\nexport { injectSpeedInsights, computeRoute };\nexport type { SpeedInsightsProps, BeforeSendMiddleware };\n\n// eslint-disable-next-line import/no-default-export -- Allow default export\nexport default {\n injectSpeedInsights,\n computeRoute,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/queue.ts","../package.json","../src/utils.ts","../src/generic.ts"],"sourcesContent":["export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.si) return;\n\n window.si = function a(...params): void {\n window.siq = window.siq || [];\n window.siq.push(params);\n };\n};\n","{\n \"name\": \"@vercel/speed-insights\",\n \"version\": \"2.0.0\",\n \"description\": \"Speed Insights is a tool for measuring web performance and providing suggestions for improvement.\",\n \"keywords\": [\n \"speed-insights\",\n \"vercel\"\n ],\n \"repository\": {\n \"url\": \"github:vercel/speed-insights\",\n \"directory\": \"packages/web\"\n },\n \"license\": \"Apache-2.0\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": {\n \"browser\": \"./dist/index.mjs\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./astro\": {\n \"import\": \"./dist/astro/component.ts\"\n },\n \"./next\": {\n \"browser\": \"./dist/next/index.mjs\",\n \"import\": \"./dist/next/index.mjs\",\n \"require\": \"./dist/next/index.js\"\n },\n \"./nuxt\": {\n \"import\": \"./dist/nuxt/index.mjs\",\n \"require\": \"./dist/nuxt/index.js\"\n },\n \"./nuxt/runtime\": {\n \"browser\": \"./dist/nuxt/runtime/index.mjs\",\n \"import\": \"./dist/nuxt/runtime/index.mjs\",\n \"require\": \"./dist/nuxt/runtime/index.js\"\n },\n \"./react\": {\n \"browser\": \"./dist/react/index.mjs\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./remix\": {\n \"browser\": \"./dist/remix/index.mjs\",\n \"import\": \"./dist/remix/index.mjs\",\n \"require\": \"./dist/remix/index.js\"\n },\n \"./sveltekit\": {\n \"types\": \"./dist/sveltekit/index.d.ts\",\n \"svelte\": \"./dist/sveltekit/index.mjs\"\n },\n \"./vue\": {\n \"browser\": \"./dist/vue/index.mjs\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"*\": [\n \"dist/index.d.ts\"\n ],\n \"react\": [\n \"dist/react/index.d.ts\"\n ],\n \"next\": [\n \"dist/next/index.d.ts\"\n ],\n \"nuxt\": [\n \"dist/nuxt/index.d.ts\"\n ],\n \"nuxt/runtime\": [\n \"dist/nuxt/runtime/index.d.ts\"\n ],\n \"remix\": [\n \"dist/remix/index.d.ts\"\n ],\n \"sveltekit\": [\n \"dist/sveltekit/index.d.ts\"\n ],\n \"vue\": [\n \"dist/vue/index.d.ts\"\n ]\n }\n },\n \"scripts\": {\n \"build\": \"tsup && pnpm copy-astro\",\n \"copy-astro\": \"cp -R src/astro dist/\",\n \"dev\": \"pnpm copy-astro && tsup --watch\",\n \"test\": \"vitest\"\n },\n \"devDependencies\": {\n \"@nuxt/kit\": \"^4.2.0\",\n \"@nuxt/schema\": \"^4.2.0\",\n \"@remix-run/react\": \"^2.14.0\",\n \"@sveltejs/kit\": \"^2.8.1\",\n \"@swc/core\": \"^1.9.2\",\n \"@testing-library/jest-dom\": \"^6.6.3\",\n \"@testing-library/react\": \"^16.0.1\",\n \"@types/node\": \"^22.9.1\",\n \"@types/react\": \"^18.3.12\",\n \"copyfiles\": \"^2.4.1\",\n \"jsdom\": \"^25.0.1\",\n \"next\": \"^14.0.4\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"svelte\": \"^5.2.7\",\n \"tsup\": \"8.3.5\",\n \"vitest\": \"^2.1.5\",\n \"vue\": \"^3.5.13\",\n \"vue-router\": \"^4.4.5\"\n },\n \"peerDependencies\": {\n \"@sveltejs/kit\": \"^1 || ^2\",\n \"next\": \">= 13\",\n \"nuxt\": \">= 3\",\n \"react\": \"^18 || ^19 || ^19.0.0-rc\",\n \"svelte\": \">= 4\",\n \"vue\": \"^3\",\n \"vue-router\": \"^4\"\n },\n \"peerDependenciesMeta\": {\n \"@sveltejs/kit\": {\n \"optional\": true\n },\n \"next\": {\n \"optional\": true\n },\n \"nuxt\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vue-router\": {\n \"optional\": true\n }\n }\n}\n","import { name as packageName, version } from '../package.json';\nimport type {\n BeforeSend,\n InjectSpeedInsightsProps,\n SpeedInsightsProps,\n} from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n try {\n const env = process.env.NODE_ENV;\n if (env === 'development' || env === 'test') {\n return 'development';\n }\n } catch {\n // do nothing, this is okay\n }\n return 'production';\n}\n\nexport function isProduction(): boolean {\n return detectEnvironment() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return detectEnvironment() === 'development';\n}\n\nexport function computeRoute(\n pathname: string | null,\n pathParams: Record<string, string | string[]> | null,\n): string | null {\n if (!pathname || !pathParams) {\n return pathname;\n }\n\n let result = pathname;\n try {\n const entries = Object.entries(pathParams);\n // simple keys must be handled first\n for (const [key, value] of entries) {\n if (!Array.isArray(value)) {\n const matcher = turnValueToRegExp(value);\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[${key}]`);\n }\n }\n }\n // array values next\n for (const [key, value] of entries) {\n if (Array.isArray(value)) {\n const matcher = turnValueToRegExp(value.join('/'));\n if (matcher.test(result)) {\n result = result.replace(matcher, `/[...${key}]`);\n }\n }\n }\n return result;\n } catch {\n return pathname;\n }\n}\n\nfunction turnValueToRegExp(value: string): RegExp {\n return new RegExp(`/${escapeRegExp(value)}(?=[/?#]|$)`);\n}\n\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction getScriptSrc(\n props: SpeedInsightsProps & { basePath?: string },\n): string {\n if (props.scriptSrc) {\n return makeAbsolute(props.scriptSrc);\n }\n if (isDevelopment()) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.debug.js';\n }\n if (props.dsn) {\n return 'https://va.vercel-scripts.com/v1/speed-insights/script.js';\n }\n if (props.basePath) {\n return makeAbsolute(`${props.basePath}/speed-insights/script.js`);\n }\n return '/_vercel/speed-insights/script.js';\n}\n\nexport function loadProps(\n explicitProps: InjectSpeedInsightsProps,\n confString?: string,\n): {\n src: string;\n beforeSend?: BeforeSend;\n dataset: Record<string, string>;\n} {\n let props = explicitProps;\n if (confString) {\n try {\n props = {\n ...(JSON.parse(confString)\n ?.speedInsights as Partial<SpeedInsightsProps>),\n ...explicitProps,\n };\n } catch {\n // Invalid JSON, use only explicit props\n }\n }\n\n const dataset: Record<string, string> = {\n sdkn: packageName + (props.framework ? `/${props.framework}` : ''),\n sdkv: version,\n };\n\n if (props.sampleRate) {\n dataset.sampleRate = props.sampleRate.toString();\n }\n if (props.route) {\n dataset.route = props.route;\n }\n if (isDevelopment() && props.debug === false) {\n dataset.debug = 'false';\n }\n if (props.dsn) {\n dataset.dsn = props.dsn;\n }\n\n if (props.endpoint) {\n dataset.endpoint = makeAbsolute(props.endpoint);\n } else if (props.basePath) {\n // backward compatibility\n dataset.endpoint = makeAbsolute(`${props.basePath}/speed-insights/vitals`);\n }\n\n return {\n src: getScriptSrc(props),\n beforeSend: props.beforeSend,\n dataset,\n };\n}\n\nfunction makeAbsolute(url: string): string {\n return url.startsWith('http://') ||\n url.startsWith('https://') ||\n url.startsWith('/')\n ? url\n : `/${url}`;\n}\n","import { initQueue } from './queue';\nimport type {\n BeforeSend,\n InjectSpeedInsightsProps,\n SpeedInsightsProps,\n} from './types';\nimport { computeRoute, isBrowser, loadProps } from './utils';\n\n/**\n * Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).\n * @param [props] - Speed Insights options.\n * @param [props.debug] - Whether to enable debug logging in development. Defaults to `true`.\n * @param [props.beforeSend] - A middleware function to modify events before they are sent. Should return the event object or `null` to cancel the event.\n * @param [props.sampleRate] - When setting to 0.5, 50% of the events will be sent to Vercel Speed Insights. Defaults to `1`.\n * @param [props.route] - The dynamic route of the page.\n * @param [props.dsn] - The DSN of the project to send events to. Only required when self-hosting.\n * @param [confString] - an optional JSON string (InjectSpeedInsightsProps) containing the default configuration. Explicit props will take over any provided default.\n */\nfunction injectSpeedInsights(\n props: InjectSpeedInsightsProps = {},\n confString?: string,\n): {\n setRoute: (route: string | null) => void;\n} | null {\n // When route is null, it means that pages router is not ready yet. Will resolve soon\n if (!isBrowser() || props.route === null) return null;\n\n initQueue();\n\n const { beforeSend, src, dataset } = loadProps(props, confString);\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return null;\n\n if (beforeSend) {\n window.si?.('beforeSend', beforeSend);\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n // Apply all dataset attributes from loadProps\n for (const [key, value] of Object.entries(dataset)) {\n script.dataset[key] = value;\n }\n\n script.onerror = (): void => {\n console.log(\n `[Vercel Speed Insights] Failed to load script from ${src}. Please check if any content blockers are enabled and try again.`,\n );\n };\n\n document.head.appendChild(script);\n\n return {\n setRoute: (route: string | null): void => {\n script.dataset.route = route ?? undefined;\n },\n };\n}\n\nexport { injectSpeedInsights, computeRoute };\nexport type { SpeedInsightsProps, BeforeSend as BeforeSendMiddleware };\n\nexport default {\n injectSpeedInsights,\n computeRoute,\n};\n"],"mappings":"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","names":[]}
@@ -2,20 +2,20 @@ interface SpeedInsightsProps {
2
2
  dsn?: string;
3
3
  sampleRate?: number;
4
4
  route?: string | null;
5
- beforeSend?: BeforeSendMiddleware;
5
+ beforeSend?: BeforeSend;
6
6
  debug?: boolean;
7
7
  scriptSrc?: string;
8
8
  endpoint?: string;
9
9
  }
10
10
  type EventTypes = 'vital';
11
- interface Event {
11
+ interface BeforeSendEvent {
12
12
  type: EventTypes;
13
13
  url: string;
14
14
  route?: string;
15
15
  }
16
- type BeforeSendMiddleware = (data: Event) => Event | null | undefined | false;
16
+ type BeforeSend = (event: BeforeSendEvent) => BeforeSendEvent | null | undefined | false;
17
17
  interface Functions {
18
- beforeSend?: BeforeSendMiddleware;
18
+ beforeSend?: BeforeSend;
19
19
  }
20
20
  interface SpeedInsights$1<T extends keyof Functions = keyof Functions> {
21
21
  queue: [T, Functions[T]][];
@@ -29,7 +29,7 @@ declare global {
29
29
  siq?: SpeedInsights$1['queue'];
30
30
  sil?: boolean;
31
31
  /** used by Astro component only */
32
- speedInsightsBeforeSend?: BeforeSendMiddleware;
32
+ speedInsightsBeforeSend?: BeforeSend;
33
33
  }
34
34
  }
35
35