Skip to content

fix(gtm): broken onBeforeGtmStart arguments - #494

Merged
harlan-zw merged 4 commits into
nuxt:mainfrom
endorfin:main
Sep 22, 2025
Merged

fix(gtm): broken onBeforeGtmStart arguments#494
harlan-zw merged 4 commits into
nuxt:mainfrom
endorfin:main

Conversation

@endorfin

@endorfinendorfin commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

🔗 Linked issue

Followup on #392

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

  • Fix gtag function to use arguments object instead of rest parameters for GTM compatibility
  • Add documentation example showing consent mode configuration

- Fix dataLayer initialization by moving it inside gtag function
- Add onBeforeGtmStart callback option for custom initialization
- Ensure dataLayer exists before each gtag call to prevent errors
- Add documentation example showing consent mode configuration
Fixes potential race condition where dataLayer might not be initialized
when onBeforeGtmStart callback is executed.
@vercel

vercelBot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

@endorfin is attempting to deploy a commit to the Nuxt Team on Vercel.

A member of the Team first needs to authorize it.

@endorfinendorfin mentioned this pull request Sep 9, 2025
6 tasks
@pkg-pr-new

pkg-pr-newBot commented Sep 9, 2025

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/nuxt/scripts/@nuxt/scripts@494

commit: 1e2e7d0

@harlan-zw

Copy link
Copy Markdown
Collaborator

Thanks for the PR! Can you please check the failing ci. Also I'll get @huang-julien to review this (if he's available).

@huang-julienhuang-julien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Can you provide a minimal reproduction ? I've been using the GTM debugger and the piece of code provided in the previous PR seems to work correctly

- Fix gtag function in onBeforeGtmStart hook to use native arguments object
- GTM DataLayer expects Arguments object, not Array for proper event processing
- Enables consent settings to be correctly processed before GTM initialization
- Add ESLint disable comment for prefer-rest-params rule
@endorfin

Copy link
Copy Markdown
ContributorAuthor

GTM onBeforeGtmStart Fix - Technical Analysis

Initial Hypothesis vs. Reality

My initial assumption was that the issue was related to the DataLayer not being properly initialized when the onBeforeGtmStart hook was called. However, after debugging with console logging, this proved to be incorrect.

The Real Root Cause

The problem was related to JavaScript's type system and Google Tag Manager's internal event processing:

Working External Implementation:

functiongtag(){dataLayer.push(arguments);}

Console Output:Arguments(3) ["consent", "default", {ad_storage: "denied", ...}]

Broken Internal Implementation:

functiongtag(...args){dataLayer.push(args);}

Console Output:Array(3) ["consent", "default", {ad_storage: "denied", ...}]

Why This Difference Matters

Google Tag Manager's DataLayer specifically expects each gtag call to be pushed as an Arguments object, not a regular JavaScript Array. While both contain identical data, they have different internal types:

  1. Arguments Object: Special array-like object with properties GTM recognizes
  2. Array Object: Regular JavaScript array that GTM's parser handles differently

When using rest parameters (...args), JavaScript converts parameters into a standard Array. When using native arguments, JavaScript preserves the special Arguments type that GTM expects.

Key Takeaway

This was not a timing, initialization, or DataLayer availability issue. It was a pure type compatibility problem between JavaScript's modern rest parameters and Google Tag Manager's legacy API expectations.

The bug was difficult to diagnose because the data appeared identical in console logs, but the underlying object types were different enough to break GTM's internal consent processing.

Solution

The fix ensures that GTM receives exactly the data type it expects by using the native arguments object instead of rest parameters, allowing consent settings to be properly processed during the initialization phase.

The example code was missing the gtag parameter in the onBeforeGtmStart
callback function, which would cause a ReferenceError when trying to
use gtag() for
@endorfinendorfin changed the title fix(gtm): move dataLayer initialization into gtag functionfix(gtm): fix onBeforeGtmStart gtag function using arguments objectSep 10, 2025
@endorfinendorfin changed the title fix(gtm): fix onBeforeGtmStart gtag function using arguments objectfix(gtm): onBeforeGtmStart gtag function using arguments objectSep 10, 2025

@huang-julienhuang-julien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks !
I'm not sure why but there was a reason I didn't move GTM to arguments for gtag. I think it didn't work at that time (but did for GA which requiredarguments instead of args.
Looks like an unmentionned breaking change on GTM

@harlan-zwharlan-zw changed the title fix(gtm): onBeforeGtmStart gtag function using arguments objectfix(gtm): broken onBeforeGtmStart argumentsSep 22, 2025
@harlan-zw

harlan-zw commented Sep 22, 2025

Copy link
Copy Markdown
Collaborator

Thanks for your help with this, much appreicated.

@harlan-zw
harlan-zw merged commit 1edcd3d into nuxt:mainSep 22, 2025
3 of 5 checks passed
zizzfizzix pushed a commit to zizzfizzix/nuxt-scripts that referenced this pull request Mar 5, 2026
Co-authored-by: Harlan Wilton <harlan@harlanzw.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@endorfin@harlan-zw@huang-julien