@nuxt/scripts 0.12.2 → 0.13.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.
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760342373620,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"e404bf6c-6cc5-4a5a-bd29-546b71b82a4b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760559698659,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"78c6ab23-83d1-4e01-9f34-31be10d5e3b9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760342373621,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"e404bf6c-6cc5-4a5a-bd29-546b71b82a4b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760559698660,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"78c6ab23-83d1-4e01-9f34-31be10d5e3b9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -1 +1 @@
1
- {"id":"e404bf6c-6cc5-4a5a-bd29-546b71b82a4b","timestamp":1760342368989}
1
+ {"id":"78c6ab23-83d1-4e01-9f34-31be10d5e3b9","timestamp":1760559694033}
@@ -0,0 +1 @@
1
+ {"id":"78c6ab23-83d1-4e01-9f34-31be10d5e3b9","timestamp":1760559694033,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760342373621,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"e404bf6c-6cc5-4a5a-bd29-546b71b82a4b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><script type="importmap">{"imports":{"#entry":"/__nuxt-scripts/_nuxt/CGGF_5bm.js"}}</script><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.Bb8Z00UZ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CGGF_5bm.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CVO1_9PV.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/D0r3Knsf.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Cp-IABpG.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DlfHMoPT.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-404.c-5_FvQE.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CDuymAca.js"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/Z5EPizOU.js"><link rel="prefetch" as="style" crossorigin href="/__nuxt-scripts/_nuxt/error-500.Dgf4btmt.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt-scripts/_nuxt/C09X5LNe.js"><script type="module" src="/__nuxt-scripts/_nuxt/CGGF_5bm.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1760559698660,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"78c6ab23-83d1-4e01-9f34-31be10d5e3b9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16"
6
6
  },
7
- "version": "0.12.2",
7
+ "version": "0.13.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { useNuxt, useLogger, addDevServerHandler, tryUseNuxt, logger as logger$1, defineNuxtModule, createResolver, addImports, addComponentsDir, addTypeTemplate, addPluginTemplate, addBuildPlugin, hasNuxtModule } from '@nuxt/kit';
1
+ import { useNuxt, useLogger, addDevServerHandler, tryUseNuxt, logger as logger$1, defineNuxtModule, createResolver, addImports, addComponentsDir, addTemplate, addTypeTemplate, addPluginTemplate, addBuildPlugin, hasNuxtModule } from '@nuxt/kit';
2
2
  import { defu } from 'defu';
3
3
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
4
4
  import { existsSync } from 'node:fs';
@@ -531,6 +531,25 @@ function NuxtScriptsCheckScripts() {
531
531
  });
532
532
  }
533
533
 
534
+ function templateTriggerResolver(defaultScriptOptions) {
535
+ const needsIdleTimeout = defaultScriptOptions?.trigger && typeof defaultScriptOptions.trigger === "object" && "idleTimeout" in defaultScriptOptions.trigger;
536
+ const needsInteraction = defaultScriptOptions?.trigger && typeof defaultScriptOptions.trigger === "object" && "interaction" in defaultScriptOptions.trigger;
537
+ const imports = [];
538
+ if (needsIdleTimeout) {
539
+ imports.push(`import { useScriptTriggerIdleTimeout } from '#nuxt-scripts/composables/useScriptTriggerIdleTimeout'`);
540
+ }
541
+ if (needsInteraction) {
542
+ imports.push(`import { useScriptTriggerInteraction } from '#nuxt-scripts/composables/useScriptTriggerInteraction'`);
543
+ }
544
+ return [
545
+ ...imports,
546
+ `export function resolveTrigger(trigger) {`,
547
+ needsIdleTimeout ? ` if ('idleTimeout' in trigger) return useScriptTriggerIdleTimeout({ timeout: trigger.idleTimeout })` : "",
548
+ needsInteraction ? ` if ('interaction' in trigger) return useScriptTriggerInteraction({ events: trigger.interaction })` : "",
549
+ ` return null`,
550
+ `}`
551
+ ].filter(Boolean).join("\n");
552
+ }
534
553
  function resolveTriggerForTemplate(trigger) {
535
554
  if (trigger && typeof trigger === "object") {
536
555
  const keys = Object.keys(trigger);
@@ -701,6 +720,12 @@ const module = defineNuxtModule({
701
720
  path: await resolvePath("./runtime/components"),
702
721
  pathPrefix: false
703
722
  });
723
+ addTemplate({
724
+ filename: "nuxt-scripts-trigger-resolver.mjs",
725
+ getContents() {
726
+ return templateTriggerResolver(config.defaultScriptOptions);
727
+ }
728
+ });
704
729
  const scripts = await registry(resolvePath);
705
730
  for (const script of scripts) {
706
731
  if (script.import?.name) {
@@ -3,6 +3,7 @@ import { useScript as _useScript } from "@unhead/vue/scripts";
3
3
  import { reactive } from "vue";
4
4
  import { onNuxtReady, useNuxtApp, useRuntimeConfig, injectHead } from "nuxt/app";
5
5
  import { logger } from "../logger.js";
6
+ import { resolveTrigger } from "#build/nuxt-scripts-trigger-resolver";
6
7
  function useNuxtScriptRuntimeConfig() {
7
8
  return useRuntimeConfig().public["nuxt-scripts"];
8
9
  }
@@ -16,6 +17,12 @@ export function useScript(input, options) {
16
17
  console.warn("[Nuxt Scripts] Bundling is not supported for dynamic script sources. Static URLs are required for bundling.");
17
18
  options.bundle = false;
18
19
  }
20
+ if (options.trigger && typeof options.trigger === "object" && !("then" in options.trigger)) {
21
+ const resolved = resolveTrigger(options.trigger);
22
+ if (resolved) {
23
+ options.trigger = resolved;
24
+ }
25
+ }
19
26
  const id = String(resolveScriptKey(input));
20
27
  const nuxtApp = useNuxtApp();
21
28
  options.head = options.head || injectHead();
@@ -1,17 +1,91 @@
1
1
  import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
- export declare const PlausibleAnalyticsOptions: import("valibot").ObjectSchema<{
3
- readonly domain: import("valibot").StringSchema<undefined>;
2
+ declare const PlausibleAnalyticsOptionsSchema: import("valibot").ObjectSchema<{
3
+ readonly scriptId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
4
+ readonly domain: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
4
5
  readonly extension: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").UnionSchema<(import("valibot").LiteralSchema<"hash", undefined> | import("valibot").LiteralSchema<"outbound-links", undefined> | import("valibot").LiteralSchema<"file-downloads", undefined> | import("valibot").LiteralSchema<"tagged-events", undefined> | import("valibot").LiteralSchema<"revenue", undefined> | import("valibot").LiteralSchema<"pageview-props", undefined> | import("valibot").LiteralSchema<"compat", undefined> | import("valibot").LiteralSchema<"local", undefined> | import("valibot").LiteralSchema<"manual", undefined>)[], undefined>, import("valibot").ArraySchema<import("valibot").UnionSchema<(import("valibot").LiteralSchema<"hash", undefined> | import("valibot").LiteralSchema<"outbound-links", undefined> | import("valibot").LiteralSchema<"file-downloads", undefined> | import("valibot").LiteralSchema<"tagged-events", undefined> | import("valibot").LiteralSchema<"revenue", undefined> | import("valibot").LiteralSchema<"pageview-props", undefined> | import("valibot").LiteralSchema<"compat", undefined> | import("valibot").LiteralSchema<"local", undefined> | import("valibot").LiteralSchema<"manual", undefined>)[], undefined>, undefined>], undefined>, undefined>;
6
+ readonly customProperties: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").AnySchema, undefined>, undefined>;
7
+ readonly endpoint: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
8
+ readonly fileDownloads: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
9
+ readonly fileExtensions: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
10
+ }, undefined>, undefined>;
11
+ readonly hashBasedRouting: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
12
+ readonly autoCapturePageviews: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
13
+ readonly captureOnLocalhost: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
14
+ readonly trackForms: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
5
15
  }, undefined>;
6
- export type PlausibleAnalyticsInput = RegistryScriptInput<typeof PlausibleAnalyticsOptions, false>;
7
- export interface PlausibleAnalyticsApi {
8
- plausible: ((event: '404', options: Record<string, any>) => void) & ((event: 'event', options: Record<string, any>) => void) & ((...params: any[]) => void) & {
9
- q: any[];
16
+ /**
17
+ * Plausible Analytics options
18
+ * @see https://plausible.io/docs/script-extensions
19
+ */
20
+ export interface PlausibleAnalyticsOptions {
21
+ /**
22
+ * Unique script ID for your site (recommended - new format as of October 2025)
23
+ * Get this from your Plausible dashboard under Site Installation
24
+ *
25
+ * Extract it from your Plausible script URL:
26
+ * ```
27
+ * <script src="https://plausible.io/js/pa-gYyxvZhkMzdzXBAtSeSNz.js"></script>
28
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
29
+ * scriptId: 'gYyxvZhkMzdzXBAtSeSNz'
30
+ * ```
31
+ * @example 'gYyxvZhkMzdzXBAtSeSNz'
32
+ */
33
+ scriptId?: string;
34
+ /**
35
+ * Your site domain
36
+ * @deprecated Use `scriptId` instead (new October 2025 format)
37
+ * @example 'example.com'
38
+ */
39
+ domain?: string;
40
+ /**
41
+ * Script extensions for additional features
42
+ * @deprecated Use init options like `hashBasedRouting`, `captureOnLocalhost`, etc. instead (new October 2025 format)
43
+ */
44
+ extension?: 'hash' | 'outbound-links' | 'file-downloads' | 'tagged-events' | 'revenue' | 'pageview-props' | 'compat' | 'local' | 'manual' | Array<'hash' | 'outbound-links' | 'file-downloads' | 'tagged-events' | 'revenue' | 'pageview-props' | 'compat' | 'local' | 'manual'>;
45
+ /** Custom properties to track with every pageview */
46
+ customProperties?: Record<string, any>;
47
+ /** Custom tracking endpoint URL */
48
+ endpoint?: string;
49
+ /** Configure file download tracking */
50
+ fileDownloads?: {
51
+ /** File extensions to track (default: pdf, xlsx, docx, txt, rtf, csv, exe, key, pps, ppt, pptx, 7z, pkg, rar, gz, zip, avi, mov, mp4, mpeg, wmv, midi, mp3, wav, wma, dmg) */
52
+ fileExtensions?: string[];
53
+ };
54
+ /** Enable hash-based routing for single-page apps */
55
+ hashBasedRouting?: boolean;
56
+ /** Set to false to manually trigger pageviews */
57
+ autoCapturePageviews?: boolean;
58
+ /** Enable tracking on localhost */
59
+ captureOnLocalhost?: boolean;
60
+ /** Enable form submission tracking */
61
+ trackForms?: boolean;
62
+ }
63
+ export type PlausibleAnalyticsInput = RegistryScriptInput<typeof PlausibleAnalyticsOptionsSchema, false>;
64
+ /**
65
+ * Init options for plausible.init() (October 2025 format)
66
+ * @see https://plausible.io/docs/script-extensions
67
+ */
68
+ export interface PlausibleInitOptions {
69
+ customProperties?: Record<string, any>;
70
+ endpoint?: string;
71
+ fileDownloads?: {
72
+ fileExtensions?: string[];
10
73
  };
74
+ hashBasedRouting?: boolean;
75
+ autoCapturePageviews?: boolean;
76
+ captureOnLocalhost?: boolean;
77
+ }
78
+ export type PlausibleFunction = ((event: '404', options: Record<string, any>) => void) & ((event: 'event', options: Record<string, any>) => void) & ((...params: any[]) => void) & {
79
+ q: any[];
80
+ init: (options: PlausibleInitOptions) => void;
81
+ };
82
+ export interface PlausibleAnalyticsApi {
83
+ plausible: PlausibleFunction;
11
84
  }
12
85
  declare global {
13
86
  interface Window {
14
- plausible: PlausibleAnalyticsApi;
87
+ plausible: PlausibleFunction;
15
88
  }
16
89
  }
17
90
  export declare function useScriptPlausibleAnalytics<T extends PlausibleAnalyticsApi>(_options?: PlausibleAnalyticsInput): import("#nuxt-scripts/types").UseScriptContext<T>;
91
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { useRegistryScript } from "../utils.js";
2
- import { array, literal, object, optional, string, union } from "#nuxt-scripts-validator";
2
+ import { any, array, boolean, literal, object, optional, record, string, union } from "#nuxt-scripts-validator";
3
+ import { logger } from "../logger.js";
3
4
  const extensions = [
4
5
  literal("hash"),
5
6
  literal("outbound-links"),
@@ -11,23 +12,75 @@ const extensions = [
11
12
  literal("local"),
12
13
  literal("manual")
13
14
  ];
14
- export const PlausibleAnalyticsOptions = object({
15
- domain: string(),
16
- // required
17
- extension: optional(union([union(extensions), array(union(extensions))]))
15
+ const PlausibleAnalyticsOptionsSchema = object({
16
+ // New October 2025: unique script ID per site (replaces domain)
17
+ scriptId: optional(string()),
18
+ // Legacy: domain-based approach (deprecated)
19
+ domain: optional(string()),
20
+ // Legacy extension support (deprecated)
21
+ extension: optional(union([union(extensions), array(union(extensions))])),
22
+ // New October 2025 init options
23
+ customProperties: optional(record(string(), any())),
24
+ endpoint: optional(string()),
25
+ fileDownloads: optional(object({
26
+ fileExtensions: optional(array(string()))
27
+ })),
28
+ hashBasedRouting: optional(boolean()),
29
+ autoCapturePageviews: optional(boolean()),
30
+ captureOnLocalhost: optional(boolean()),
31
+ trackForms: optional(boolean())
18
32
  });
19
33
  export function useScriptPlausibleAnalytics(_options) {
20
34
  return useRegistryScript("plausibleAnalytics", (options) => {
21
- const extensions2 = Array.isArray(options?.extension) ? options.extension.join(".") : [options?.extension];
35
+ const useNewScript = !!options?.scriptId;
36
+ const useLegacyScript = !!options?.extension;
37
+ if (import.meta.dev) {
38
+ if (!useNewScript && !options?.domain) {
39
+ logger.warn("Plausible Analytics: No `scriptId` or `domain` provided. Please provide either `scriptId` or `domain` (legacy).");
40
+ }
41
+ if (useNewScript && options?.domain) {
42
+ logger.warn("Plausible Analytics: You are using both `scriptId` (new format) and `domain` (deprecated). Please use only `scriptId` for the new format.");
43
+ }
44
+ if (useNewScript && useLegacyScript) {
45
+ logger.warn("Plausible Analytics: You are using both `scriptId` (new format) and `extension` (deprecated). Please use `scriptId` with init options like `hashBasedRouting`, `captureOnLocalhost`, etc. instead.");
46
+ }
47
+ }
48
+ let scriptSrc;
49
+ if (useNewScript) {
50
+ scriptSrc = `https://plausible.io/js/pa-${options.scriptId}.js`;
51
+ } else if (useLegacyScript) {
52
+ const extensions2 = Array.isArray(options.extension) ? options.extension.join(".") : [options.extension];
53
+ scriptSrc = `https://plausible.io/js/script.${extensions2}.js`;
54
+ } else {
55
+ scriptSrc = "https://plausible.io/js/script.js";
56
+ }
57
+ const initOptions = {};
58
+ if (options?.customProperties) initOptions.customProperties = options.customProperties;
59
+ if (options?.endpoint) initOptions.endpoint = options.endpoint;
60
+ if (options?.fileDownloads) initOptions.fileDownloads = options.fileDownloads;
61
+ if (options?.hashBasedRouting !== void 0) initOptions.hashBasedRouting = options.hashBasedRouting;
62
+ if (options?.autoCapturePageviews !== void 0) initOptions.autoCapturePageviews = options.autoCapturePageviews;
63
+ if (options?.captureOnLocalhost !== void 0) initOptions.captureOnLocalhost = options.captureOnLocalhost;
64
+ const scriptInput = !useNewScript && options?.domain ? {
65
+ "src": scriptSrc,
66
+ "data-domain": options.domain
67
+ } : {
68
+ src: scriptSrc
69
+ };
22
70
  return {
23
- scriptInput: {
24
- "src": options?.extension ? `https://plausible.io/js/script.${extensions2}.js` : "https://plausible.io/js/script.js",
25
- "data-domain": options?.domain
26
- },
27
- schema: import.meta.dev ? PlausibleAnalyticsOptions : void 0,
71
+ scriptInput,
72
+ schema: import.meta.dev ? PlausibleAnalyticsOptionsSchema : void 0,
28
73
  scriptOptions: {
29
74
  use() {
30
75
  return { plausible: window.plausible };
76
+ },
77
+ clientInit() {
78
+ window.plausible = window.plausible || function() {
79
+ (plausible.q = plausible.q || []).push(arguments);
80
+ }, plausible.init = plausible.init || function(i) {
81
+ plausible.o = i || {};
82
+ };
83
+ window.plausible.init(initOptions);
31
84
  }
32
85
  }
33
86
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nuxt/scripts",
3
3
  "type": "module",
4
- "version": "0.12.2",
4
+ "version": "0.13.0",
5
5
  "description": "Load third-party scripts with better performance, privacy and DX in Nuxt Apps.",
6
6
  "author": {
7
7
  "website": "https://harlanzw.com",
@@ -63,6 +63,9 @@
63
63
  "@unhead/vue": "^2.0.3"
64
64
  },
65
65
  "peerDependenciesMeta": {
66
+ "@googlemaps/markerclusterer": {
67
+ "optional": true
68
+ },
66
69
  "@stripe/stripe-js": {
67
70
  "optional": true
68
71
  },
@@ -91,7 +94,7 @@
91
94
  "pathe": "^2.0.3",
92
95
  "pkg-types": "^2.3.0",
93
96
  "sirv": "^3.0.2",
94
- "std-env": "^3.9.0",
97
+ "std-env": "^3.10.0",
95
98
  "ufo": "^1.6.1",
96
99
  "unplugin": "^2.3.10",
97
100
  "unstorage": "^1.17.1",
@@ -105,14 +108,14 @@
105
108
  "@nuxt/test-utils": "3.19.2",
106
109
  "@paypal/paypal-js": "^9.0.1",
107
110
  "@types/semver": "^7.7.1",
108
- "@typescript-eslint/typescript-estree": "^8.46.0",
111
+ "@typescript-eslint/typescript-estree": "^8.46.1",
109
112
  "@vue/test-utils": "^2.4.6",
110
113
  "acorn-loose": "^8.5.2",
111
114
  "bumpp": "^10.3.1",
112
115
  "changelogen": "^0.6.2",
113
116
  "eslint": "^9.37.0",
114
117
  "eslint-plugin-n": "^17.23.1",
115
- "happy-dom": "^20.0.0",
118
+ "happy-dom": "^20.0.2",
116
119
  "knitwork": "^1.2.0",
117
120
  "nuxt": "^4.1.3",
118
121
  "playwright-core": "^1.56.0",
@@ -120,9 +123,9 @@
120
123
  "typescript": "5.9.3",
121
124
  "vitest": "^3.2.4",
122
125
  "vue": "^3.5.22",
123
- "vue-router": "^4.5.1",
126
+ "vue-router": "^4.6.2",
124
127
  "vue-tsc": "^3.0.9",
125
- "@nuxt/scripts": "0.12.2"
128
+ "@nuxt/scripts": "0.13.0"
126
129
  },
127
130
  "resolutions": {
128
131
  "@nuxt/scripts": "workspace:*"
@@ -1 +0,0 @@
1
- {"id":"e404bf6c-6cc5-4a5a-bd29-546b71b82a4b","timestamp":1760342368989,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}