Google Tag Manager Kodunu functions.php ile WordPress’e Ekleme
Google Tag Manager’ı WordPress sitenize eklemek için eklenti kurmak zorunda değilsiniz. Doğrudan functions.php dosyasına birkaç satır kod ekleyerek bunu temiz ve performanslı bir şekilde yapabilirsiniz. Bu yazıda GTM kodunu WordPress’e doğru şekilde nasıl entegre edeceğinizi, farklı senaryolara göre nasıl özelleştireceğinizi ve dikkat etmeniz gereken noktaları ele alacağız.
Google Tag Manager Neden functions.php ile Eklenmeli?
Pek çok WordPress kullanıcısı GTM kodunu tema dosyalarına manuel olarak yapıştırır ya da bunun için ayrı bir eklenti kurar. Her iki yaklaşımın da ciddi dezavantajları var.
Manuel yerleştirme yöntemiyle tema güncellendiğinde tüm değişiklikler kaybolur. Eklenti yöntemi ise gereksiz bir bağımlılık oluşturur; basit bir kod parçası için ekstra bir eklenti aktif tutmak hem güvenlik riski taşır hem de performansı etkiler.
functions.php yöntemiyle şu avantajları elde edersiniz:
- Eklentisiz çalışır: Ekstra kaynak yükü olmaz
- Tema güncellemelerinden etkilenmez: Child theme kullanıldığında kalıcıdır
- Merkezi yönetim: Tüm kod enjeksiyonlarınızı tek bir dosyada tutarsınız
- Koşullu yükleme imkânı: Belirli sayfalarda GTM’i devre dışı bırakabilirsiniz
- Çoklu konteyner desteği: Birden fazla GTM konteyneri kolayca yönetilir
Temel GTM Entegrasyonu
Google Tag Manager, iki ayrı kod parçası gerektirir. İlki etiketinin hemen içine, ikincisi ise etiketinin hemen açılışından sonra yerleştirilmelidir.
İşte en temel haliyle bu entegrasyonu gerçekleştiren fonksiyon:
// functions.php
function gtm_head_code() {
$gtm_id = 'GTM-XXXXXXX'; // GTM konteyner ID'nizi buraya yazın
?>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<?php echo esc_attr($gtm_id); ?>');</script>
<!-- End Google Tag Manager -->
<?php
}
add_action('wp_head', 'gtm_head_code', 1);
function gtm_body_code() {
$gtm_id = 'GTM-XXXXXXX';
?>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?php echo esc_attr($gtm_id); ?>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<?php
}
add_action('wp_body_open', 'gtm_body_code', 1);
Burada wp_body_open hook’u WordPress 5.2 ile birlikte geldi. Temanız bu hook’u destekliyorsa açılışından hemen sonraya kod enjekte edebilirsiniz. Eğer temanız bunu desteklemiyorsa alternatif bir yaklaşım gerekir, bunu ilerleyen bölümlerde ele alacağız.
GTM ID’yi Sabit Kod Yerine Değişkende Tutma
Yukarıdaki örnekte GTM ID’sini iki farklı fonksiyonda tekrar ettik. Bu, ileride ID değiştiğinde iki yeri güncellemenizi gerektirir. Daha temiz bir yaklaşım için sabiti tanımlayın:
// functions.php - GTM ID sabit tanımı
define('GTM_CONTAINER_ID', 'GTM-XXXXXXX');
function gtm_head_code() {
if (!defined('GTM_CONTAINER_ID') || empty(GTM_CONTAINER_ID)) {
return;
}
$gtm_id = GTM_CONTAINER_ID;
?>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<?php echo esc_attr($gtm_id); ?>');</script>
<!-- End Google Tag Manager -->
<?php
}
add_action('wp_head', 'gtm_head_code', 1);
function gtm_body_code() {
if (!defined('GTM_CONTAINER_ID') || empty(GTM_CONTAINER_ID)) {
return;
}
$gtm_id = GTM_CONTAINER_ID;
?>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?php echo esc_attr($gtm_id); ?>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<?php
}
add_action('wp_body_open', 'gtm_body_code', 1);
Daha da iyisi, GTM ID’yi WordPress seçeneklerinde (options) saklayarak yönetim panelinden güncellenebilir hale getirebilirsiniz. Ancak bu yazının kapsamında biz sabit kod yaklaşımını kullanıyoruz.
wp_body_open Hook’u Desteklemeyen Temalar İçin Çözüm
Bazı eski temalar veya kötü yazılmış üçüncü taraf temalar wp_body_open hook’unu içermez. Bu durumda noscript kodunu wp_head‘in sonuna ya da wp_footer‘ın başına ekleyebilirsiniz. GTM belgelerine göre bu ideal değildir ama çalışmaya devam eder.
// wp_body_open desteklenmiyor mu? İşte alternatif:
function gtm_body_code_fallback() {
if (!defined('GTM_CONTAINER_ID') || empty(GTM_CONTAINER_ID)) {
return;
}
$gtm_id = GTM_CONTAINER_ID;
?>
<!-- Google Tag Manager (noscript) - fallback -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?php echo esc_attr($gtm_id); ?>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<?php
}
// wp_body_open varsa onu kullan, yoksa wp_footer'a ekle
if (function_exists('wp_body_open')) {
add_action('wp_body_open', 'gtm_body_code_fallback', 1);
} else {
add_action('wp_footer', 'gtm_body_code_fallback', 1);
}
Eğer temanıza erişiminiz varsa ve child theme kullanıyorsanız, header.php içindeki <body etiketinin hemen altına ekleyerek bu hook’u aktif edebilirsiniz.
GTM’i Belirli Sayfalardan Hariç Tutma
Gerçek dünyada her zaman GTM’i tüm sayfalara yüklemek istemezsiniz. Örneğin yönetim paneline giriş yapmış kullanıcılarda test verilerinin kirletilmemesi için GTM’i devre dışı bırakmak mantıklıdır. Ya da WooCommerce’in teşekkür sayfasında özel bir dönüşüm kodu çalıştırıp GTM’i kapatmak isteyebilirsiniz.
// Koşullu GTM yükleme - gelişmiş versiyon
function should_load_gtm() {
// Yöneticiler ve editörler için GTM yükleme
if (current_user_can('edit_posts')) {
return false;
}
// WordPress yönetim panelinde yükleme
if (is_admin()) {
return false;
}
// Login sayfasında yükleme
if (in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php'))) {
return false;
}
// Belirli bir sayfa ID'sinde yükleme (örnek: gizlilik politikası ID: 42)
if (is_page(42)) {
return false;
}
return true;
}
function gtm_head_code_conditional() {
if (!should_load_gtm()) {
return;
}
$gtm_id = GTM_CONTAINER_ID;
?>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<?php echo esc_attr($gtm_id); ?>');</script>
<?php
}
add_action('wp_head', 'gtm_head_code_conditional', 1);
WooCommerce İçin dataLayer Entegrasyonu
Eğer WooCommerce kullanıyorsanız, salt GTM kodu yeterli değildir. Enhanced Ecommerce takibi için dataLayer nesnesine ürün ve sipariş bilgilerini göndermanız gerekir. İşte temel bir WooCommerce dataLayer kurulumu:
// WooCommerce ürün sayfaları için dataLayer
function gtm_woocommerce_datalayer() {
if (!should_load_gtm()) {
return;
}
$data_layer = array();
// Genel sayfa bilgileri
$data_layer['pageType'] = 'other';
if (is_woocommerce()) {
if (is_product()) {
global $post;
$product = wc_get_product($post->ID);
if ($product) {
$data_layer['pageType'] = 'product';
$data_layer['productId'] = $product->get_id();
$data_layer['productName'] = $product->get_name();
$data_layer['productPrice'] = $product->get_price();
$data_layer['productSku'] = $product->get_sku();
// Kategori bilgisi
$categories = wp_get_post_terms($product->get_id(), 'product_cat');
if (!is_wp_error($categories) && !empty($categories)) {
$data_layer['productCategory'] = $categories[0]->name;
}
}
} elseif (is_shop()) {
$data_layer['pageType'] = 'shop';
} elseif (is_product_category()) {
$data_layer['pageType'] = 'category';
$category = get_queried_object();
if ($category) {
$data_layer['categoryName'] = $category->name;
}
} elseif (is_checkout()) {
$data_layer['pageType'] = 'checkout';
} elseif (is_order_received_page()) {
$data_layer['pageType'] = 'purchase';
// Sipariş bilgilerini dataLayer'a ekle
global $wp;
$order_id = absint($wp->query_vars['order-received']);
if ($order_id) {
$order = wc_get_order($order_id);
if ($order) {
$data_layer['orderId'] = $order->get_id();
$data_layer['orderTotal'] = $order->get_total();
$data_layer['currency'] = $order->get_currency();
}
}
} elseif (is_cart()) {
$data_layer['pageType'] = 'cart';
}
} elseif (is_front_page()) {
$data_layer['pageType'] = 'home';
} elseif (is_single()) {
$data_layer['pageType'] = 'post';
} elseif (is_page()) {
$data_layer['pageType'] = 'page';
}
// Kullanıcı bilgileri (giriş yapmışsa)
if (is_user_logged_in()) {
$current_user = wp_get_current_user();
$data_layer['userId'] = get_current_user_id();
$data_layer['userRole'] = implode(',', $current_user->roles);
}
?>
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push(<?php echo wp_json_encode($data_layer); ?>);
</script>
<?php
}
add_action('wp_head', 'gtm_woocommerce_datalayer', 2); // GTM'den sonra, önce değil
Bu kod wp_head hook’unda priority 2 ile çalışır. GTM’in priority 1 ile yüklendiğini hatırlayın, dolayısıyla dataLayer her zaman GTM scriptinden önce hazır olur.
Çoklu GTM Konteyneri Yönetimi
Bazı ajans senaryolarında tek bir WordPress sitesinde birden fazla GTM konteyneri çalıştırmanız gerekebilir. Örneğin biri genel site takibi için, biri müşteriye ait kod için kullanılabilir.
// Çoklu konteyner desteği
function gtm_multiple_containers() {
if (!should_load_gtm()) {
return;
}
$containers = array(
'GTM-XXXXXXX', // Ana konteyner
'GTM-YYYYYYY', // Müşteri konteyneri
);
foreach ($containers as $container_id) {
$container_id = sanitize_text_field($container_id);
if (empty($container_id)) {
continue;
}
?>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<?php echo esc_attr($container_id); ?>');</script>
<?php
}
}
add_action('wp_head', 'gtm_multiple_containers', 1);
Güvenlik ve Performans Notları
GTM kodunu functions.php ile eklerken dikkat etmeniz gereken birkaç önemli nokta var.
Sanitizasyon her zaman şart: GTM ID’leri kullanıcı girdisinden geliyorsa mutlaka esc_attr() veya sanitize_text_field() kullanın. Yukarıdaki örneklerin tamamında bunu uyguladık.
Önbellek uyumluluğu: W3 Total Cache, WP Rocket veya Cloudflare kullanıyorsanız, functions.php ile eklenen GTM kodu önbellek dosyalarına gömülür. Bu genellikle sorun değildir ancak GTM ID değiştirdiğinizde önbelleği temizlemeyi unutmayın.
Content Security Policy (CSP): Eğer sunucunuzda CSP başlıkları aktifse googletagmanager.com ve google-analytics.com domainlerini whitelist’e eklemeniz gerekebilir.
Child theme zorunluluğu: Bu kodları doğrudan temanın functions.php dosyasına eklerseniz tema güncellemelerinde kaybolur. Mutlaka child theme kullanın veya site genelinde geçerli bir mu-plugins dosyası oluşturun.
wp-config.php ile ortam kontrolü: Staging ve production ortamlarında farklı GTM ID’leri kullanmak için şu yaklaşımı tercih edebilirsiniz:
// wp-config.php veya functions.php başında
if (!defined('GTM_CONTAINER_ID')) {
// WP_ENV tanımlıysa production mı staging mi kontrol et
if (defined('WP_ENV') && WP_ENV === 'staging') {
define('GTM_CONTAINER_ID', 'GTM-STAGING1'); // Staging konteyneri
} else {
define('GTM_CONTAINER_ID', 'GTM-XXXXXXX'); // Production konteyneri
}
}
Bu sayede staging ortamında yanlışlıkla gerçek veriler toplamazsınız ve test süreçleriniz production analitiğinizi kirletmez.
GTM Kurulumunu Doğrulama
Kodu ekledikten sonra doğrulamanın birkaç yolu var:
- GTM Preview modu: Tag Manager arayüzünden “Preview” butonuna basın, sitenizi açın ve debug panelinin göründüğünü kontrol edin
- Tarayıcı DevTools: Elements sekmesinde
içinde GTM scriptini arayın - Chrome Tag Assistant: Google’ın resmi uzantısıyla GTM durumunu kontrol edin
- Google Analytics Realtime raporu: GTM üzerinden GA kuruluysa anlık kullanıcı görmeli misiniz test edin
dataLayerkonsol kontrolü: Tarayıcı konsolundawindow.dataLayeryazın ve beklenen verilerin geldiğini doğrulayın
Konsol çıktısı şuna benzemelidir:
# Tarayıcı konsolunda çalıştırın:
# > window.dataLayer
# Beklenen çıktı örneği:
# [
# { pageType: "product", productId: 123, productName: "Ürün Adı", ... },
# { event: "gtm.js", "gtm.start": 1234567890 }
# ]
Sık Yapılan Hatalar
yerine wp_head‘in sonuna ekleme: add_action('wp_head', 'fonksiyon', 99) gibi yüksek bir priority kullanırsanız GTM geç yüklenebilir ve bazı tetikleyicileri kaçırabilirsiniz. Priority değerini 1 tutun.
Noscript kısmını atlamak: Birçok sysadmin sadece JavaScript kodunu ekleyip noscript iframe’ini atlar. Bu, JavaScript devre dışı olan kullanıcıların takip edilememesine neden olur. Küçük bir kullanıcı kitlesi gibi görünse de bazı kurumsal ortamlarda JS bloke edilebilir.
dataLayer’ı GTM’den sonra tanımlamak: window.dataLayer nesnesi GTM script’inden önce hazır olmalı. Priority sıranızı buna göre ayarlayın.
ID doğrulaması yapmamak: GTM ID formatı her zaman GTM- ön ekiyle başlar ve ardından alfanümerik karakterler gelir. Yanlış formatta bir ID girilmesine karşı küçük bir doğrulama eklemek iyi bir pratiktir.
Sonuç
functions.php üzerinden GTM entegrasyonu, eklenti bağımlılığından kurtulmanın ve kodu merkezi olarak yönetmenin en temiz yoludur. Temel entegrasyondan başlayarak WooCommerce dataLayer entegrasyonuna, çoklu konteyner desteğine ve ortam bazlı yapılandırmaya kadar ölçeklenebilir bir yapı kurabilirsiniz.
En kritik nokta şu: Bu kodları mutlaka child theme functions.php dosyasına ya da özel bir mu-plugin dosyasına ekleyin. Ana tema dosyasına yapılan değişiklikler her güncellemede kaybolur ve bu tür kayıplar genellikle fark edilmeden günlerce veri toplanamadan geçer.
GTM kurulumunuzu production’a almadan önce her zaman staging ortamında test edin, dataLayer çıktısını konsol üzerinden doğrulayın ve GTM Preview modunu kullanın. Analitik veriler iş kararlarının temelini oluşturduğu için kötü kurulum, kötü kararlar demektir.
