Skip to content

fix(gtm): don't declare dataLayer on the global Window (1.x backport) - #865

Merged
harlan-zw merged 1 commit into
1.xfrom
fix/gtm-global-datalayer-conflict-1x
Aug 18, 2026
Merged

fix(gtm): don't declare dataLayer on the global Window (1.x backport)#865
harlan-zw merged 1 commit into
1.xfrom
fix/gtm-global-datalayer-conflict-1x

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Backport of #855 to the 1.x release line. Fixes #852 on 1.x.

❓ Type of change

  • 🐞 Bug fix (a non-breaking change that fixes an issue)

📚 Description

Straight cherry-pick of a6d763e, no conflicts and no drift. 1.x still exports the deprecated GoogleTagManagerConsent alias that main dropped, but the cherry-pick does not touch that line.

The GTM registry augmented the global Window with the whole GoogleTagManagerApi, including a required dataLayer. That made the package irreconcilable with any other package that declares Window.dataLayer, most commonly @gtm-support/core, the engine behind @gtm-support/vue-gtm. The two declarations merge into one Window, which then fails this package's own extends clause. TypeScript reports TS2430 at every one of the consumer's own Window augmentations, and the consumer cannot suppress it because neither declaration is theirs.

Making dataLayer optional does not fix it. Array<T>.push is (...items: T[]) => number, while DataLayerPush's first overload starts with (command: string, ...), so a foreign element type stays incompatible.

The fix declares only the member that is genuinely global and unambiguous:

-  interface Window extends GoogleTagManagerApi {}
+  interface Window extends Pick<GoogleTagManagerApi, 'google_tag_manager'> {}

GoogleTagManagerApi itself is unchanged, so useScriptGoogleTagManager() and its proxy keep dataLayer typed. The registry never read the global declaration for dataLayer anyway: it reads (window as any)[dataLayerName], because the name is configurable through the l / dataLayer options. window.google_tag_manager is read directly in use(), which is why that member stays.

This is a type-level change only. Zero runtime bytes.

📝 Checklist

  • I have linked an issue or discussion.
  • I have added tests.

test/types/global-window.test-d.ts guards the regression. On this branch it fails against the old declaration and passes against the fix.

On 1.x: pnpm vitest run --project typecheck passes (46 tests, no type errors), pnpm typecheck clean, pnpm lint clean.

Co-authored-by: Harlan Wilton <harlan@harlanzw.com>
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview Aug 18, 2026 4:38am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ae9fdadc-9011-492d-9a61-09da81ac082c

📥 Commits

Reviewing files that changed from the base of the PR and between d4d3099 and 8c8e881.

📒 Files selected for processing (2)
  • packages/script/src/runtime/registry/google-tag-manager.ts
  • test/types/global-window.test-d.ts

Included review availability: Your plan includes up to 4 reviews per rolling hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The global Window augmentation now exposes only google_tag_manager from GoogleTagManagerApi. It no longer declares the configurable global dataLayer property. Type-level tests verify that Window.dataLayer is absent, Window.google_tag_manager remains available, and the exported Google Tag Manager API retains callable dataLayer.push support.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 8c8e8

This localized type-only fix removes the conflicting global Window.dataLayer declaration while preserving the intended Google Tag Manager typings. The reported checks pass, and no actionable merge-blocking risk remains beyond normal review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the GTM fix: removing the global Window dataLayer declaration in the 1.x backport.
Description check ✅ Passed The description explains the TypeScript compatibility issue, the type-only fix, preserved API typing, regression test, and validation results.
Linked Issues check ✅ Passed The changes remove the conflicting global Window dataLayer declaration while preserving google_tag_manager and GoogleTagManagerApi dataLayer typing as required by issue #852.
Out of Scope Changes check ✅ Passed The source change and regression test directly support the linked issue and stated backport objective; no unrelated changes are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/gtm-global-datalayer-conflict-1x

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 8c8e881

@harlan-zw
harlan-zw merged commit 77f1e40 into 1.x Aug 18, 2026
17 checks passed
@harlan-zw
harlan-zw deleted the fix/gtm-global-datalayer-conflict-1x branch August 18, 2026 04:43
Sign up for free to 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.

2 participants