diff --git a/docs/content/scripts/paypal.md b/docs/content/scripts/paypal.md index e6249a1f..0c705476 100644 --- a/docs/content/scripts/paypal.md +++ b/docs/content/scripts/paypal.md @@ -11,10 +11,6 @@ links: icon: i-simple-icons-github to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalButtons.vue size: xs - - label: "" - icon: i-simple-icons-github - to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMarks.vue - size: xs - label: "" icon: i-simple-icons-github to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMessages.vue @@ -24,11 +20,10 @@ links: [PayPal](https://www.paypal.com) is a popular payment gateway that allows you to accept payments online. -Nuxt Scripts provides multiple PayPal features: -- `useScriptPayPal` composable which loads the script `https://www.paypal.com/sdk/js`. -- `ScriptPayPalButtons` component that allows you to embed [PayPal Buttons](https://developer.paypal.com/sdk/js/reference/#buttons) on your site. -- `ScriptPayPalMarks` component that allows you to embed [PayPal Marks](https://developer.paypal.com/sdk/js/reference/#marks) on your site. -- `ScriptPayPalMessages` component that allows you to embed [PayPal Messages](https://developer.paypal.com/studio/checkout/pay-later/us/customize/reference) on your site. +Nuxt Scripts provides PayPal SDK v6 integration: +- `useScriptPayPal` composable which loads the script `https://www.paypal.com/web-sdk/v6/core`. +- `ScriptPayPalButtons` component that initializes the PayPal SDK v6 instance and exposes it via a scoped slot. +- `ScriptPayPalMessages` component that allows you to use [PayPal Messages](https://developer.paypal.com/sdk/js/reference/) on your site. ::script-stats :: @@ -38,13 +33,15 @@ Nuxt Scripts provides multiple PayPal features: ## Types -To use the PayPal with full TypeScript support, you will need +To use PayPal with full TypeScript support, you will need to install the `@paypal/paypal-js` dependency. ```bash pnpm add -D @paypal/paypal-js ``` +The v6 types are available from `@paypal/paypal-js/sdk-v6`. + ### Demo ::code-group @@ -55,34 +52,49 @@ pnpm add -D @paypal/paypal-js ``` diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index f299c6fb..64950f06 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -2,31 +2,42 @@
- - - + :components="['paypal-payments']" + page-type="checkout" + @ready="onReady" + > + + +
diff --git a/scripts/generate-registry-types.ts b/scripts/generate-registry-types.ts index a02eef8a..e374302e 100644 --- a/scripts/generate-registry-types.ts +++ b/scripts/generate-registry-types.ts @@ -236,7 +236,6 @@ const componentToSlug: Record = { ScriptLemonSqueezy: 'lemon-squeezy', ScriptStripePricingTable: 'stripe', ScriptPayPalButtons: 'paypal', - ScriptPayPalMarks: 'paypal', ScriptPayPalMessages: 'paypal', } diff --git a/src/registry-types.json b/src/registry-types.json index 1895ab33..bb16d5c0 100644 --- a/src/registry-types.json +++ b/src/registry-types.json @@ -474,37 +474,27 @@ { "name": "PayPalOptions", "kind": "const", - "code": "export const PayPalOptions = object({\n /**\n * Your PayPal client ID.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#client-id\n */\n clientId: string(),\n /**\n * The buyer's country code (for testing with sandbox).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#buyer-country\n */\n buyerCountry: optional(string()),\n /**\n * Set to `true` to show a \"Pay Now\" button instead of \"Continue\".\n * @default 'true'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#commit\n */\n commit: optional(string()),\n /**\n * The PayPal SDK components to load.\n * @default 'buttons,messages,marks,card-fields,funding-eligibility'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#components\n */\n components: optional(union([string(), array(string())])),\n /**\n * The currency code for the transaction.\n * @default 'USD'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#currency\n */\n currency: optional(string()),\n /**\n * Enable debug mode for the PayPal SDK.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#debug\n */\n debug: optional(union([string(), boolean()])),\n /**\n * Funding sources to disable (e.g., `'credit'`, `'card'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#disable-funding\n */\n disableFunding: optional(union([string(), array(string())])),\n /**\n * Funding sources to enable (e.g., `'venmo'`, `'paylater'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#enable-funding\n */\n enableFunding: optional(union([string(), array(string())])),\n /**\n * The date of integration to ensure backwards-compatible defaults.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#integration-date\n */\n integrationDate: optional(string()),\n /**\n * The transaction intent.\n * @default 'capture'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#intent\n */\n intent: optional(string()),\n /**\n * The locale for the PayPal buttons (e.g., `'en_US'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#locale\n */\n locale: optional(string()),\n /**\n * The merchant ID(s). For multiple merchants, pass an array and the SDK\n * will automatically set `merchant-id` to `*` and use `data-merchant-id`.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#merchant-id\n */\n merchantId: optional(union([string(), array(string())])),\n /**\n * The partner attribution ID for revenue sharing.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#data-partner-attribution-id\n */\n partnerAttributionId: optional(string()),\n /**\n * Enable vault mode to save payment methods for future transactions.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#vault\n */\n vault: optional(union([string(), boolean()])),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n})" + "code": "export const PayPalOptions = union([\n object({\n /**\n * Your PayPal client ID.\n * @see https://developer.paypal.com/sdk/js/reference/\n */\n clientId: string(),\n clientToken: optional(string()),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n }),\n object({\n clientId: optional(string()),\n /**\n * A server-generated client token for authentication.\n * @see https://docs.paypal.ai/payments/methods/paypal/sdk/js/v6/paypal-checkout\n */\n clientToken: string(),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n }),\n])" }, { "name": "PayPalApi", "kind": "interface", - "code": "export interface PayPalApi {\n paypal: PayPalNamespace\n}" + "code": "export interface PayPalApi {\n paypal: PayPalV6Namespace\n}" }, { "name": "ScriptPayPalButtonsProps", "kind": "interface", - "code": "interface ScriptPayPalButtonsProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal buttons.\n */\n buttonOptions?: PayPalButtonsComponentOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial\n /**\n * Disables the paypal buttons.\n */\n disabled?: boolean\n}" + "code": "interface ScriptPayPalButtonsProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * Client ID or client token for PayPal SDK v6 authentication.\n */\n clientId?: string\n /**\n * Server-generated client token for SDK v6.\n */\n clientToken?: string\n /**\n * The v6 SDK components to load.\n * @default ['paypal-payments']\n */\n components?: Components[]\n /**\n * The page type context hint.\n */\n pageType?: PageTypes\n /**\n * The locale for the SDK (BCP-47 code).\n */\n locale?: string\n /**\n * The merchant ID(s).\n */\n merchantId?: string | string[]\n /**\n * Partner attribution ID for revenue sharing.\n */\n partnerAttributionId?: string\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial\n}" }, { "name": "ScriptPayPalButtonsDefaults", "kind": "const", - "code": "const ScriptPayPalButtonsDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"disabled\": \"false\",\n \"buttonOptions\": \"() => ({})\",\n \"paypalScriptOptions\": \"() => ({})\"\n}" - }, - { - "name": "ScriptPayPalMarksProps", - "kind": "interface", - "code": "interface ScriptPayPalMarksProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal marks.\n */\n marksOptions?: PayPalMarksComponentOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial\n}" - }, - { - "name": "ScriptPayPalMarksDefaults", - "kind": "const", - "code": "const ScriptPayPalMarksDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"marksOptions\": \"() => ({})\",\n \"paypalScriptOptions\": \"() => ({})\"\n}" + "code": "const ScriptPayPalButtonsDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"components\": \"() => ['paypal-payments'] as Components[]\",\n \"paypalScriptOptions\": \"() => ({})\"\n}" }, { "name": "ScriptPayPalMessagesProps", "kind": "interface", - "code": "interface ScriptPayPalMessagesProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal buttons.\n */\n messagesOptions?: PayPalMessagesComponentOptions\n /**\n * The merchant id for the paypal script.\n */\n merchantId?: string\n /**\n * The partner attribution id for the paypal script.\n */\n partnerAttributionId?: string\n /**\n * The options for the paypal scipt.\n */\n paypalScriptOptions?: Partial\n}" + "code": "interface ScriptPayPalMessagesProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * Client ID or client token for PayPal SDK v6 authentication.\n */\n clientId?: string\n /**\n * Server-generated client token for SDK v6.\n */\n clientToken?: string\n /**\n * The merchant ID for the paypal script.\n */\n merchantId?: string | string[]\n /**\n * The partner attribution ID.\n */\n partnerAttributionId?: string\n /**\n * The page type context hint.\n */\n pageType?: PageTypes\n /**\n * The locale for the SDK (BCP-47 code).\n */\n locale?: string\n /**\n * Options for the PayPal Messages session.\n */\n messagesOptions?: PayPalMessagesOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial\n}" }, { "name": "ScriptPayPalMessagesDefaults", @@ -795,4 +785,4 @@ "code": "interface ScriptCarbonAdsProps {\n serve: string\n placement: string\n format: string\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n}" } ] -} \ No newline at end of file +} diff --git a/src/runtime/components/ScriptPayPalButtons.vue b/src/runtime/components/ScriptPayPalButtons.vue index 74e642b7..0d1755c8 100644 --- a/src/runtime/components/ScriptPayPalButtons.vue +++ b/src/runtime/components/ScriptPayPalButtons.vue @@ -1,22 +1,16 @@ diff --git a/src/runtime/components/ScriptPayPalMarks.vue b/src/runtime/components/ScriptPayPalMarks.vue deleted file mode 100644 index 5742ddf8..00000000 --- a/src/runtime/components/ScriptPayPalMarks.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - diff --git a/src/runtime/components/ScriptPayPalMessages.vue b/src/runtime/components/ScriptPayPalMessages.vue index 54074184..55b455f8 100644 --- a/src/runtime/components/ScriptPayPalMessages.vue +++ b/src/runtime/components/ScriptPayPalMessages.vue @@ -1,10 +1,18 @@ diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index ad86970e..e2b07b40 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -1,13 +1,12 @@ import type { RegistryScriptInput } from '#nuxt-scripts/types' -import type { PayPalNamespace } from '@paypal/paypal-js' -import { withQuery } from 'ufo' +import type { PayPalV6Namespace } from '@paypal/paypal-js/sdk-v6' import { useRegistryScript } from '../utils' import { PayPalOptions } from './schemas' export { PayPalOptions } export interface PayPalApi { - paypal: PayPalNamespace + paypal: PayPalV6Namespace } declare global { @@ -19,61 +18,17 @@ export type PayPalInput = RegistryScriptInput export function useScriptPayPal(_options?: PayPalInput) { return useRegistryScript('paypal', (options) => { - let dataMerchantId - - if (Array.isArray(options?.merchantId) && options?.merchantId.length > 1) { - dataMerchantId = JSON.stringify(options.merchantId) - options.merchantId = '*' - } - - if (Array.isArray(options?.components)) { - options.components = options.components.join(',') - } - - if (Array.isArray(options?.disableFunding)) { - options.disableFunding = options.disableFunding.join(',') - } - - if (Array.isArray(options?.enableFunding)) { - options.enableFunding = options.enableFunding.join(',') - } - if (options?.sandbox === undefined) { options.sandbox = import.meta.dev } - let components = ['buttons', 'messages', 'marks', 'card-fields', 'funding-eligibility'].join(',') - - if (options.components) { - if (Array.isArray(options.components)) { - components = options.components.join(',') - } - else { - components = options.components - } - } - return { scriptInput: { - 'src': withQuery(options.sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js', { - 'client-id': options.clientId, - 'buyer-country': options.buyerCountry, - 'commit': options.commit, - 'components': components, - 'currency': options.currency, - 'debug': options.debug, - 'disable-funding': options.disableFunding, - 'enable-funding': options.enableFunding, - 'integration-date': options.integrationDate, - 'intent': options.intent, - 'locale': options.locale, - 'vault': options.vault, - }), - 'data-merchant-id': dataMerchantId, - 'data-partner-attribution-id': options.partnerAttributionId, // TODO: maybe nuxt specific default + src: options.sandbox + ? 'https://www.sandbox.paypal.com/web-sdk/v6/core' + : 'https://www.paypal.com/web-sdk/v6/core', }, schema: import.meta.dev ? PayPalOptions : undefined, - // trigger: 'client', scriptOptions: { use() { return { diff --git a/src/runtime/registry/schemas.ts b/src/runtime/registry/schemas.ts index f388575e..d37e088a 100644 --- a/src/runtime/registry/schemas.ts +++ b/src/runtime/registry/schemas.ts @@ -584,87 +584,32 @@ export const NpmOptions = object({ provider: optional(union([literal('jsdelivr'), literal('cdnjs'), literal('unpkg')])), }) -export const PayPalOptions = object({ - /** - * Your PayPal client ID. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#client-id - */ - clientId: string(), - /** - * The buyer's country code (for testing with sandbox). - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#buyer-country - */ - buyerCountry: optional(string()), - /** - * Set to `true` to show a "Pay Now" button instead of "Continue". - * @default 'true' - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#commit - */ - commit: optional(string()), - /** - * The PayPal SDK components to load. - * @default 'buttons,messages,marks,card-fields,funding-eligibility' - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#components - */ - components: optional(union([string(), array(string())])), - /** - * The currency code for the transaction. - * @default 'USD' - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#currency - */ - currency: optional(string()), - /** - * Enable debug mode for the PayPal SDK. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#debug - */ - debug: optional(union([string(), boolean()])), - /** - * Funding sources to disable (e.g., `'credit'`, `'card'`). - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#disable-funding - */ - disableFunding: optional(union([string(), array(string())])), - /** - * Funding sources to enable (e.g., `'venmo'`, `'paylater'`). - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#enable-funding - */ - enableFunding: optional(union([string(), array(string())])), - /** - * The date of integration to ensure backwards-compatible defaults. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#integration-date - */ - integrationDate: optional(string()), - /** - * The transaction intent. - * @default 'capture' - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#intent - */ - intent: optional(string()), - /** - * The locale for the PayPal buttons (e.g., `'en_US'`). - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#locale - */ - locale: optional(string()), - /** - * The merchant ID(s). For multiple merchants, pass an array and the SDK - * will automatically set `merchant-id` to `*` and use `data-merchant-id`. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#merchant-id - */ - merchantId: optional(union([string(), array(string())])), - /** - * The partner attribution ID for revenue sharing. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#data-partner-attribution-id - */ - partnerAttributionId: optional(string()), - /** - * Enable vault mode to save payment methods for future transactions. - * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#vault - */ - vault: optional(union([string(), boolean()])), - /** - * Use the PayPal sandbox environment. Defaults to `true` in development. - */ - sandbox: optional(boolean()), -}) +export const PayPalOptions = union([ + object({ + /** + * Your PayPal client ID. + * @see https://developer.paypal.com/sdk/js/reference/ + */ + clientId: string(), + clientToken: optional(string()), + /** + * Use the PayPal sandbox environment. Defaults to `true` in development. + */ + sandbox: optional(boolean()), + }), + object({ + clientId: optional(string()), + /** + * A server-generated client token for authentication. + * @see https://docs.paypal.ai/payments/methods/paypal/sdk/js/v6/paypal-checkout + */ + clientToken: string(), + /** + * Use the PayPal sandbox environment. Defaults to `true` in development. + */ + sandbox: optional(boolean()), + }), +]) export const PostHogOptions = object({ /** diff --git a/src/runtime/types.ts b/src/runtime/types.ts index 25a8a19c..a7a3a4ce 100644 --- a/src/runtime/types.ts +++ b/src/runtime/types.ts @@ -3,7 +3,7 @@ import type { Script, } from '@unhead/vue/types' import type { Import } from 'unimport' -import type { InferInput, ObjectSchema, ValiError } from 'valibot' +import type { InferInput, ObjectSchema, UnionSchema, ValiError } from 'valibot' import type { ComputedRef, Ref } from 'vue' import type { ClarityInput } from './registry/clarity' import type { CloudflareWebAnalyticsInput } from './registry/cloudflare-web-analytics' @@ -205,7 +205,7 @@ export type EmptyOptionsSchema = typeof _emptyOptions type ScriptInput = Script -export type InferIfSchema = T extends ObjectSchema ? InferInput : T +export type InferIfSchema = T extends ObjectSchema | UnionSchema ? InferInput : T export type RegistryScriptInput< T = EmptyOptionsSchema, Bundelable extends boolean = true, diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 36d0af82..1e22e9b5 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -8,7 +8,7 @@ import type { UseScriptContext, } from '#nuxt-scripts/types' import type { UseScriptInput } from '@unhead/vue' -import type { GenericSchema, InferInput, ObjectSchema, ValiError } from 'valibot' +import type { GenericSchema, InferInput, ObjectSchema, UnionSchema, ValiError } from 'valibot' import { parse } from '#nuxt-scripts-validator' import { defu } from 'defu' import { useRuntimeConfig } from 'nuxt/app' @@ -33,7 +33,7 @@ function validateScriptInputSchema(key: string, schema: type OptionsFn = (options: InferIfSchema, ctx: { scriptInput?: UseScriptInput & { src?: string } }) => ({ scriptInput?: UseScriptInput scriptOptions?: NuxtUseScriptOptions - schema?: O extends ObjectSchema ? O : undefined + schema?: O extends ObjectSchema | UnionSchema ? O : undefined clientInit?: () => void | Promise scriptMode?: 'external' | 'npm' // NEW: external = CDN script (default), npm = NPM package only }) @@ -122,8 +122,9 @@ export function useRegistryScript, O = Em scriptOptions.devtools = defu(scriptOptions.devtools, { registryKey, loadedFrom }) if (options.schema) { const registryMeta: Record = {} - for (const k in options.schema.entries) { - if (options.schema.entries[k].type !== 'optional') { + const entries = 'entries' in options.schema ? options.schema.entries as Record : undefined + for (const k in entries) { + if (entries[k]?.type !== 'optional') { registryMeta[k] = String(userOptions[k as any as keyof typeof userOptions]) } } diff --git a/src/script-meta.ts b/src/script-meta.ts index 6612173c..b993ef79 100644 --- a/src/script-meta.ts +++ b/src/script-meta.ts @@ -121,7 +121,7 @@ export const scriptMeta: Record = { trackedData: ['transactions'], }, payPal: { - urls: ['https://www.paypal.com/sdk/js?client-id=AbFpjEMbYxL5HLLTyiOXSXp1VMwRRHWpQp3x-P8tPQVSCC-nNFINJ-_v-d8VVyy2nJfW2XuivLY0ITeO'], + urls: ['https://www.paypal.com/web-sdk/v6/core'], trackedData: ['transactions'], }, diff --git a/src/script-sizes.json b/src/script-sizes.json index c75c660a..ccac9c1d 100644 --- a/src/script-sizes.json +++ b/src/script-sizes.json @@ -2,14 +2,14 @@ "plausibleAnalytics": { "totalTransferKb": 1.9, "totalDecodedKb": 2.9, - "loadTimeMs": 90, + "loadTimeMs": 79, "scripts": [ { "url": "https://plausible.io/js/script.js", "transferKb": 1.9, "decodedKb": 2.9, "encoding": "zstd", - "durationMs": 90, + "durationMs": 79, "initiatorType": "script", "protocol": "unknown" } @@ -18,14 +18,14 @@ "cloudflareWebAnalytics": { "totalTransferKb": 10.8, "totalDecodedKb": 30.4, - "loadTimeMs": 369, + "loadTimeMs": 100, "scripts": [ { "url": "https://static.cloudflareinsights.com/beacon.min.js", "transferKb": 10.8, "decodedKb": 30.4, "encoding": "gzip", - "durationMs": 369, + "durationMs": 100, "initiatorType": "script", "protocol": "unknown" } @@ -40,23 +40,23 @@ "fathomAnalytics": { "totalTransferKb": 3, "totalDecodedKb": 6.7, - "loadTimeMs": 298, + "loadTimeMs": 340, "scripts": [ { "url": "https://cdn.usefathom.com/script.js", "transferKb": 2.7, "decodedKb": 6.7, "encoding": "zstd", - "durationMs": 79, + "durationMs": 340, "initiatorType": "script", "protocol": "unknown" }, { - "url": "https://cdn.usefathom.com/?h=http%3A%2F%2F127.0.0.1&p=%2FfathomAnalytics&r=&sid=null&qs=%7B%7D&cid=89161488", + "url": "https://cdn.usefathom.com/?h=http%3A%2F%2F127.0.0.1&p=%2FfathomAnalytics&r=&sid=null&qs=%7B%7D&cid=22238330", "transferKb": 0.3, "decodedKb": 0, "encoding": "none", - "durationMs": 298, + "durationMs": 304, "initiatorType": "img", "protocol": "unknown" } @@ -65,14 +65,14 @@ "matomoAnalytics": { "totalTransferKb": 60.4, "totalDecodedKb": 218.6, - "loadTimeMs": 136, + "loadTimeMs": 101, "scripts": [ { "url": "https://cdn.matomo.cloud/demo.matomo.cloud/matomo.js", "transferKb": 60.4, "decodedKb": 218.6, "encoding": "br", - "durationMs": 136, + "durationMs": 101, "initiatorType": "script", "protocol": "unknown" } @@ -81,14 +81,14 @@ "rybbitAnalytics": { "totalTransferKb": 9, "totalDecodedKb": 25.3, - "loadTimeMs": 1118, + "loadTimeMs": 1127, "scripts": [ { "url": "https://app.rybbit.io/api/script.js", "transferKb": 9, "decodedKb": 25.3, "encoding": "zstd", - "durationMs": 1118, + "durationMs": 1127, "initiatorType": "script", "protocol": "unknown" } @@ -97,14 +97,14 @@ "databuddyAnalytics": { "totalTransferKb": 10.6, "totalDecodedKb": 29.2, - "loadTimeMs": 79, + "loadTimeMs": 83, "scripts": [ { "url": "https://cdn.databuddy.cc/databuddy.js", "transferKb": 10.6, "decodedKb": 29.2, "encoding": "zstd", - "durationMs": 79, + "durationMs": 83, "initiatorType": "script", "protocol": "unknown" } @@ -113,14 +113,14 @@ "segment": { "totalTransferKb": 29.4, "totalDecodedKb": 107, - "loadTimeMs": 540, + "loadTimeMs": 597, "scripts": [ { "url": "https://cdn.segment.com/analytics.js/v1/KBXOGxgqMFjm2mxtJDJg0iDn5AnGYb9C/analytics.min.js", "transferKb": 28.2, "decodedKb": 106.4, "encoding": "br", - "durationMs": 540, + "durationMs": 597, "initiatorType": "script", "protocol": "unknown" }, @@ -129,7 +129,7 @@ "transferKb": 1.2, "decodedKb": 0.6, "encoding": "none", - "durationMs": 98, + "durationMs": 83, "initiatorType": "fetch", "protocol": "unknown" } @@ -138,14 +138,14 @@ "googleAnalytics": { "totalTransferKb": 151.5, "totalDecodedKb": 446, - "loadTimeMs": 493, + "loadTimeMs": 537, "scripts": [ { "url": "https://www.googletagmanager.com/gtag/js?id=G-TR58L0EF8P", "transferKb": 151.5, "decodedKb": 446, "encoding": "zstd", - "durationMs": 493, + "durationMs": 537, "initiatorType": "script", "protocol": "unknown" } @@ -154,14 +154,14 @@ "umamiAnalytics": { "totalTransferKb": 2.4, "totalDecodedKb": 2.6, - "loadTimeMs": 82, + "loadTimeMs": 99, "scripts": [ { "url": "https://cloud.umami.is/script.js", "transferKb": 2.4, "decodedKb": 2.6, "encoding": "br", - "durationMs": 82, + "durationMs": 99, "initiatorType": "script", "protocol": "unknown" } @@ -170,14 +170,14 @@ "metaPixel": { "totalTransferKb": 93.9, "totalDecodedKb": 353.3, - "loadTimeMs": 133, + "loadTimeMs": 123, "scripts": [ { "url": "https://connect.facebook.net/en_US/fbevents.js", "transferKb": 93.9, "decodedKb": 353.3, "encoding": "gzip", - "durationMs": 133, + "durationMs": 123, "initiatorType": "script", "protocol": "h2" } @@ -186,14 +186,14 @@ "xPixel": { "totalTransferKb": 9.5, "totalDecodedKb": 32.3, - "loadTimeMs": 71, + "loadTimeMs": 72, "scripts": [ { "url": "https://static.ads-twitter.com/uwt.js", "transferKb": 9.5, "decodedKb": 32.3, "encoding": "gzip", - "durationMs": 71, + "durationMs": 72, "initiatorType": "script", "protocol": "unknown" } @@ -202,14 +202,14 @@ "tikTokPixel": { "totalTransferKb": 2.7, "totalDecodedKb": 7.6, - "loadTimeMs": 293, + "loadTimeMs": 473, "scripts": [ { "url": "https://analytics.tiktok.com/i18n/pixel/events.js", "transferKb": 2.7, "decodedKb": 7.6, "encoding": "gzip", - "durationMs": 293, + "durationMs": 473, "initiatorType": "script", "protocol": "unknown" } @@ -218,14 +218,14 @@ "snapchatPixel": { "totalTransferKb": 24.7, "totalDecodedKb": 57.4, - "loadTimeMs": 620, + "loadTimeMs": 569, "scripts": [ { "url": "https://sc-static.net/scevent.min.js", "transferKb": 24.7, "decodedKb": 57.4, "encoding": "gzip", - "durationMs": 620, + "durationMs": 569, "initiatorType": "script", "protocol": "unknown" } @@ -234,30 +234,30 @@ "redditPixel": { "totalTransferKb": 20, "totalDecodedKb": 79.6, - "loadTimeMs": 126, + "loadTimeMs": 122, "scripts": [ { "url": "https://www.redditstatic.com/ads/pixel.js", "transferKb": 20, "decodedKb": 79.6, "encoding": "gzip", - "durationMs": 126, + "durationMs": 122, "initiatorType": "script", "protocol": "unknown" } ] }, "googleAdsense": { - "totalTransferKb": 63.2, - "totalDecodedKb": 192.5, - "loadTimeMs": 392, + "totalTransferKb": 63.4, + "totalDecodedKb": 193.1, + "loadTimeMs": 401, "scripts": [ { "url": "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", - "transferKb": 63.2, - "decodedKb": 192.5, + "transferKb": 63.4, + "decodedKb": 193.1, "encoding": "br", - "durationMs": 392, + "durationMs": 401, "initiatorType": "script", "protocol": "h2" } @@ -266,14 +266,14 @@ "carbonAds": { "totalTransferKb": 10.8, "totalDecodedKb": 37.1, - "loadTimeMs": 85, + "loadTimeMs": 55, "scripts": [ { "url": "https://cdn.carbonads.com/carbon.js?serve=CW7DTKJL&placement=unlighthousedev&format=cover", "transferKb": 10.8, "decodedKb": 37.1, "encoding": "gzip", - "durationMs": 85, + "durationMs": 55, "initiatorType": "script", "protocol": "unknown" } @@ -282,14 +282,14 @@ "hotjar": { "totalTransferKb": 6.1, "totalDecodedKb": 14.7, - "loadTimeMs": 359, + "loadTimeMs": 346, "scripts": [ { "url": "https://static.hotjar.com/c/hotjar-3925006.js?sv=6", "transferKb": 6.1, "decodedKb": 14.7, "encoding": "br", - "durationMs": 359, + "durationMs": 346, "initiatorType": "script", "protocol": "unknown" } @@ -298,30 +298,30 @@ "clarity": { "totalTransferKb": 0.8, "totalDecodedKb": 0.6, - "loadTimeMs": 5379, + "loadTimeMs": 365, "scripts": [ { "url": "https://www.clarity.ms/tag/mqk2m9dr2v", "transferKb": 0.8, "decodedKb": 0.6, "encoding": "none", - "durationMs": 5379, + "durationMs": 365, "initiatorType": "script", "protocol": "unknown" } ] }, "googleTagManager": { - "totalTransferKb": 106.2, - "totalDecodedKb": 295.2, - "loadTimeMs": 479, + "totalTransferKb": 106.4, + "totalDecodedKb": 295.9, + "loadTimeMs": 483, "scripts": [ { "url": "https://www.googletagmanager.com/gtm.js?id=GTM-MWW974PF", - "transferKb": 106.2, - "decodedKb": 295.2, + "transferKb": 106.4, + "decodedKb": 295.9, "encoding": "zstd", - "durationMs": 479, + "durationMs": 483, "initiatorType": "script", "protocol": "unknown" } @@ -330,14 +330,14 @@ "intercom": { "totalTransferKb": 3.6, "totalDecodedKb": 7.4, - "loadTimeMs": 701, + "loadTimeMs": 735, "scripts": [ { "url": "https://widget.intercom.io/widget/akg5rmxb", "transferKb": 3.6, "decodedKb": 7.4, "encoding": "gzip", - "durationMs": 701, + "durationMs": 735, "initiatorType": "script", "protocol": "unknown" } @@ -346,30 +346,30 @@ "crisp": { "totalTransferKb": 3.3, "totalDecodedKb": 7.6, - "loadTimeMs": 142, + "loadTimeMs": 92, "scripts": [ { "url": "https://client.crisp.chat/l.js", "transferKb": 3.3, "decodedKb": 7.6, "encoding": "br", - "durationMs": 142, + "durationMs": 92, "initiatorType": "script", "protocol": "unknown" } ] }, "stripe": { - "totalTransferKb": 213.2, + "totalTransferKb": 212.4, "totalDecodedKb": 916.7, - "loadTimeMs": 162, + "loadTimeMs": 170, "scripts": [ { "url": "https://js.stripe.com/v3/", - "transferKb": 213.2, + "transferKb": 212.4, "decodedKb": 916.7, "encoding": "br", - "durationMs": 162, + "durationMs": 170, "initiatorType": "script", "protocol": "h2" } @@ -378,71 +378,62 @@ "lemonSqueezy": { "totalTransferKb": 1.8, "totalDecodedKb": 3.8, - "loadTimeMs": 143, + "loadTimeMs": 84, "scripts": [ { "url": "https://assets.lemonsqueezy.com/lemon.js", "transferKb": 1.8, "decodedKb": 3.8, "encoding": "br", - "durationMs": 143, + "durationMs": 84, "initiatorType": "script", "protocol": "unknown" } ] }, "payPal": { - "totalTransferKb": 94.1, - "totalDecodedKb": 355.3, - "loadTimeMs": 904, + "totalTransferKb": 49.6, + "totalDecodedKb": 150.9, + "loadTimeMs": 182, "scripts": [ { - "url": "https://www.paypal.com/sdk/js?client-id=AbFpjEMbYxL5HLLTyiOXSXp1VMwRRHWpQp3x-P8tPQVSCC-nNFINJ-_v-d8VVyy2nJfW2XuivLY0ITeO", - "transferKb": 93.3, - "decodedKb": 354.3, + "url": "https://www.paypal.com/web-sdk/v6/core", + "transferKb": 49.6, + "decodedKb": 150.9, "encoding": "gzip", - "durationMs": 904, + "durationMs": 182, "initiatorType": "script", "protocol": "unknown" - }, - { - "url": "https://www.sandbox.paypal.com/xoplatform/logger/api/logger?disableSetCookie=true", - "transferKb": 0.8, - "decodedKb": 1, - "encoding": "br", - "durationMs": 650, - "initiatorType": "xmlhttprequest", - "protocol": "unknown" } ] }, "vimeoPlayer": { "totalTransferKb": 8.9, "totalDecodedKb": 23.8, - "loadTimeMs": 98, + "loadTimeMs": 107, "scripts": [ { "url": "https://player.vimeo.com/api/player.js", "transferKb": 8.9, "decodedKb": 23.8, "encoding": "gzip", - "durationMs": 98, + "durationMs": 107, "initiatorType": "script", "protocol": "unknown" } ] }, "youTubePlayer": { - "totalTransferKb": 13.6, + "totalTransferKb": 14, "totalDecodedKb": 32.4, - "loadTimeMs": 282, + "loadTimeMs": 293, "scripts": [ { "url": "https://www.youtube.com/iframe_api", - "transferKb": 3, + "transferKb": 3.4, "decodedKb": 1, "encoding": "br", - "durationMs": 282, + "durationMs": 293, "initiatorType": "script", "protocol": "unknown" }, @@ -451,7 +442,7 @@ "transferKb": 10.6, "decodedKb": 31.4, "encoding": "br", - "durationMs": 19, + "durationMs": 20, "initiatorType": "script", "protocol": "unknown" } @@ -472,14 +463,14 @@ "googleRecaptcha": { "totalTransferKb": 360.6, "totalDecodedKb": 844.4, - "loadTimeMs": 291, + "loadTimeMs": 252, "scripts": [ { "url": "https://www.google.com/recaptcha/api.js", "transferKb": 1.5, "decodedKb": 1.6, "encoding": "gzip", - "durationMs": 291, + "durationMs": 252, "initiatorType": "script", "protocol": "unknown" }, @@ -488,7 +479,7 @@ "transferKb": 359.1, "decodedKb": 842.8, "encoding": "gzip", - "durationMs": 248, + "durationMs": 227, "initiatorType": "script", "protocol": "h2" } @@ -497,14 +488,14 @@ "googleSignIn": { "totalTransferKb": 91.8, "totalDecodedKb": 246.7, - "loadTimeMs": 1114, + "loadTimeMs": 916, "scripts": [ { "url": "https://accounts.google.com/gsi/client", "transferKb": 91.8, "decodedKb": 246.7, "encoding": "gzip", - "durationMs": 1114, + "durationMs": 916, "initiatorType": "script", "protocol": "unknown" }