Skip to content

Đo lường: Google Tag Manager ​

Toàn hệ dùng một container duy nhất: GTM-MZ6DXZZ3. Khai ở đúng một chỗ cho mỗi cụm (app/env.public.ts), và mọi chỗ khác re-export từ đó.

CụmNạp GTMNạp ở đâu
www.conan.schoolcóapp/root.tsx, snippet trong <head> + <noscript> iframe
tokyo.conan.schoolcó (từ 09.09.2026)app/components/GoogleTagManager.tsx + app/lib/gtm.ts
admin, mam, play, video, docskhôngcông cụ nội bộ, không đo

Vì sao tokyo không chép được snippet của www ​

Ba khác biệt, và cả ba đều đổi cách viết mã:

Tokyo là SPA. Đổi trang không nạp lại tài liệu, nên lượt xem trang tự động của GTM chỉ nổ một lần trong cả phiên. GoogleTagManager.tsx vì thế tự đẩy page_view ở mỗi lần đổi đường dẫn. Thiếu điều này thì báo cáo nói mỗi người dùng xem đúng một trang rồi thôi, một con số trông hợp lý nên không ai nghi ngờ.

Cùng một ứng dụng phục vụ inside6.com. Đó là thương hiệu khác. initGtm() từ chối chạy khi host kết thúc bằng inside6.com; trộn hai tài sản đo lường vào một container thì không tách ra lại được.

Dev không đẩy vào container thật. import.meta.env.DEV chặn ở cùng chỗ đó.

Không có <noscript> iframe ở tokyo: không có JavaScript thì cả ứng dụng không chạy, nên không có gì để đo.

Luật: dataLayer không mang thông tin định danh ​

Chỉ user_id. Không email, không tên, không số điện thoại.

Mọi thứ đẩy vào dataLayer đều rời trình duyệt sang Google, và từ đó một tag cấu hình sai ở phía GTM là đủ để nó đi tiếp sang bên thứ ba, trong khi mã nguồn không có gì đổi để mà rà ra. Cần ghép danh tính thì ghép ở phía sau bằng user_id, nơi dữ liệu còn nằm trong tay mình.

Ba chỗ hỏng đã có thật (rà soát 09.09.2026) ​

  1. tokyo khai GTM_ID mà không nạp gì. Hằng số nằm trong env.public.ts nhiều tháng, không file nào nạp gtm.js. Cụm trông như đã cài, đây là loại hỏng tệ nhất: không có lỗi, không có trang trắng, chỉ có một tập dữ liệu bằng không mà không ai đi tìm.
  2. www khai container ở hai file cùng được import. env.public.ts (thời Next, @/) và app/env.public.ts (~/) cùng khai GTM-MZ6DXZZ3. Trùng giá trị nên vô hình, cho tới ngày đổi container, sửa một bản, và một nửa số trang lặng lẽ báo về container cũ. Đã sửa: bản gốc export { GTM_ID } from './app/env.public'.
  3. Email và tên người học đi vào dataLayer. hooks/useActivityTracker.ts đẩy user_email, $email, $name trong session_start và identify_user. Đã gỡ, chỉ còn user_id.

Còn một mảnh chưa dọn: www.conan.school/components/tracking/GoogleTagManager.tsx là bản GTM viết cho Next (import Script from 'next/script', mà next/script không nằm trong bảng alias của vite.config.ts, import là build gãy). Không ai dùng, nhưng nó chép lại đúng snippet đang chạy, nên người sau vào "sửa GTM" rất dễ sửa nhầm bản chết.

Gác ​

bash
npm run check:analytics

Chạy trong job guards của CI. Ba điều: mỗi cụm khai container ở nhiều nhất một file; cụm nào khai thì phải có chỗ nạp thật googletagmanager.com/gtm.js; và ruột của mọi dataLayer.push(…) / trackEvent(…) không chứa khoá định danh. Gác chỉ soi ruột của lượt đẩy chứ không soi cả file, một trang nói về số điện thoại trong nội dung không phải là một trang gửi số điện thoại sang Google, và một gác kêu ở đó là một gác người ta học cách bỏ qua.

Gác dùng git grep --untracked: file vừa thêm mà chưa commit vẫn là mã sắp chạy. Không có cờ đó thì gác bỏ qua đúng những file mà PR đang thêm vào, tức xanh ở đúng lần duy nhất nó cần đỏ.

Tài liệu nội bộ nền tảng Conan School.