Meta — AdsPing dashboard setup

Sıfırdan üretime: AdsPing'e giriş yaptıktan sonra Meta Conversions API'yi bağlamak için adım adım rehber. Yaklaşık 5 dakika.

Bu sayfa AdsPing tarafındaki adımları anlatır. Meta Events Manager'da Pixel ID veya Access Token bulma için Meta — manual setup sayfasına bakın. Sitenize pb.js entegrasyonu için Meta — integration guide.

Önce

  • AdsPing hesabınız olmalı (yoksa kayıt olun)
  • Meta tarafında bir Pixel (Dataset) ve Business Manager erişimi olmalı — OAuth bunu otomatik tanır, manuel kuruluyorsanız Pixel ID + Conversions API Access Token lazım
  • Sitenizin alan adı (örn. acme.com)
1

Yeni pixel oluştur

Dashboard'da sol menüden Pixels'a tıklayın, sağ üstte + New pixel butonuyla wizard'ı açın.

URL: app.adsping.com/dashboard/pixels

Screenshot pending

Dashboard → Pixels sayfası, sağ üstte + New pixel butonu

Ekran görüntüsü: /dashboard/pixels — sağ üstteki + New pixel butonu vurgulanmış

Dashboard ana sayfası — sağ üst köşedeki + New pixel butonu yeni pixel wizard'ını başlatır
2

Domain bilgilerini gir

Wizard'ın ilk adımı: pixel adı + birincil domain + opsiyonel subdomain'ler.

  1. Pixel name — kendi referansınız için (örn. Acme Web)
  2. Primary domain — sitenizin apex domain'i (örn. acme.com). www öneki otomatik kapsanır.
  3. Subdomains (opsiyonel) — varsa app.acme.com, blog.… gibi
Screenshot pending

Wizard step 0 — Domain formu

Ekran görüntüsü: /dashboard/pixels/new wizard'ının Step 0 (Domain) ekranı, alanlar dolu örnek

Step 0 — pixel adı, birincil domain, opsiyonel subdomain alanları

Continue → wizard sonraki adıma geçer.

3

Plan seç

Bir abonelik planı seçin. 14 gün ücretsiz deneme ile başlar (ilk pixel).

Plan'a tıkladığınızda Stripe Checkout açılır, ödeme bilgilerini girersiniz. İlk pixel için 14 gün boyunca ödeme alınmaz; deneme süresi bitince seçtiğiniz plan ücreti otomatik tahsil edilir.

Screenshot pending

Wizard step 1 — plan seçimi

Ekran görüntüsü: /dashboard/pixels/new wizard'ının Step 1 (Plan) ekranı, 3 plan kartı yan yana

Step 1 — Starter / Growth / Scale tier kartları
Ödeme tamamlandıktan sonra otomatik olarak /dashboard/pixels/<id>?subscribed=1 URL'ine yönlendirilirsiniz — pixel detay sayfası.
4

Pixel detay sayfasına git

Pixel detayı 3 sekmeden oluşur: Report, Destinations, Settings.

Sekmelerin içeriği:

  • Report — Diagnostics kartı + son event'ler listesi
  • Destinations — Meta / TikTok / Google Ads kartları ve pipeline'lar
  • Settings — Install snippet + Allowed Domains + pixel ayarları
Screenshot pending

Pixel detay sayfası — 3 sekmeli yapı

Ekran görüntüsü: /dashboard/pixels/<id> — 3 sekmeli üst bar görünür, Destinations sekmesi seçili

Pixel detay — üstte Report / Destinations / Settings sekmeleri görünür
5

Meta'yı bağla

Destinations sekmesinde Meta (Facebook) kartına gidin. İki seçenek: OAuth veya manuel.

Seçenek A — OAuth (önerilen)

Meta kartında Connect with Facebook butonuna tıklayın. Facebook penceresi açılır, Business Manager hesabınızla giriş yapıp izin verirsiniz.

  • Otomatik: Meta Pixel ID
  • Otomatik: Conversions API Access Token (şifrelenmiş saklanır)
Screenshot pending

Meta destination kartı — Connect with Facebook butonu

Ekran görüntüsü: Meta kartının disconnected hâli, Connect with Facebook butonu

Destinations sekmesi → Meta (Facebook) kartı. Bağlanmamışsa Connect with Facebook butonu görünür

Seçenek B — Manuel

OAuth çalışmıyorsa (ajans Business Manager, custom rol, vs.) manuel giriş yapın:

  1. Meta Pixel ID — Events Manager → Data Sources → pixel detayında 15-16 haneli ID
  2. Conversions API Access Token — Events Manager → Settings → Conversions API → Generate Access Token
  3. Save → kart Connected olur
Screenshot pending

Meta destination kartı — manuel form alanları

Ekran görüntüsü: Meta kartı manuel formu, iki input dolu + Save butonu

Manuel modda: Meta Pixel ID + Conversions API Access Token alanları
Token bulma adımları için detaylı görsel rehber: Meta — manual setup.
6

Sitenize entegre edin

Önce stack'inizi seçin — her birinin entegrasyonu farklı.

Settings sekmesinden Install snippet'i kopyaladıktan sonra, sitenizin tipine göre aşağıdaki bölümlerden birini izleyin:

Sıralama her ikisinde de önemli: pb.js, Meta snippet'inin altına gelmelidir. pb.js, fbq'yu wrap'lemek için onun yüklü olmasını bekler — ters sıralamada server-side mirror çalışmaz, browser pixel + CAPI iki katı sayılır.

Stack 1 — Düz HTML / Vanilla JS

6.1 — Snippet'i sayfaya ekle

Sitenizdeki her sayfanın <head> bölümüne (veya bütün sayfaları kapsayan template'e — header.php, layout.html, vs.) şu iki blok'u bu sırayla ekleyin:

<!-- 1) Meta Pixel — varsa kalsın, yoksa Meta'nın resmi snippet'ini ekle -->
<script>
  !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;
  s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
  fbq('init','<META_PIXEL_ID>');
  fbq('track','PageView');
</script>

<!-- 2) AdsPing pb.js — Meta snippet'inin ALTINA -->
<script async src="https://api.adsping.io/pb.js" data-pixel-id="<PIXEL_ID>"></script>

6.2 — Event tetikleme

PageView otomatik fire'lanır. Diğer event'ler için form ve butonlara onclick / onsubmit handler'ları ekleyin. Mevcut fbq() çağrılarınız varsa hiçbir şey yapmanıza gerek yok — pb.js otomatik mirror eder.

Form gönderme → Lead:

<form id="contact-form" action="/iletisim" method="post">
  <input name="email" type="email" required>
  <input name="phone" type="tel" required>
  <textarea name="message"></textarea>
  <button type="submit">Gönder</button>
</form>

<script>
  document.getElementById('contact-form').addEventListener('submit', function() {
    fbq('track', 'Lead', {
      content_name: 'İletişim Formu',
      value: 0,
      currency: 'TRY'
    });
  });
</script>

Ürün/hizmet sayfası → ViewContent:

<!-- /hizmetler/sac-ekimi.html gibi bir ürün sayfasının <head>'ine -->
<script>
  fbq('track', 'ViewContent', {
    content_name: 'Saç Ekimi',
    content_ids: ['SVC-HAIR-001'],
    content_type: 'product',
    value: 2500,
    currency: 'TRY'
  });
</script>

WhatsApp / telefon → Contact:

<a href="https://wa.me/902121234567"
   onclick="fbq('track','Contact',{content_name:'WhatsApp CTA'}); return true;">
  WhatsApp ile İletişim
</a>

<a href="tel:+902121234567"
   onclick="fbq('track','Contact',{content_name:'Header Phone'}); return true;">
  +90 (212) 123 45 67
</a>

Form submit AJAX ile yapılıyorsa:

document.getElementById('contact-form').addEventListener('submit', async function(e) {
  e.preventDefault();
  const data = new FormData(this);

  // Event'i AJAX BAŞARILI olduktan sonra fire et,
  // başarısız submission'da spam'lemeyelim:
  try {
    const res = await fetch('/api/contact', { method: 'POST', body: data });
    if (res.ok) {
      fbq('track', 'Lead', { content_name: 'İletişim Formu' });
    }
  } catch (err) { /* … */ }
});
Otomatik Advanced Matching: Form içindeki <input type="email"> ve <input type="tel"> alanları submit anında otomatik olarak SHA-256'lanıp Meta'ya gönderilir — ek kod yazmanıza gerek yok. iOS Safari ITP altında match quality'yi belirgin şekilde artırır.

Stack 2 — React / Next.js

6.1 — Script'i layout'a ekle

Next.js App Router'da app/layout.tsx:

// app/layout.tsx
import Script from "next/script";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="tr">
      <head>
        {/* 1) Meta Pixel — pb.js'ten ÖNCE */}
        <Script id="fb-pixel" strategy="afterInteractive">
          {`
            !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
            n.callMethod.apply(n,arguments):n.queue.push(arguments)};
            if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];
            t=b.createElement(e);t.async=!0;t.src=v;
            s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
            (window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
            fbq('init','<META_PIXEL_ID>');
            fbq('track','PageView');
          `}
        </Script>

        {/* 2) AdsPing pb.js — Meta snippet'inin ALTINDA */}
        <Script
          src="https://api.adsping.io/pb.js"
          data-pixel-id="<PIXEL_ID>"
          strategy="afterInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Pages Router kullanıyorsanız pages/_document.tsx:

// pages/_document.tsx
import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="tr">
      <Head>
        <script
          dangerouslySetInnerHTML={{
            __html: `
              !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
              n.callMethod.apply(n,arguments):n.queue.push(arguments)};
              if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];
              t=b.createElement(e);t.async=!0;t.src=v;
              s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
              (window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
              fbq('init','<META_PIXEL_ID>');
              fbq('track','PageView');
            `,
          }}
        />
        <script async src="https://api.adsping.io/pb.js" data-pixel-id="<PIXEL_ID>" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

6.2 — TypeScript: window.fbq tipi

// types/global.d.ts (veya bir başka .d.ts)
export {};

declare global {
  interface Window {
    fbq?: (
      cmd: string,
      eventName: string,
      params?: Record<string, unknown>
    ) => void;
  }
}

6.3 — SPA route change'de PageView (kritik)

Next.js / React'te ilk sayfa yüklemesinde PageView fire'lanır, ama route değişimlerinde otomatik fire'lanmaz — script re-execute olmaz. Bunu manuel halletmek zorundasınız.

App Router'da usePathname ile dinleyin:

// components/PageViewTracker.tsx
"use client";

import { usePathname } from "next/navigation";
import { useEffect } from "react";

export function PageViewTracker() {
  const pathname = usePathname();

  useEffect(() => {
    if (typeof window === "undefined") return;
    window.fbq?.("track", "PageView");
  }, [pathname]);

  return null;
}

Sonra app/layout.tsx'de <body> içine ekleyin:

<body>
  <PageViewTracker />
  {children}
</body>

6.4 — Event tetikleme component örnekleri

Contact form (Lead):

"use client";

import { useState } from "react";

export function ContactForm() {
  const [submitting, setSubmitting] = useState(false);

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setSubmitting(true);
    const form = new FormData(e.currentTarget);

    try {
      const res = await fetch("/api/contact", {
        method: "POST",
        body: form,
      });
      if (res.ok) {
        window.fbq?.("track", "Lead", {
          content_name: "İletişim Formu",
          value: 0,
          currency: "TRY",
        });
      }
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <form onSubmit={onSubmit}>
      <input name="email" type="email" required />
      <input name="phone" type="tel" required />
      <textarea name="message" />
      <button disabled={submitting}>Gönder</button>
    </form>
  );
}

WhatsApp / phone link (Contact):

<a
  href="https://wa.me/902121234567"
  onClick={() =>
    window.fbq?.("track", "Contact", {
      content_name: "WhatsApp CTA",
      content_category: "whatsapp",
    })
  }
>
  WhatsApp ile İletişim
</a>

<a
  href="tel:+902121234567"
  onClick={() =>
    window.fbq?.("track", "Contact", { content_name: "Header Phone" })
  }
>
  +90 (212) 123 45 67
</a>

Ürün/hizmet sayfası (ViewContent):

// app/hizmetler/[slug]/page.tsx — server component
import { ViewContentTracker } from "./ViewContentTracker";

export default async function Page({ params }: { params: { slug: string } }) {
  const service = await getService(params.slug);
  return (
    <>
      <ViewContentTracker
        contentName={service.name}
        contentId={service.id}
        value={service.price}
      />
      {/* sayfa içeriği */}
    </>
  );
}
// components/ViewContentTracker.tsx
"use client";

import { useEffect } from "react";

export function ViewContentTracker({
  contentName,
  contentId,
  value,
}: {
  contentName: string;
  contentId: string;
  value?: number;
}) {
  useEffect(() => {
    window.fbq?.("track", "ViewContent", {
      content_name: contentName,
      content_ids: [contentId],
      content_type: "product",
      value,
      currency: "TRY",
    });
  }, [contentName, contentId, value]);

  return null;
}

6.5 — Helper utility (opsiyonel)

Aynı kodu birden fazla yerden çağırıyorsanız tek noktaya topla:

// lib/tracking.ts
type EventData = {
  content_name?: string;
  content_category?: string;
  content_ids?: string[];
  content_type?: string;
  value?: number;
  currency?: string;
  order_id?: string;
};

export function track(eventName: string, data: EventData = {}) {
  if (typeof window === "undefined") return;
  window.fbq?.("track", eventName, data);
}

// Kullanım:
//   import { track } from "@/lib/tracking";
//   track("Lead", { content_name: "İletişim Formu" });
//   track("Contact", { content_name: "WhatsApp CTA" });
Otomatik Advanced Matching aynı şekilde çalışır: form içindeki email/tel input'ları submit anında yakalanır. Component'inizden ekstra bir şey geçmeniz gerekmez — tarayıcı DOM'unda görünen alanlardan pb.js kendi alır.
7

Doğrula

Üç farklı kanaldan doğrulama yapın — birinde sorun olursa diğeri kontrol verir.

(a) AdsPing dashboard

Pixel detay → Report sekmesi:

  • Diagnostics kartı — 24 saatlik success rate %95+ olmalı
  • Recent events listesi — son event'ler canlı akar (event_name, destination, status)
Screenshot pending

Report sekmesi — Diagnostics + Recent events

Ekran görüntüsü: Report sekmesi, Diagnostics card yüksek success rate, event'ler tablosu dolu

Report sekmesi: solda Diagnostics özet, altta son event'ler tablosu

(b) Meta Events Manager

Events Manager → pixel → Test Events sekmesi → sitenizin URL'ini gir. Her event'i hem Browser hem Server sütununda görmelisiniz (dedup edilmiş).

(c) Browser debug

Sayfanın URL'ine ?pb_debug=1 ekleyin → sağ alt köşede mor panel açılır, canlı event listesi.

Veya DevTools console'da:

localStorage.setItem('pb_debug', '1'); location.reload();

Network sekmesinde iki request görmelisiniz:

  • facebook.com/tr → 200 (browser pixel)
  • api.adsping.io/api/v1/t/<pixelId> → 201 (server-side mirror)

Sık karşılaşılan sorunlar

BelirtiÇözüm
Test Events'te sadece Browser sütunu görünür, Server boşpb.js sayfada yüklü değil ya da Meta snippet'inden önce yüklenmiş. Script sıralamasını ve Network'te pb.js 200 dönüyor mu kontrol edin.
event rejected: domain not allowed console hatasıPixel Settings sekmesindeki Allowed Domains kartına o domain'i ekleyin.
Browser pixel + CAPI iki katı sayılıyorpb.js Meta snippet'inden önce yüklenmiş — event_id paylaşımı yok, dedup çalışmıyor. Sıralamayı düzeltin.
SPA route change'de ViewContent fırlamıyorRouter'ın routeChangeComplete event'inde fbq('track','ViewContent',...) çağrısını manuel tetikleyin.
Meta CAPI 403 / "Permission denied"Access token süresi dolmuş veya pixel ile uyumsuz. Events Manager'dan yeni token üret → AdsPing Meta kartından güncelle.
Bittiğinde: Sitenize gelen her event hem browser-side Meta pixel'e hem server-side Meta CAPI'a gider. iOS Safari ITP, ad-blocker, 3rd-party cookie kayıplarına rağmen attribution sağlam kalır. Sonraki adım için Meta integration guide ile siteye event tetikleme kodu ekleyin.