@@ -6,6 +6,7 @@ import { injectHead, onNuxtReady, useHead, useNuxtApp, useRuntimeConfig } from '
66import { markRaw , ref } from 'vue'
77// @ts -expect-error virtual template
88import { resolveTrigger } from '#build/nuxt-scripts-trigger-resolver'
9+ import { debugEnabled } from '../debug'
910import { logger } from '../logger'
1011
1112type NuxtScriptsApp = ReturnType < typeof useNuxtApp > & {
@@ -293,6 +294,58 @@ export function useScript<T extends Record<symbol | string, any> = Record<symbol
293294 return reloaded . load ( )
294295 }
295296 nuxtApp . $scripts [ id ] = instance
297+
298+ // Debug logging: emit a structured log per script lifecycle event when debug
299+ // is enabled at build-time (or in dev). Tagged with registryKey when present
300+ // (e.g. `googleTagManager`), else the script id (src/key).
301+ if ( import . meta. client && debugEnabled ) {
302+ const registryKey = options ?. devtools ?. registryKey as string | undefined
303+ const src = ( input as any ) ?. src
304+ const trigger = options ?. trigger
305+ const loadedFrom = options ?. devtools ?. loadedFrom as string | undefined
306+ const ctx = {
307+ id : instance . id ,
308+ ...( registryKey ? { registryKey } : { } ) ,
309+ ...( src ? { src } : { } ) ,
310+ ...( loadedFrom ? { loadedFrom } : { } ) ,
311+ }
312+ const log = logger . withTag ( registryKey || instance . id )
313+ const t0 = performance . now ( )
314+ let tLoadStart = 0
315+ log . debug ( 'registered' , {
316+ ...ctx ,
317+ trigger : typeof trigger === 'object' ? ( trigger instanceof Promise ? 'promise' : JSON . stringify ( trigger ) ) : trigger ,
318+ } )
319+ options . head . hooks . hook ( 'script:updated' , ( entry ) => {
320+ if ( entry . script . id !== instance . id )
321+ return
322+ const status = entry . script . status
323+ const elapsed = Math . round ( performance . now ( ) - t0 )
324+ if ( status === 'loading' )
325+ tLoadStart = performance . now ( )
326+ const payload : Record < string , any > = { ...ctx , status, elapsedMs : elapsed }
327+ if ( status === 'loaded' && tLoadStart )
328+ payload . loadMs = Math . round ( performance . now ( ) - tLoadStart )
329+ const fn = status === 'error' ? log . warn : log . debug
330+ fn ( `status: ${ status } ` , payload )
331+ } )
332+ const _origLoad = instance . load
333+ instance . load = ( ) => {
334+ log . debug ( 'load() called' , ctx )
335+ return _origLoad ( )
336+ }
337+ const _origRemove = instance . remove
338+ instance . remove = ( ) => {
339+ log . debug ( 'remove() called' , ctx )
340+ return _origRemove ( )
341+ }
342+ const _origReload = instance . reload
343+ instance . reload = async ( ) => {
344+ log . debug ( 'reload() called' , ctx )
345+ return _origReload ( )
346+ }
347+ }
348+
296349 // used for devtools integration
297350 if ( import . meta. dev && import . meta. client ) {
298351 if ( exists ) {
0 commit comments