Overview
This article covers implementing Google Tag Manager (GTM), Google Analytics 4 (GA4), Meta Pixel, LinkedIn Insight Tag, and other tracking tools. It is intended to be the source of truth for customers, analytics consultants, and developers who are configuring attribution and event tracking for Teachable schools.
NOTE: We recommend leveraging a direct integration wherever possible as opposed to the code snippet to simplify setup and possible tracking complexities.
Summary & Best Practices
Use native integrations wherever possible for broader support and easy-of-setup.
Avoid duplicating container IDs β prefer using only the integration.
Checkout pages do not allow custom code snippets β use the integrations to track sales attribution.
add_to_cart and purchase events are available in the data layer.
For advanced tracking, use GTM's built-in features and preview/debug mode to validate data layer pushes.
Code Snippets vs. Integrations
Teachable supports tracking tools via two mechanisms:
Code Snippets: Manually added through the "Code Snippets" settings in the admin.
Native Integrations: Enabled via the "App Hub" section in the admin dashboard (e.g., GTM, GA4, Meta Pixel, etc.).
Type | How It's Added | Where It Loads |
Code Snippet | Manually in Admin > Code Snippets | Most student-facing pages |
Integration | Admin > Integrations | Broadly across all pages, including Checkout |
Important: Due to security concerns, there are pages where the integration is present but the code snippet is not.
Page-Level Presence of Integrations and Snippets
0 = Neither present
1 = Integration only present
2 = Code Snippet + Integration Present
Page | GA4 | GTM | Meta Pixel | TikTok | Segment | ||
Landing Page (/) | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Sales Page (/p) | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Checkout (/checkout) | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Thank You Page | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Product Detail (/l) | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Course Index (/courses) | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Course Curriculum (/courses/enrolled/*) | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Lecture Player(/lectures) | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Student Profile, Address, Purchase History, Contact | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Coaching Enrolled | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
Coaching Milestones | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
Login / Signup / OTP | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Data Layer Events for Checkout & Purchase
Teachable fires 2 key data layer events to track checkout conversion:
add_to_cart: Fired when a user lands on the checkout
purchase: Fired after a customer completes a purchase
1. Add to Cart event data layer structure
window.dataLayer.push({ event: "add_to_cart", eventModel: { currency: "USD", value: "0.99", coupon: "null", tax: "0", items: [ { item_id: 1217085, item_name: "Sushi rolling technique", item_variant: "Sushi rolling technique", price: 0.99, quantity: 1 } ] }, gtm.uniqueEventId: 7 });
2. Purchase event data layer structure
window.dataLayer.push({ event: "purchase", eventModel: { transaction_id: "174719268", value: 0.99, tax: 7, currency: "USD", coupon: null, items: [ { item_id: "5450802", item_name: "Sushi rolling technique", item_variant: "99", price: 0.99, quantity: 1 } ] }, gtm.uniqueEventId: 9 });
GTM Container Duplication Behavior
If both the GTM integration and a manual code snippet are added with the same container ID, GTM will deduplicate automatically:
GTM detects existing containers and prevents loading the same container twice.
However, if different container IDs are added via:
App integration (e.g., GTM container ID in Teachable settings), and
A separate manual snippet in the header
Then two containers will load, which can result in duplicate events or parallel tracking setups.
Recommendation: Use only the GTM integration and avoid also adding the GTM container via code snippets.