@nuxt/scripts 1.0.6 → 1.1.1

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 (84) hide show
  1. package/dist/devtools-client/200.html +1 -1
  2. package/dist/devtools-client/404.html +1 -1
  3. package/dist/devtools-client/_nuxt/B-0LGYiZ.js +188 -0
  4. package/dist/devtools-client/_nuxt/BHdEFiuu.js +1 -0
  5. package/dist/devtools-client/_nuxt/CZLtBO2f.js +1 -0
  6. package/dist/devtools-client/_nuxt/CpUjVpvL.js +1 -0
  7. package/dist/devtools-client/_nuxt/CpodaK4k.js +1 -0
  8. package/dist/devtools-client/_nuxt/DkOU4Aaf.js +1 -0
  9. package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
  10. package/dist/devtools-client/_nuxt/builds/meta/7cf30d77-8399-4375-9a20-302132331b02.json +1 -0
  11. package/dist/devtools-client/_nuxt/d96VI30H.js +1 -0
  12. package/dist/devtools-client/_nuxt/{entry.XOvcedFq.css → entry.DFx-MLUa.css} +1 -1
  13. package/dist/devtools-client/_nuxt/error-404.aORtIbIE.css +1 -0
  14. package/dist/devtools-client/_nuxt/error-500.FkAdJQFV.css +1 -0
  15. package/dist/devtools-client/_nuxt/{first-party.C8Ha4JLM.css → first-party.D_SBdnka.css} +1 -1
  16. package/dist/devtools-client/_nuxt/index.DIj4bh55.css +1 -0
  17. package/dist/devtools-client/_nuxt/{registry.B9lnjF_b.css → registry.CDbTq1x3.css} +1 -1
  18. package/dist/devtools-client/docs/index.html +1 -1
  19. package/dist/devtools-client/first-party/index.html +1 -1
  20. package/dist/devtools-client/index.html +1 -1
  21. package/dist/devtools-client/registry/index.html +1 -1
  22. package/dist/module.d.mts +12 -2
  23. package/dist/module.d.ts +12 -2
  24. package/dist/module.json +1 -1
  25. package/dist/module.mjs +271 -35
  26. package/dist/registry.mjs +76 -5
  27. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +36 -5
  28. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.d.vue.ts +2 -2
  29. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue.d.ts +2 -2
  30. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.d.vue.ts +2 -2
  31. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue.d.ts +2 -2
  32. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.d.vue.ts +2 -2
  33. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue.d.ts +2 -2
  34. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.d.vue.ts +2 -2
  35. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue.d.ts +2 -2
  36. package/dist/runtime/components/ScriptCalendlyInlineWidget.d.vue.ts +59 -0
  37. package/dist/runtime/components/ScriptCalendlyInlineWidget.vue +79 -0
  38. package/dist/runtime/components/ScriptCalendlyInlineWidget.vue.d.ts +59 -0
  39. package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +1 -1
  40. package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +1 -1
  41. package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +1 -1
  42. package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +1 -1
  43. package/dist/runtime/composables/useScript.js +48 -0
  44. package/dist/runtime/debug.d.ts +1 -0
  45. package/dist/runtime/debug.js +1 -0
  46. package/dist/runtime/devtools-standalone-bridge.client.js +3 -1
  47. package/dist/runtime/logger.js +4 -0
  48. package/dist/runtime/registry/_gcm-consent.d.ts +14 -0
  49. package/dist/runtime/registry/_gcm-consent.js +24 -0
  50. package/dist/runtime/registry/ahrefs-analytics.d.ts +39 -0
  51. package/dist/runtime/registry/ahrefs-analytics.js +18 -0
  52. package/dist/runtime/registry/calendly.d.ts +76 -0
  53. package/dist/runtime/registry/calendly.js +63 -0
  54. package/dist/runtime/registry/google-analytics.d.ts +5 -6
  55. package/dist/runtime/registry/google-analytics.js +4 -10
  56. package/dist/runtime/registry/google-tag-manager.d.ts +5 -6
  57. package/dist/runtime/registry/google-tag-manager.js +13 -18
  58. package/dist/runtime/registry/linkedin-insight.d.ts +35 -0
  59. package/dist/runtime/registry/linkedin-insight.js +49 -0
  60. package/dist/runtime/registry/schemas.d.ts +124 -0
  61. package/dist/runtime/registry/schemas.js +115 -2
  62. package/dist/runtime/registry/tiktok-pixel.d.ts +79 -14
  63. package/dist/runtime/registry/tiktok-pixel.js +62 -28
  64. package/dist/runtime/registry/usercentrics.d.ts +85 -0
  65. package/dist/runtime/registry/usercentrics.js +54 -0
  66. package/dist/runtime/server/proxy-handler.js +13 -4
  67. package/dist/runtime/types.d.ts +36 -1
  68. package/dist/runtime/utils.d.ts +8 -2
  69. package/dist/runtime/utils.js +5 -1
  70. package/dist/stats.mjs +19 -0
  71. package/dist/types-source.mjs +291 -11
  72. package/dist/types.d.mts +1 -1
  73. package/package.json +9 -6
  74. package/dist/devtools-client/_nuxt/CZp-OuKP.js +0 -1
  75. package/dist/devtools-client/_nuxt/Djr8-0jV.js +0 -1
  76. package/dist/devtools-client/_nuxt/DtB6K90V.js +0 -188
  77. package/dist/devtools-client/_nuxt/DyyF3uw_.js +0 -1
  78. package/dist/devtools-client/_nuxt/GzJXdFDa.js +0 -1
  79. package/dist/devtools-client/_nuxt/W-xcwSaJ.js +0 -1
  80. package/dist/devtools-client/_nuxt/YlRaZkPa.js +0 -1
  81. package/dist/devtools-client/_nuxt/builds/meta/57f43375-6c5e-40af-a5bc-9479e5286aac.json +0 -1
  82. package/dist/devtools-client/_nuxt/error-404.DsZYSkA7.css +0 -1
  83. package/dist/devtools-client/_nuxt/error-500.Cqipl6_j.css +0 -1
  84. package/dist/devtools-client/_nuxt/index.DZD1lwyI.css +0 -1
@@ -1,3 +1,22 @@
1
+ export declare const gcmConsentState: import("valibot").ObjectSchema<{
2
+ readonly ad_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
3
+ readonly ad_user_data: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
4
+ readonly ad_personalization: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
5
+ readonly analytics_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
6
+ readonly functionality_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
7
+ readonly personalization_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
8
+ readonly security_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
9
+ readonly wait_for_update: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
10
+ readonly region: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
11
+ }, undefined>;
12
+ export declare const AhrefsAnalyticsOptions: import("valibot").ObjectSchema<{
13
+ /**
14
+ * Your Ahrefs Web Analytics project key. Set as the `data-key` attribute
15
+ * on the loaded `analytics.js` script tag.
16
+ * @see https://ahrefs.com/web-analytics
17
+ */
18
+ readonly key: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>;
19
+ }, undefined>;
1
20
  export declare const BlueskyEmbedOptions: import("valibot").ObjectSchema<{
2
21
  /**
3
22
  * The Bluesky post URL to embed.
@@ -808,6 +827,105 @@ export declare const BingUetOptions: import("valibot").ObjectSchema<{
808
827
  readonly ad_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
809
828
  }, undefined>, undefined>;
810
829
  }, undefined>;
830
+ export declare const LinkedInInsightOptions: import("valibot").ObjectSchema<{
831
+ /**
832
+ * Your LinkedIn Insight Tag Partner ID, or an array of Partner IDs to push
833
+ * onto window._linkedin_data_partner_ids. The first ID is used as the
834
+ * primary _linkedin_partner_id global.
835
+ * @example '111143'
836
+ * @example ['111143', '111154']
837
+ * @see https://www.linkedin.com/help/lms/answer/a417869/access-your-linkedin-partner-id
838
+ */
839
+ readonly id: import("valibot").UnionSchema<[import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>, import("valibot").SchemaWithPipe<readonly [import("valibot").ArraySchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>, undefined>, import("valibot").MinLengthAction<string[], 1, undefined>]>], undefined>;
840
+ /**
841
+ * Optional page-load event ID for Conversions API deduplication. Assigned
842
+ * to window._linkedin_event_id BEFORE the Insight Tag base code runs. Must
843
+ * match the eventId sent with the corresponding server-side Conversions
844
+ * API event.
845
+ *
846
+ * Per-event conversion deduplication uses the per-call event_id passed to
847
+ * lintrk('track', { conversion_id, event_id }) instead.
848
+ * @see https://learn.microsoft.com/en-us/linkedin/marketing/conversions/deduplication
849
+ */
850
+ readonly eventId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
851
+ /**
852
+ * Auto-fire lintrk('track') on Vue Router route changes (SPA virtual page
853
+ * views). When true, suppresses the script's built-in auto-page-view via
854
+ * window._wait_for_lintrk and tracks every navigation including the
855
+ * initial page through Nuxt's page:finish hook. When false, the script
856
+ * fires its own page-view exactly once on load and SPA navigations are
857
+ * not tracked unless lintrk('track') is called manually.
858
+ * @default false
859
+ */
860
+ readonly enableAutoSpaTracking: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
861
+ }, undefined>;
862
+ export declare const UsercentricsOptions: import("valibot").ObjectSchema<{
863
+ /**
864
+ * Your Usercentrics CMP v3 ruleset ID. Find it in the admin under
865
+ * Implementation; the snippet's `data-ruleset-id` value.
866
+ */
867
+ readonly rulesetId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>;
868
+ /**
869
+ * Inject the Usercentrics autoblocker (`autoblocker.js`) ahead of the loader.
870
+ * Enable when your ruleset relies on Auto Blocking (vs. Manual Blocking) to
871
+ * gate third-party scripts before consent is granted.
872
+ * @default false
873
+ */
874
+ readonly autoblocker: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
875
+ /**
876
+ * Override the language displayed by the CMP UI (BCP-47 code, e.g. `'en'`, `'de'`).
877
+ */
878
+ readonly language: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
879
+ }, undefined>;
880
+ export declare const CalendlyOptions: import("valibot").ObjectSchema<{
881
+ /**
882
+ * The Calendly event URL to embed.
883
+ * Required for inline, popup, and badge widgets when called via the composable.
884
+ * @example 'https://calendly.com/your-name/30min'
885
+ * @see https://help.calendly.com/hc/en-us/articles/223147027
886
+ */
887
+ readonly url: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
888
+ /**
889
+ * Pre-fill invitee fields on the booking form.
890
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
891
+ */
892
+ readonly prefill: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
893
+ readonly name: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
894
+ readonly email: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
895
+ readonly firstName: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
896
+ readonly lastName: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
897
+ /** Custom answers keyed by `a1`, `a2`, ... matching custom question order. */
898
+ readonly customAnswers: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").StringSchema<undefined>, undefined>, undefined>;
899
+ }, undefined>, undefined>;
900
+ /**
901
+ * UTM parameters appended to the booking URL for marketing attribution.
902
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
903
+ */
904
+ readonly utm: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
905
+ readonly utmCampaign: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
906
+ readonly utmSource: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
907
+ readonly utmMedium: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
908
+ readonly utmContent: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
909
+ readonly utmTerm: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
910
+ }, undefined>, undefined>;
911
+ /**
912
+ * Theme and layout overrides applied to the booking page.
913
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
914
+ */
915
+ readonly pageSettings: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
916
+ readonly backgroundColor: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
917
+ readonly hideEventTypeDetails: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
918
+ readonly hideLandingPageDetails: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
919
+ readonly primaryColor: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
920
+ readonly textColor: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
921
+ }, undefined>, undefined>;
922
+ /**
923
+ * CSS selector for the element that hosts the inline widget.
924
+ * Required when the widget is initialised inline; the element should have a
925
+ * minimum height of around 700px so the booking iframe is fully visible.
926
+ */
927
+ readonly parentElement: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
928
+ }, undefined>;
811
929
  export declare const SegmentOptions: import("valibot").ObjectSchema<{
812
930
  /**
813
931
  * Your Segment write key.
@@ -957,6 +1075,12 @@ export declare const TikTokPixelOptions: import("valibot").ObjectSchema<{
957
1075
  * @see https://business-api.tiktok.com/portal/docs?id=1739585600931842
958
1076
  */
959
1077
  readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>, import("valibot").LiteralSchema<"hold", undefined>], undefined>, undefined>;
1078
+ /**
1079
+ * Data residency region for the Pixel SDK.
1080
+ * - `'global'` (default) -> `analytics.tiktok.com`
1081
+ * - `'us'` -> `analytics.us.tiktok.com` (US enterprise data residency)
1082
+ */
1083
+ readonly region: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"global", undefined>, import("valibot").LiteralSchema<"us", undefined>], undefined>, undefined>;
960
1084
  }, undefined>;
961
1085
  export declare const UmamiAnalyticsOptions: import("valibot").ObjectSchema<{
962
1086
  /**
@@ -1,6 +1,6 @@
1
1
  import { any, array, boolean, custom, literal, minLength, number, object, optional, pipe, record, string, union } from "valibot";
2
2
  const consentCategoryValue = union([literal("granted"), literal("denied")]);
3
- const gcmConsentState = object({
3
+ export const gcmConsentState = object({
4
4
  ad_storage: optional(consentCategoryValue),
5
5
  ad_user_data: optional(consentCategoryValue),
6
6
  ad_personalization: optional(consentCategoryValue),
@@ -11,6 +11,14 @@ const gcmConsentState = object({
11
11
  wait_for_update: optional(number()),
12
12
  region: optional(array(string()))
13
13
  });
14
+ export const AhrefsAnalyticsOptions = object({
15
+ /**
16
+ * Your Ahrefs Web Analytics project key. Set as the `data-key` attribute
17
+ * on the loaded `analytics.js` script tag.
18
+ * @see https://ahrefs.com/web-analytics
19
+ */
20
+ key: pipe(string(), minLength(1))
21
+ });
14
22
  export const BlueskyEmbedOptions = object({
15
23
  /**
16
24
  * The Bluesky post URL to embed.
@@ -778,6 +786,105 @@ export const BingUetOptions = object({
778
786
  ad_storage: optional(consentCategoryValue)
779
787
  }))
780
788
  });
789
+ export const LinkedInInsightOptions = object({
790
+ /**
791
+ * Your LinkedIn Insight Tag Partner ID, or an array of Partner IDs to push
792
+ * onto window._linkedin_data_partner_ids. The first ID is used as the
793
+ * primary _linkedin_partner_id global.
794
+ * @example '111143'
795
+ * @example ['111143', '111154']
796
+ * @see https://www.linkedin.com/help/lms/answer/a417869/access-your-linkedin-partner-id
797
+ */
798
+ id: union([pipe(string(), minLength(1)), pipe(array(pipe(string(), minLength(1))), minLength(1))]),
799
+ /**
800
+ * Optional page-load event ID for Conversions API deduplication. Assigned
801
+ * to window._linkedin_event_id BEFORE the Insight Tag base code runs. Must
802
+ * match the eventId sent with the corresponding server-side Conversions
803
+ * API event.
804
+ *
805
+ * Per-event conversion deduplication uses the per-call event_id passed to
806
+ * lintrk('track', { conversion_id, event_id }) instead.
807
+ * @see https://learn.microsoft.com/en-us/linkedin/marketing/conversions/deduplication
808
+ */
809
+ eventId: optional(string()),
810
+ /**
811
+ * Auto-fire lintrk('track') on Vue Router route changes (SPA virtual page
812
+ * views). When true, suppresses the script's built-in auto-page-view via
813
+ * window._wait_for_lintrk and tracks every navigation including the
814
+ * initial page through Nuxt's page:finish hook. When false, the script
815
+ * fires its own page-view exactly once on load and SPA navigations are
816
+ * not tracked unless lintrk('track') is called manually.
817
+ * @default false
818
+ */
819
+ enableAutoSpaTracking: optional(boolean())
820
+ });
821
+ export const UsercentricsOptions = object({
822
+ /**
823
+ * Your Usercentrics CMP v3 ruleset ID. Find it in the admin under
824
+ * Implementation; the snippet's `data-ruleset-id` value.
825
+ */
826
+ rulesetId: pipe(string(), minLength(1)),
827
+ /**
828
+ * Inject the Usercentrics autoblocker (`autoblocker.js`) ahead of the loader.
829
+ * Enable when your ruleset relies on Auto Blocking (vs. Manual Blocking) to
830
+ * gate third-party scripts before consent is granted.
831
+ * @default false
832
+ */
833
+ autoblocker: optional(boolean()),
834
+ /**
835
+ * Override the language displayed by the CMP UI (BCP-47 code, e.g. `'en'`, `'de'`).
836
+ */
837
+ language: optional(string())
838
+ });
839
+ export const CalendlyOptions = object({
840
+ /**
841
+ * The Calendly event URL to embed.
842
+ * Required for inline, popup, and badge widgets when called via the composable.
843
+ * @example 'https://calendly.com/your-name/30min'
844
+ * @see https://help.calendly.com/hc/en-us/articles/223147027
845
+ */
846
+ url: optional(string()),
847
+ /**
848
+ * Pre-fill invitee fields on the booking form.
849
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
850
+ */
851
+ prefill: optional(object({
852
+ name: optional(string()),
853
+ email: optional(string()),
854
+ firstName: optional(string()),
855
+ lastName: optional(string()),
856
+ /** Custom answers keyed by `a1`, `a2`, ... matching custom question order. */
857
+ customAnswers: optional(record(string(), string()))
858
+ })),
859
+ /**
860
+ * UTM parameters appended to the booking URL for marketing attribution.
861
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
862
+ */
863
+ utm: optional(object({
864
+ utmCampaign: optional(string()),
865
+ utmSource: optional(string()),
866
+ utmMedium: optional(string()),
867
+ utmContent: optional(string()),
868
+ utmTerm: optional(string())
869
+ })),
870
+ /**
871
+ * Theme and layout overrides applied to the booking page.
872
+ * @see https://help.calendly.com/hc/en-us/articles/360020052833
873
+ */
874
+ pageSettings: optional(object({
875
+ backgroundColor: optional(string()),
876
+ hideEventTypeDetails: optional(boolean()),
877
+ hideLandingPageDetails: optional(boolean()),
878
+ primaryColor: optional(string()),
879
+ textColor: optional(string())
880
+ })),
881
+ /**
882
+ * CSS selector for the element that hosts the inline widget.
883
+ * Required when the widget is initialised inline; the element should have a
884
+ * minimum height of around 700px so the booking iframe is fully visible.
885
+ */
886
+ parentElement: optional(string())
887
+ });
781
888
  export const SegmentOptions = object({
782
889
  /**
783
890
  * Your Segment write key.
@@ -879,7 +986,13 @@ export const TikTokPixelOptions = object({
879
986
  * - `'hold'` fires `ttq.holdConsent()` to defer until an explicit update
880
987
  * @see https://business-api.tiktok.com/portal/docs?id=1739585600931842
881
988
  */
882
- defaultConsent: optional(union([literal("granted"), literal("denied"), literal("hold")]))
989
+ defaultConsent: optional(union([literal("granted"), literal("denied"), literal("hold")])),
990
+ /**
991
+ * Data residency region for the Pixel SDK.
992
+ * - `'global'` (default) -> `analytics.tiktok.com`
993
+ * - `'us'` -> `analytics.us.tiktok.com` (US enterprise data residency)
994
+ */
995
+ region: optional(union([literal("global"), literal("us")]))
883
996
  });
884
997
  export const UmamiAnalyticsOptions = object({
885
998
  /**
@@ -1,6 +1,6 @@
1
1
  import type { RegistryScriptInput, UseScriptContext } from '#nuxt-scripts/types';
2
2
  import { TikTokPixelOptions } from './schemas.js';
3
- type StandardEvents = 'ViewContent' | 'ClickButton' | 'Search' | 'AddToWishlist' | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'CompletePayment' | 'PlaceAnOrder' | 'Contact' | 'Download' | 'SubmitForm' | 'CompleteRegistration' | 'Subscribe';
3
+ type StandardEvents = 'ViewContent' | 'ClickButton' | 'Search' | 'AddToWishlist' | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'CompletePayment' | 'PlaceAnOrder' | 'Purchase' | 'Contact' | 'Download' | 'SubmitForm' | 'CompleteRegistration' | 'Subscribe' | 'StartTrial' | 'ApplicationApproval' | 'CustomizeProduct' | 'FindLocation' | 'Schedule' | 'SubmitApplication';
4
4
  interface EventProperties {
5
5
  content_id?: string;
6
6
  content_type?: string;
@@ -16,34 +16,99 @@ interface EventProperties {
16
16
  value?: number;
17
17
  description?: string;
18
18
  query?: string;
19
+ /** Order/transaction identifier; complements `event_id` for transaction-level dedup. */
20
+ order_id?: string;
19
21
  [key: string]: any;
20
22
  }
23
+ /**
24
+ * Advanced matching parameters. TikTok requires SHA-256-hashed values for `email`,
25
+ * `phone_number`, `external_id`, and the name/address fields to enable matching.
26
+ * Passing raw values disables matching silently; a dev-mode warning is logged.
27
+ * @see https://business-api.tiktok.com/portal/docs?id=1739585702922241
28
+ */
21
29
  interface IdentifyProperties {
22
30
  email?: string;
23
31
  phone_number?: string;
24
32
  external_id?: string;
33
+ first_name?: string;
34
+ last_name?: string;
35
+ city?: string;
36
+ state?: string;
37
+ country?: string;
38
+ zip_code?: string;
25
39
  }
26
- type TtqFns = ((cmd: 'track', event: StandardEvents | (string & {}), properties?: EventProperties) => void) & ((cmd: 'page') => void) & ((cmd: 'identify', properties: IdentifyProperties) => void) & ((cmd: (string & {}), ...args: any[]) => void);
40
+ interface TrackOptions {
41
+ /** Used to deduplicate events sent from both the browser Pixel and the server-side Events API. */
42
+ event_id?: string;
43
+ /**
44
+ * Sandbox test-event identifier. When set, events route to TikTok's Test Events panel
45
+ * without affecting production reporting.
46
+ */
47
+ test_event_code?: string;
48
+ [key: string]: any;
49
+ }
50
+ /**
51
+ * The deferred methods TikTok's base code installs on `ttq`. Calling one before
52
+ * `events.js` loads pushes a `[method, ...args]` tuple onto the queue; afterwards
53
+ * `events.js` rebinds them to live implementations.
54
+ */
55
+ export interface TtqInstance {
56
+ /** Track a page view. */
57
+ page: () => void;
58
+ /** Track a standard or custom conversion event. */
59
+ track: (event: StandardEvents | (string & {}), properties?: EventProperties, options?: TrackOptions) => void;
60
+ /** Associate advanced-matching identifiers with the current user. */
61
+ identify: (properties: IdentifyProperties) => void;
62
+ /** Opt user in to tracking. Queued before the script loads; live once `events.js` binds. */
63
+ grantConsent: () => void;
64
+ /** Opt user out of tracking. Queued before the script loads; live once `events.js` binds. */
65
+ revokeConsent: () => void;
66
+ /** Defer consent until an explicit grant/revoke. Queued before the script loads; live once `events.js` binds. */
67
+ holdConsent: () => void;
68
+ enableCookie: () => void;
69
+ disableCookie: () => void;
70
+ }
71
+ /**
72
+ * Legacy callable signature. Pre-1.2 `useScriptTikTokPixel` exposed `ttq` as an
73
+ * `fbq`-style callable (`ttq('page')`, `ttq('track', …)`); the adapter keeps it
74
+ * working alongside the method form.
75
+ */
76
+ type TtqCallable = ((cmd: 'track', event: StandardEvents | (string & {}), properties?: EventProperties, options?: TrackOptions) => void) & ((cmd: 'page') => void) & ((cmd: 'identify', properties: IdentifyProperties) => void) & ((cmd: (string & {}), ...args: any[]) => void);
77
+ /**
78
+ * The public `ttq` returned by the composable: a callable adapter (legacy form)
79
+ * that also carries the deferred methods (`ttq.page()`, `ttq.track(…)`). The
80
+ * adapter forwards to `window.ttq`, which is TikTok's real array protocol.
81
+ */
82
+ export type Ttq = TtqCallable & TtqInstance & {
83
+ /** Resolve the per-pixel method bag for a specific pixel id. */
84
+ instance: (id: string) => TtqInstance;
85
+ };
27
86
  export interface TikTokPixelApi {
28
- ttq: TtqFns & {
29
- push: TtqFns;
30
- loaded: boolean;
31
- queue: any[];
32
- /** Opt user in to tracking. Queued before the script loads; live once `events.js` binds. */
33
- grantConsent: () => void;
34
- /** Opt user out of tracking. Queued before the script loads; live once `events.js` binds. */
35
- revokeConsent: () => void;
36
- /** Defer consent until an explicit grant/revoke. Queued before the script loads; live once `events.js` binds. */
37
- holdConsent: () => void;
38
- };
87
+ ttq: Ttq;
39
88
  }
89
+ /**
90
+ * TikTok's `window.ttq` is an Array, not a callable: `events.js` reads it as a
91
+ * queue of `[method, ...args]` tuples and replays them, with the deferred
92
+ * methods installed as own properties on the array.
93
+ */
94
+ type TtqArray = TtqInstance & Array<any[]> & {
95
+ methods: string[];
96
+ setAndDefer: (target: any, method: string) => void;
97
+ instance: (id: string) => TtqInstance;
98
+ _i?: Record<string, any[]>;
99
+ _t?: Record<string, number>;
100
+ _o?: Record<string, any>;
101
+ };
40
102
  declare global {
41
- interface Window extends TikTokPixelApi {
103
+ interface Window {
104
+ ttq: TtqArray;
42
105
  TiktokAnalyticsObject: string;
43
106
  }
44
107
  }
45
108
  export { TikTokPixelOptions };
46
109
  export type TikTokPixelInput = RegistryScriptInput<typeof TikTokPixelOptions, true, false>;
110
+ /** Resolve the Pixel SDK URL for a given data-residency region. */
111
+ export declare function tiktokPixelSrc(region?: 'global' | 'us'): string;
47
112
  export interface TikTokPixelConsent {
48
113
  /** Call `ttq.grantConsent()`. */
49
114
  grant: () => void;
@@ -1,11 +1,38 @@
1
1
  import { withQuery } from "ufo";
2
+ import { logger } from "../logger.js";
2
3
  import { useRegistryScript } from "../utils.js";
3
4
  import { TikTokPixelOptions } from "./schemas.js";
4
5
  export { TikTokPixelOptions };
6
+ export function tiktokPixelSrc(region) {
7
+ return region === "us" ? "https://analytics.us.tiktok.com/i18n/pixel/events.js" : "https://analytics.tiktok.com/i18n/pixel/events.js";
8
+ }
9
+ const TTQ_METHODS = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie", "holdConsent", "revokeConsent", "grantConsent"];
10
+ const SHA256_HEX = /^[a-f0-9]{64}$/i;
11
+ function warnUnhashedIdentify(props) {
12
+ const hashFields = ["email", "phone_number", "external_id", "first_name", "last_name", "city", "state", "country", "zip_code"];
13
+ const offenders = hashFields.filter((f) => {
14
+ const v = props[f];
15
+ return typeof v === "string" && v.length > 0 && !SHA256_HEX.test(v);
16
+ });
17
+ if (offenders.length) {
18
+ logger.withTag("tiktokPixel").warn(`identify() received unhashed value(s) for ${offenders.join(", ")}. TikTok requires SHA-256 hashing for advanced matching; raw values will be ignored. See https://business-api.tiktok.com/portal/docs?id=1739585702922241`);
19
+ }
20
+ }
21
+ function createTtqAdapter() {
22
+ const dispatch = (method, ...args) => {
23
+ if (import.meta.dev && method === "identify" && args[0])
24
+ warnUnhashedIdentify(args[0]);
25
+ return window.ttq[method]?.(...args);
26
+ };
27
+ const adapter = ((method, ...args) => dispatch(method, ...args));
28
+ for (const method of [...TTQ_METHODS, "instance"])
29
+ adapter[method] = (...args) => dispatch(method, ...args);
30
+ return adapter;
31
+ }
5
32
  export function useScriptTikTokPixel(_options) {
6
33
  const instance = useRegistryScript("tiktokPixel", (options) => ({
7
34
  scriptInput: {
8
- src: withQuery("https://analytics.tiktok.com/i18n/pixel/events.js", {
35
+ src: withQuery(tiktokPixelSrc(options?.region), {
9
36
  sdkid: options?.id,
10
37
  lib: "ttq"
11
38
  }),
@@ -14,39 +41,46 @@ export function useScriptTikTokPixel(_options) {
14
41
  schema: import.meta.dev ? TikTokPixelOptions : void 0,
15
42
  scriptOptions: {
16
43
  use() {
17
- return { ttq: window.ttq };
44
+ return { ttq: createTtqAdapter() };
18
45
  }
19
46
  },
47
+ // TikTok's `events.js` consumes the official array-based snippet protocol:
48
+ // `window.ttq` is an Array of `[method, ...args]` tuples that `events.js`
49
+ // drains once loaded. (It does NOT understand the Facebook `fbq` callable
50
+ // protocol — using that shape silently drops every browser Pixel event.)
20
51
  clientInit: import.meta.server ? void 0 : () => {
21
52
  window.TiktokAnalyticsObject = "ttq";
22
- const ttq = window.ttq = function(...params) {
23
- if (ttq.callMethod) {
24
- ttq.callMethod(...params);
25
- } else {
26
- ttq.queue.push(params);
27
- }
28
- };
29
- ttq.push = ttq;
30
- ttq.loaded = true;
31
- ttq.queue = [];
32
- const consentMethods = ["grantConsent", "revokeConsent", "holdConsent"];
33
- for (const name of consentMethods) {
34
- ;
35
- ttq[name] = function(...params) {
36
- ttq.queue.push([name, ...params]);
53
+ const ttq = window.ttq = window.ttq || [];
54
+ ttq.methods = TTQ_METHODS;
55
+ ttq.setAndDefer = function(target, method) {
56
+ target[method] = function(...args) {
57
+ target.push([method, ...args]);
37
58
  };
38
- }
39
- if (options?.defaultConsent === "granted")
40
- ttq.grantConsent();
41
- else if (options?.defaultConsent === "denied")
42
- ttq.revokeConsent();
43
- else if (options?.defaultConsent === "hold")
44
- ttq.holdConsent();
59
+ };
60
+ for (const method of ttq.methods)
61
+ ttq.setAndDefer(ttq, method);
62
+ ttq.instance = function(id) {
63
+ const bag = ttq._i?.[id] || [];
64
+ for (const method of ttq.methods)
65
+ ttq.setAndDefer(bag, method);
66
+ return bag;
67
+ };
45
68
  if (options?.id) {
46
- ttq("init", options.id);
47
- if (options?.trackPageView !== false) {
48
- ttq("page");
49
- }
69
+ ttq._i = ttq._i || {};
70
+ ttq._i[options.id] = ttq._i[options.id] || [];
71
+ ttq._i[options.id]._u = tiktokPixelSrc(options?.region);
72
+ ttq._t = ttq._t || {};
73
+ ttq._t[options.id] = Date.now();
74
+ ttq._o = ttq._o || {};
75
+ ttq._o[options.id] = {};
76
+ if (options?.defaultConsent === "granted")
77
+ ttq.grantConsent();
78
+ else if (options?.defaultConsent === "denied")
79
+ ttq.revokeConsent();
80
+ else if (options?.defaultConsent === "hold")
81
+ ttq.holdConsent();
82
+ if (options?.trackPageView !== false)
83
+ ttq.page();
50
84
  }
51
85
  }
52
86
  }), _options);
@@ -0,0 +1,85 @@
1
+ import type { RegistryScriptInput, UseScriptContext } from '#nuxt-scripts/types';
2
+ import { UsercentricsOptions } from './schemas.js';
3
+ export { UsercentricsOptions };
4
+ export type UsercentricsInput = RegistryScriptInput<typeof UsercentricsOptions, false, false>;
5
+ export interface UsercentricsCmpEventDetail {
6
+ type: string;
7
+ source?: string;
8
+ [key: string]: any;
9
+ }
10
+ /**
11
+ * The Usercentrics CMP v3 programmatic API exposed on `window.__ucCmp`.
12
+ * Each method returns a Promise resolved once the CMP is ready.
13
+ */
14
+ export interface UsercentricsCmp {
15
+ isInitialized: () => Promise<boolean>;
16
+ isConsentRequired: () => Promise<boolean>;
17
+ showFirstLayer: () => Promise<void>;
18
+ showSecondLayer: () => Promise<void>;
19
+ showServiceDetails: (id: string) => Promise<void>;
20
+ showAutoblockerMoreInfoView: () => Promise<void>;
21
+ closeCmp: () => Promise<void>;
22
+ acceptAllConsents: () => Promise<void>;
23
+ denyAllConsents: () => Promise<void>;
24
+ saveConsents: () => Promise<void>;
25
+ updateCategoriesConsents: (consents: Array<{
26
+ categorySlug: string;
27
+ consent: boolean;
28
+ }>) => Promise<void>;
29
+ updateServicesConsents: (consents: Array<{
30
+ templateId: string;
31
+ consent: boolean;
32
+ }>) => Promise<void>;
33
+ updateTcfConsents: (...args: unknown[]) => Promise<void>;
34
+ refreshScripts: () => Promise<void>;
35
+ clearUserSession: () => Promise<void>;
36
+ getConsentDetails: () => Promise<Record<string, any>>;
37
+ getCmpConfig: () => Promise<Record<string, any>>;
38
+ getActiveLanguage: () => Promise<string>;
39
+ getControllerId: () => Promise<string>;
40
+ changeLanguage: (lang: string) => Promise<void>;
41
+ [key: string]: any;
42
+ }
43
+ export interface UsercentricsApi {
44
+ ucCmp: UsercentricsCmp;
45
+ }
46
+ declare global {
47
+ interface Window {
48
+ __ucCmp?: UsercentricsCmp;
49
+ }
50
+ }
51
+ /**
52
+ * Vendor-native Usercentrics consent helpers exposed on the composable result.
53
+ * Use these to drive `useScript` consent triggers from CMP events.
54
+ */
55
+ export interface UsercentricsConsent {
56
+ /**
57
+ * Resolves once the CMP API is ready (`UC_CMP_API_READY`) or immediately if
58
+ * it already is. Resolves with `window.__ucCmp` so callers can query
59
+ * consent state without polling.
60
+ */
61
+ whenReady: () => Promise<UsercentricsCmp>;
62
+ /**
63
+ * Subscribe to `UC_UI_CMP_EVENT` browser events (the v3 consent change
64
+ * event). Returns a teardown function. The callback receives the event
65
+ * detail, e.g. `{ type: 'ACCEPT_ALL' | 'DENY_ALL' | 'SAVE', ... }`.
66
+ */
67
+ onConsentChange: (cb: (detail: UsercentricsCmpEventDetail, event: Event) => void) => () => void;
68
+ /** Open the privacy settings (first layer banner). */
69
+ showFirstLayer: () => Promise<void> | void;
70
+ /** Open the detailed settings (second layer modal). */
71
+ showSecondLayer: () => Promise<void> | void;
72
+ /** Accept all consents. */
73
+ acceptAll: () => Promise<void> | void;
74
+ /** Reject all consents. */
75
+ denyAll: () => Promise<void> | void;
76
+ }
77
+ /**
78
+ * Load the Usercentrics CMP v3 ("Web CMP") loader and expose typed access to
79
+ * the `window.__ucCmp` programmatic API plus a `consent` helper with
80
+ * `onConsentChange` for wiring consent triggers (`useScript({ trigger: ... })`)
81
+ * to Usercentrics events.
82
+ *
83
+ * @see https://usercentrics.com/knowledge-hub/usercentrics-cmp-v3-migrations/
84
+ */
85
+ export declare function useScriptUsercentrics<T extends UsercentricsApi>(_options?: UsercentricsInput): UseScriptContext<T, UsercentricsConsent>;
@@ -0,0 +1,54 @@
1
+ import { useHead } from "@unhead/vue";
2
+ import { useRegistryScript } from "../utils.js";
3
+ import { UsercentricsOptions } from "./schemas.js";
4
+ export { UsercentricsOptions };
5
+ export function useScriptUsercentrics(_options) {
6
+ const instance = useRegistryScript("usercentrics", (options) => {
7
+ if (import.meta.client && options.autoblocker) {
8
+ useHead({
9
+ script: [{
10
+ src: "https://web.cmp.usercentrics.eu/modules/autoblocker.js",
11
+ tagPosition: "head",
12
+ tagPriority: "high"
13
+ }]
14
+ });
15
+ }
16
+ return {
17
+ scriptInput: {
18
+ "src": "https://web.cmp.usercentrics.eu/ui/loader.js",
19
+ "id": "usercentrics-cmp",
20
+ "data-ruleset-id": options.rulesetId,
21
+ "data-language": options.language,
22
+ "crossorigin": false
23
+ },
24
+ schema: import.meta.dev ? UsercentricsOptions : void 0,
25
+ scriptOptions: {
26
+ use() {
27
+ return { ucCmp: window.__ucCmp };
28
+ }
29
+ }
30
+ };
31
+ }, _options);
32
+ if (import.meta.client && !instance.consent) {
33
+ const whenReady = () => new Promise((resolve) => {
34
+ const onReady = () => {
35
+ window.removeEventListener("UC_CMP_API_READY", onReady);
36
+ resolve(window.__ucCmp);
37
+ };
38
+ window.addEventListener("UC_CMP_API_READY", onReady);
39
+ });
40
+ instance.consent = {
41
+ whenReady,
42
+ onConsentChange(cb) {
43
+ const handler = (e) => cb(e.detail, e);
44
+ window.addEventListener("UC_UI_CMP_EVENT", handler);
45
+ return () => window.removeEventListener("UC_UI_CMP_EVENT", handler);
46
+ },
47
+ showFirstLayer: () => window.__ucCmp?.showFirstLayer?.(),
48
+ showSecondLayer: () => window.__ucCmp?.showSecondLayer?.(),
49
+ acceptAll: () => window.__ucCmp?.acceptAllConsents?.(),
50
+ denyAll: () => window.__ucCmp?.denyAllConsents?.()
51
+ };
52
+ }
53
+ return instance;
54
+ }