Event Tracking Overview
TikTok event tracking captures user actions on your website or app, enabling conversion measurement, audience building, and campaign optimization.
Event Types
| Type | Description | Use Case |
|---|---|---|
| Standard Events | Pre-defined by TikTok | Campaign optimization, best match quality |
| Custom Events | User-defined events | Unique business actions not in standard set |
| Automatic Events | PageView (auto-tracked) | Basic site navigation |
Standard Events
TikTok recommends using standard events for best campaign performance.
Ecommerce Events
CompletePayment
Fires when a purchase is completed.
ttq.track('CompletePayment', {
value: 199.98,
currency: 'USD',
order_id: 'ORDER_12345',
content_type: 'product',
contents: [
{
content_id: 'SKU_123',
content_name: 'Blue Widget',
quantity: 2,
price: 99.99
}
]
});
Required Parameters:
value- Total transaction valuecurrency- Three-letter currency code (USD, EUR, etc.)
Recommended Parameters:
order_id- Unique transaction identifiercontents- Array of purchased products
ViewContent
Fires when a user views a product or content page.
ttq.track('ViewContent', {
content_type: 'product',
content_id: 'SKU_123',
content_name: 'Blue Widget',
content_category: 'Widgets',
value: 99.99,
currency: 'USD'
});
Use Cases:
- Product detail pages
- Blog post views
- Video content views
- Service landing pages
AddToCart
Fires when a product is added to cart.
ttq.track('AddToCart', {
content_type: 'product',
content_id: 'SKU_123',
content_name: 'Blue Widget',
quantity: 2,
price: 99.99,
value: 199.98,
currency: 'USD'
});
Implementation Example:
// On add to cart button click
document.getElementById('add-to-cart-btn').addEventListener('click', function() {
var productId = this.dataset.productId;
var productName = this.dataset.productName;
var price = parseFloat(this.dataset.price);
var quantity = parseInt(document.getElementById('quantity').value);
ttq.track('AddToCart', {
content_type: 'product',
content_id: productId,
content_name: productName,
quantity: quantity,
price: price,
value: price * quantity,
currency: 'USD'
});
});
InitiateCheckout
Fires when checkout process begins.
ttq.track('InitiateCheckout', {
value: 199.98,
currency: 'USD',
content_type: 'product',
contents: [
{
content_id: 'SKU_123',
quantity: 2,
price: 99.99
},
{
content_id: 'SKU_456',
quantity: 1,
price: 49.99
}
]
});
Trigger Points:
- Click "Checkout" button
- Navigate to checkout page
- Begin checkout flow
AddPaymentInfo
Fires when payment information is added.
ttq.track('AddPaymentInfo', {
value: 199.98,
currency: 'USD',
content_type: 'product'
});
Trigger Points:
- Payment method selected
- Credit card form completed
- PayPal authorization
PlaceAnOrder
Fires when order is placed (before payment confirmation).
ttq.track('PlaceAnOrder', {
value: 199.98,
currency: 'USD',
order_id: 'ORDER_12345',
content_type: 'product'
});
Lead Generation Events
SubmitForm
Fires on any form submission.
ttq.track('SubmitForm', {
content_name: 'Contact Form',
content_category: 'Lead Generation'
});
Implementation:
document.getElementById('contact-form').addEventListener('submit', function(e) {
ttq.track('SubmitForm', {
content_name: 'Contact Form',
content_category: 'Lead Generation'
});
});
CompleteRegistration
Fires when user completes account registration.
ttq.track('CompleteRegistration', {
content_name: 'User Registration',
value: 0, // Assign value if applicable
currency: 'USD'
});
Contact
Fires when user initiates contact.
ttq.track('Contact', {
content_name: 'Live Chat Started'
});
Use Cases:
- Live chat initiated
- Phone click-to-call
- Email contact link clicked
Subscribe
Fires when user subscribes to newsletter or service.
ttq.track('Subscribe', {
content_name: 'Newsletter Subscription',
value: 0,
currency: 'USD'
});
Engagement Events
ClickButton
Fires on important button clicks.
ttq.track('ClickButton', {
content_name: 'Download Brochure'
});
Search
Fires when site search is performed.
ttq.track('Search', {
search_string: 'blue widgets',
content_type: 'product'
});
Implementation:
document.getElementById('search-form').addEventListener('submit', function(e) {
var searchQuery = document.getElementById('search-input').value;
ttq.track('Search', {
search_string: searchQuery,
content_type: 'product'
});
});
Download
Fires when file is downloaded.
ttq.track('Download', {
content_name: 'Product Catalog PDF',
content_type: 'document'
});
AddToWishlist
Fires when product added to wishlist.
ttq.track('AddToWishlist', {
content_id: 'SKU_123',
content_name: 'Blue Widget',
value: 99.99,
currency: 'USD'
});
Custom Events
Create custom events for actions not covered by standard events.
Creating Custom Events
ttq.track('CustomEventName', {
content_type: 'custom',
content_name: 'Description',
value: 0,
currency: 'USD'
});
Custom Event Examples
Video Play:
ttq.track('VideoPlay', {
content_name: 'Product Demo Video',
content_id: 'video_123',
video_length: 120 // seconds
});
Quiz Completion:
ttq.track('QuizCompleted', {
content_name: 'Product Recommendation Quiz',
quiz_score: 85,
result_category: 'Advanced User'
});
Size Guide Opened:
ttq.track('SizeGuideOpened', {
content_id: 'SKU_123',
content_name: 'Blue Widget'
});
Store Locator Used:
ttq.track('StoreLocatorSearch', {
search_location: 'New York, NY',
stores_found: 5
});
Custom Event Best Practices
- Use descriptive names - Clear action description
- Consistent naming - Use camelCase or snake_case consistently
- Include relevant parameters - Add context data
- Document custom events - Maintain event catalog
- Prefer standard events - Better optimization than custom
Event Parameters
Required Parameters
| Event | Required Parameters |
|---|---|
| CompletePayment | value, currency |
| AddToCart | content_id or content_name |
| ViewContent | content_id or content_name |
| InitiateCheckout | value, currency |
Common Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
value |
Number | Monetary value | 99.99 |
currency |
String | ISO currency code | "USD" |
content_type |
String | Type of content | "product" |
content_id |
String | Product/content ID | "SKU_123" |
content_name |
String | Product/content name | "Blue Widget" |
content_category |
String | Category | "Widgets" |
quantity |
Number | Item quantity | 2 |
price |
Number | Unit price | 99.99 |
order_id |
String | Transaction ID | "ORDER_12345" |
search_string |
String | Search query | "blue widgets" |
Contents Array
For multiple items:
contents: [
{
content_id: 'SKU_123',
content_name: 'Blue Widget',
quantity: 2,
price: 99.99
},
{
content_id: 'SKU_456',
content_name: 'Red Widget',
quantity: 1,
price: 49.99
}
]
Advanced Event Implementation
Dynamic Product Data
Using data attributes:
<button
class="add-to-cart"
data-product-id="SKU_123"
data-product-name="Blue Widget"
data-product-price="99.99"
data-product-category="Widgets">
Add to Cart
</button>
<script>
document.querySelectorAll('.add-to-cart').forEach(function(button) {
button.addEventListener('click', function() {
ttq.track('AddToCart', {
content_type: 'product',
content_id: this.dataset.productId,
content_name: this.dataset.productName,
price: parseFloat(this.dataset.productPrice),
content_category: this.dataset.productCategory,
quantity: 1,
value: parseFloat(this.dataset.productPrice),
currency: 'USD'
});
});
});
</script>
E-commerce Funnel Tracking
Complete shopping journey:
// 1. Product View
ttq.track('ViewContent', {
content_type: 'product',
content_id: 'SKU_123',
value: 99.99,
currency: 'USD'
});
// 2. Add to Cart
ttq.track('AddToCart', {
content_type: 'product',
content_id: 'SKU_123',
quantity: 2,
price: 99.99,
value: 199.98,
currency: 'USD'
});
// 3. Initiate Checkout
ttq.track('InitiateCheckout', {
value: 199.98,
currency: 'USD',
contents: [{
content_id: 'SKU_123',
quantity: 2,
price: 99.99
}]
});
// 4. Add Payment Info
ttq.track('AddPaymentInfo', {
value: 199.98,
currency: 'USD'
});
// 5. Complete Payment
ttq.track('CompletePayment', {
value: 199.98,
currency: 'USD',
order_id: 'ORDER_12345',
contents: [{
content_id: 'SKU_123',
quantity: 2,
price: 99.99
}]
});
Single Page Application (SPA) Events
React example:
import { useEffect } from 'react';
function ProductPage({ product }) {
useEffect(() => {
// Track page view when component mounts
if (typeof window.ttq !== 'undefined') {
window.ttq.track('ViewContent', {
content_type: 'product',
content_id: product.sku,
content_name: product.name,
value: product.price,
currency: 'USD'
});
}
}, [product]);
const handleAddToCart = () => {
if (typeof window.ttq !== 'undefined') {
window.ttq.track('AddToCart', {
content_type: 'product',
content_id: product.sku,
content_name: product.name,
quantity: 1,
price: product.price,
value: product.price,
currency: 'USD'
});
}
// Add to cart logic...
};
return (
<div>
<h1>{product.name}</h1>
<button to Cart</button>
</div>
);
}
Form Tracking
Multi-step form:
// Step 1: Form started
document.getElementById('step-1').addEventListener('submit', function(e) {
ttq.track('ClickButton', {
content_name: 'Lead Form - Step 1 Completed'
});
});
// Step 2: Contact info
document.getElementById('step-2').addEventListener('submit', function(e) {
ttq.track('ClickButton', {
content_name: 'Lead Form - Step 2 Completed'
});
});
// Final submission
document.getElementById('final-step').addEventListener('submit', function(e) {
ttq.track('SubmitForm', {
content_name: 'Lead Form - Completed',
content_category: 'Sales Lead'
});
ttq.track('CompleteRegistration', {
value: 50, // Assign lead value
currency: 'USD'
});
});
Video Engagement
var video = document.getElementById('product-video');
// Video started
video.addEventListener('play', function() {
ttq.track('ClickButton', {
content_name: 'Product Video - Play',
content_id: 'video_123'
});
});
// Video 25% watched
video.addEventListener('timeupdate', function() {
var percentWatched = (video.currentTime / video.duration) * 100;
if (percentWatched >= 25 && !video.dataset.tracked25) {
ttq.track('VideoView', {
content_name: 'Product Video - 25% Watched',
content_id: 'video_123',
watch_percentage: 25
});
video.dataset.tracked25 = 'true';
}
});
// Video completed
video.addEventListener('ended', function() {
ttq.track('VideoView', {
content_name: 'Product Video - Completed',
content_id: 'video_123',
watch_percentage: 100
});
});
Event Debugging
Enable Debug Mode
// Enable debug logging
ttq.load('YOUR_PIXEL_ID', {
debug: true
});
// Or enable after loading
ttq.instance('YOUR_PIXEL_ID').debug(true);
Manual Event Testing
// Test function
function testTikTokEvents() {
console.log('=== Testing TikTok Events ===');
// Test ViewContent
ttq.track('ViewContent', {
content_type: 'product',
content_id: 'TEST_SKU',
value: 1.00,
currency: 'USD'
});
console.log('✓ ViewContent fired');
// Test AddToCart
ttq.track('AddToCart', {
content_id: 'TEST_SKU',
quantity: 1,
price: 1.00,
value: 1.00,
currency: 'USD'
});
console.log('✓ AddToCart fired');
// Test CompletePayment
ttq.track('CompletePayment', {
value: 1.00,
currency: 'USD',
order_id: 'TEST_' + Date.now()
});
console.log('✓ CompletePayment fired');
console.log('=== Check Pixel Helper for confirmation ===');
}
// Run test
testTikTokEvents();
Validate Event Parameters
function validateCompletePayment(data) {
const errors = [];
if (!data.value || typeof data.value !== 'number') {
errors.push('Missing or invalid value parameter');
}
if (!data.currency || typeof data.currency !== 'string') {
errors.push('Missing or invalid currency parameter');
}
if (data.currency && data.currency.length !== 3) {
errors.push('Currency must be 3-letter ISO code');
}
if (errors.length > 0) {
console.error('Event validation errors:', errors);
return false;
}
return true;
}
// Use before firing event
const eventData = {
value: 99.99,
currency: 'USD',
order_id: 'ORDER_12345'
};
if (validateCompletePayment(eventData)) {
ttq.track('CompletePayment', eventData);
}
Best Practices
Event Strategy
- Track full funnel - ViewContent → AddToCart → Checkout → Purchase
- Use standard events - Better optimization than custom
- Include all parameters - More data = better optimization
- Fire events once per action - Avoid duplicates
- Test before production - Use Test Events tool
Data Quality
- Send accurate values - Match actual transaction amounts
- Use correct currency - ISO 3-letter codes
- Include order IDs - For deduplication and reconciliation
- Match product IDs - Align with catalog if using
- Hash PII - Email, phone before sending
Performance
- Fire critical events only - Don't track everything
- Batch less critical events - Reduce network requests
- Use async loading - Don't block page load
- Deduplicate events - Same event from multiple triggers
Compliance
- Respect consent - Don't fire events without consent
- Hash PII - Never send plain text email/phone
- Use cookieless mode - If required by privacy laws
- Document events - For privacy policy and audits
Event Catalog Template
## TikTok Event Catalog
### Standard Events
| Event | Trigger | Parameters | Owner |
|-------|---------|-----------|-------|
| PageView | All pages | (auto) | Engineering |
| ViewContent | Product pages | content_id, value, currency | Engineering |
| AddToCart | Cart add | content_id, quantity, value | Engineering |
| InitiateCheckout | Checkout start | value, currency, contents | Engineering |
| CompletePayment | Order confirmation | value, currency, order_id, contents | Engineering |
### Custom Events
| Event | Trigger | Parameters | Owner | Notes |
|-------|---------|-----------|-------|-------|
| QuizCompleted | Quiz result page | quiz_name, score | Marketing | For engagement tracking |
| VideoView | Video 50% watched | video_id, percentage | Marketing | Product demos only |
Next Steps
- Implement events using code examples above
- Test events in Events Manager Test Events tool
- Verify in Pixel Helper - Check real-time firing
- Monitor Event Quality Score - Aim for 6.0+
- Set up server-side - Server-Side vs Client-Side