Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/script/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,14 @@ export default defineNuxtModule<ModuleOptions>({
: undefined,
} as any

// Build-time constant: `__NUXT_SCRIPTS_DEBUG__` is replaced inline by the
// bundler, so debug branches DCE away in production when `debug: false`.
const debugConst = JSON.stringify(!!config.debug)
nuxt.options.vite ||= {}
nuxt.options.vite.define = { ...nuxt.options.vite.define, __NUXT_SCRIPTS_DEBUG__: debugConst }
nuxt.options.nitro ||= {}
nuxt.options.nitro.replace = { ...nuxt.options.nitro.replace, __NUXT_SCRIPTS_DEBUG__: debugConst }

// Register proxy handler unconditionally. The handler rejects unknown domains
// at runtime, so it's safe to register even when no scripts use proxy.
const scriptsBase = config.prefix || '/_scripts'
Expand Down
53 changes: 53 additions & 0 deletions packages/script/src/runtime/composables/useScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { injectHead, onNuxtReady, useHead, useNuxtApp, useRuntimeConfig } from '
import { markRaw, ref } from 'vue'
// @ts-expect-error virtual template
import { resolveTrigger } from '#build/nuxt-scripts-trigger-resolver'
import { debugEnabled } from '../debug'
import { logger } from '../logger'

type NuxtScriptsApp = ReturnType<typeof useNuxtApp> & {
Expand Down Expand Up @@ -293,6 +294,58 @@ export function useScript<T extends Record<symbol | string, any> = Record<symbol
return reloaded.load()
}
nuxtApp.$scripts[id] = instance

// Debug logging: emit a structured log per script lifecycle event when debug
// is enabled at build-time (or in dev). Tagged with registryKey when present
// (e.g. `googleTagManager`), else the script id (src/key).
if (import.meta.client && debugEnabled) {
const registryKey = options?.devtools?.registryKey as string | undefined
const src = (input as any)?.src
const trigger = options?.trigger
const loadedFrom = options?.devtools?.loadedFrom as string | undefined
const ctx = {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
id: instance.id,
...(registryKey ? { registryKey } : {}),
...(src ? { src } : {}),
...(loadedFrom ? { loadedFrom } : {}),
}
const log = logger.withTag(registryKey || instance.id)
const t0 = performance.now()
let tLoadStart = 0
log.debug('registered', {
...ctx,
trigger: typeof trigger === 'object' ? (trigger instanceof Promise ? 'promise' : JSON.stringify(trigger)) : trigger,
})
options.head.hooks.hook('script:updated', (entry) => {
if (entry.script.id !== instance.id)
return
const status = entry.script.status
const elapsed = Math.round(performance.now() - t0)
if (status === 'loading')
tLoadStart = performance.now()
const payload: Record<string, any> = { ...ctx, status, elapsedMs: elapsed }
if (status === 'loaded' && tLoadStart)
payload.loadMs = Math.round(performance.now() - tLoadStart)
const fn = status === 'error' ? log.warn : log.debug
fn(`status: ${status}`, payload)
})
const _origLoad = instance.load
instance.load = () => {
log.debug('load() called', ctx)
return _origLoad()
}
const _origRemove = instance.remove
instance.remove = () => {
log.debug('remove() called', ctx)
return _origRemove()
}
const _origReload = instance.reload
instance.reload = async () => {
log.debug('reload() called', ctx)
return _origReload()
}
}

// used for devtools integration
if (import.meta.dev && import.meta.client) {
if (exists) {
Expand Down
4 changes: 4 additions & 0 deletions packages/script/src/runtime/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare const __NUXT_SCRIPTS_DEBUG__: boolean

export const debugEnabled: boolean
= typeof __NUXT_SCRIPTS_DEBUG__ !== 'undefined' && __NUXT_SCRIPTS_DEBUG__
4 changes: 4 additions & 0 deletions packages/script/src/runtime/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { createConsola } from 'consola'
import { debugEnabled } from './debug'

export const logger = createConsola({
// 4 = debug, 3 = info (consola defaults). Lift the threshold so `logger.debug`
// fires when debug is opted-in at build time or in dev.
level: debugEnabled ? 4 : 3,
defaults: {
tag: 'nuxt-scripts',
},
Expand Down
7 changes: 7 additions & 0 deletions packages/script/src/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ export type NuxtUseScriptOptions<T extends Record<symbol | string, any> = {}> =
* @internal
*/
registryMeta?: Record<string, string>
/**
* Source location (file:line:col) the script was registered from, captured
* via dev-only stack-trace parsing in `useRegistryScript`. Surfaced in
* debug logs and Nuxt DevTools.
* @internal
*/
loadedFrom?: string
/**
* Known third-party domains this script communicates with.
* @internal
Expand Down
Loading