SESTEK vakası: iki dilli bir Webflow sitesini Dynamics 365'e bağlayan mimari
SESTEK'in Webflow sitesinde formlar tarayıcıdan doğrudan CRM'e gitmez; sitenin kendi alan adında yayınlanan bir Webflow Cloud uygulamasına gönderilir³ ¹⁴. Microsoft Dynamics 365 ile konuşan taraf bu uygulamadır, tarayıcı Microsoft kimlik servisiyle ya da Dynamics'le hiçbir zaman doğrudan konuşmaz³. SESTEK, yapay zekâ destekli çağrı merkezi çözümleri geliştiren, kendini konuşmalı yapay zekâ markası olarak tanımlayan bir B2B yazılım şirketi¹ ².
Proje kapsamı ve iş bölümü
Bu projede Webflow sitesini, formların React code component'lerini, form verisini karşılayan Webflow Cloud uygulamasını ve aradaki entegrasyon mimarisini Webflow geliştirme hizmetimiz kapsamında biz kurduk. Dynamics tarafındaki lead alanları ve seçenek tanımları SESTEK'in CRM yapısına ait; entegrasyonu o yapıya uyacak şekilde tasarladık. 'Sizi arayalım' demosunda aramayı SESTEK'in kendi ürünü Outbound Manager yapar⁸. Bizim işimiz o ürünü siteye, kimlik bilgilerini tarayıcıya göstermeden bağlamaktı⁸.
Başlangıç koşulları: kurumsal B2B site, iki dil, mevcut CRM yapısı
Site Türkçe ve İngilizce yayınlanacaktı; TR demo sayfası Türkçe etiketler ve veri işleme onay metni taşıyor¹. Form tipleri demo talebi, rapor indirme, bülten ve 'sizi arayalım' demosuydu² ¹² ²² ¹⁸. İki koşul tasarımı baştan belirledi. Birincisi, CRM'e erişim sırrı tarayıcıya inen hiçbir dosyada bulunamazdı³. İkincisi, pazarlama ekibi formları geliştiriciye gitmeden Designer'dan yönetebilmeliydi¹⁷. Aşağıdaki bölümler bu iki koşulun mimariye nasıl çevrildiğini anlatıyor.
Neden Zapier değil de Webflow Cloud üzerinde bir sunucu katmanı?
Kısa cevap: kimlik bilgisi tarayıcıya inemeyeceği³ ve kayıt oluşmadan önce doğrulama gerektiği için hazır bağlayıcı yerine kendi sunucu katmanımızı kurduk.
Hazır bağlayıcının yetmediği yer
Webflow'un kendi Dynamics 365 rehberi Zapier'i bir form gönderiminden lead'e giden en kısa yol olarak sunuyor¹². Tek formlu, ek kontrol istemeyen bir akışta bu yol yeterli. Aynı rehber, kayıt oluşmadan önce doğrulama, özel tekilleştirme ya da birden çok sisteme yazım gerektiğinde kod yazılmasını öneriyor¹². Önerdiği kalıp da gönderimi kendi ucunda yakalayıp işledikten sonra Dataverse'e yazmak¹². SESTEK'in ihtiyacı ilk koşula oturuyordu: her gönderim, lead açılmadan önce bot doğrulamasından ve alan kontrolünden geçmeliydi. Proje spesifikasyonumuzdaki tasarım gerekçesi de aynı yere çıkıyor: seçtiğimiz sunucudan sunucuya akış istemci sırrı gerektiriyor ve bu sır tarayıcıya inen hiçbir dosyada bulunamaz; jeton alma adımı bu yüzden sunucuya düştü³.
Webflow Cloud: sitenin kendi alt yolunda yayınlanan uygulama
Webflow Cloud, web uygulamaları için bir dağıtım ve barındırma ortamı¹³. Siteye bağlanan her ortama Webflow alan adı altında benzersiz bir yol atanır¹⁴; SESTEK'te bu uygulama demo sayfalarını ve API servislerini taşıyor¹⁷. Webflow Cloud, Next.js uygulamalarını OpenNext Cloudflare adaptörüyle dağıtıyor¹⁵; adaptör uygulamayı Cloudflare Workers'a taşıyor¹⁶. Kod GitHub deposunda duruyor, depo değiştikçe Webflow Cloud yeniden dağıtıyor¹³. Sonuçta ayrı bir sunucu ya da ayrı bir alan adı kurmadık. Uygulama siteyle aynı alan adına bağlı olduğu için form isteği tarayıcı açısından sitenin kendisine gider³. Formun önüne ayrı bir Node.js ara katmanı koyan yaklaşımlardan farkımız bu.
Form verisinin yolu: Webflow sayfasından Dynamics 365'e beş adım
Bir form gönderimi, kurduğumuz mimaride Dynamics 365'e beş adımda ulaşır. Her adım tek bir iş yapar; hiçbir adımda tarayıcı CRM'le konuşmaz³. 1. Ziyaretçi Webflow sayfasındaki React formu doldurur²⁰. 2. Görünmez bot doğrulaması jeton üretir; doğrulama betiği form görünüme yaklaşınca ya da ziyaretçi forma odaklanınca yüklenir⁷. 3. Form aynı alan adındaki Cloud app'e gider; verisini ve jetonu birlikte taşır³. 4. Cloud app jetonu doğrular, alanları izin listesiyle ayıklar; iki kontrol de sunucu tarafının tasarımında yer alır⁶ ³. 5. Sunucudan sunucuya yetkilenip lead'i Dynamics 365'e yazar¹².
Dynamics 365'te lead, nitelendiğinde hesaba, kişiye ya da fırsata dönüştürülen potansiyel bir satış fırsatıdır⁹. Formdan gelen her lead kaydı SESTEK'in CRM yapısındaki alanlara göre açılır. Web API ile kayıt oluşturmak için geçerli varlık kümesi adı, özellik adları ve tipleri önceden bilinmelidir¹⁰. Sunucudan sunucuya kimlik doğrulama için Microsoft uygulama kimliği, dizin kimliği ve istemci sırrı ister¹¹. Tasarımda bu değerler repoya yazılmaz³. Aynı vekil (proxy) deseni 'sizi arayalım' demosunda da var. Ziyaretçi adını ve telefonunu bırakır, SESTEK'in Knovvu Outbound Manager ürünü onu arar⁸. Tarayıcı yalnız bizim katmanımızı görür⁸. Bu form veriyi Dynamics'e değil, SESTEK'e iletir. Roicool beyanı: SESTEK formlarından gelen lead'ler canlıda Dynamics 365'e yazılıyor³³. Bu bizim beyanımızdır; sunucu kodu kamuya açık olmadığı için dışarıdan doğrulanamaz.
React code component formlar: Designer'dan yönetilen, Shadow DOM içinde izole
Formları native Webflow formu yerine React code component'i olarak kurduk⁴. Code component, Webflow sitelerinde kullanılmak üzere geliştirilmiş bir React bileşenidir¹⁹; bileşenler DevLink ile paketlenip paylaşımlı bir kütüphane olarak yayınlanır¹⁹. İş bölümü net: pazarlama ekibi bileşeni canvas'a sürükleyip ayarlarını sağ panelden yapar¹⁷, geliştirici tek kod tabanını korur.
Prop ile yapılandırma: tek bileşen, birden çok varyant
Sayfalara dört React form bileşeni yerleştirildi: demo talebi, bülten, rapor indirme ve 'sizi arayalım' demosu⁴. Görünüm farkları ayrı kopyalarla değil, varyantlarla çözülüyor. Bülten bileşeninin Subscribe ve Demo tipleri⁴, demo formunun adım adım ilerleyen Steps varyantı var⁴. EN demo sayfasındaki form ad, soyad, şirket ve kurumsal e-posta ister²¹; TR sayfada aynı form Türkçe etiketlerle yer alır¹. Rapor formu daha kısa, bilgiler girildikten sonra rapor hemen veriliyor²². Telefon alanında ülke kodu seçici ve ülkeye göre doğrulama var⁴.
Shadow DOM izolasyonu ve SSR
Her code component kendi Shadow DOM kabına, ayrı bir React köküyle yerleşir; bu yalıtım bileşenin sayfayla ve diğer bileşenlerle çakışmasını önler²³. İlk HTML'i sunucu tarafında render (SSR) sağlar, etkileşim tarayıcıda gerçekleşir²³. Bileşenleri layout shift, çizimi engelleyen iş ve gereksiz ağ yükü açısından gözden geçirdik⁷. Yalıtımın bedelini de gördük ve belgeledik: bileşenler Shadow DOM içinde çiziliyor⁴. Belge düzeyinde olay dinleyip hedefi bileşenin içindeki bir düğümle karşılaştıran kod kırılıyor, sayfa düzeyindeki sorgular bileşenin içini göremiyor; telefon alanındaki özel ülke panelinin kırılma sebebi de buydu⁴. Çıkardığımız kural: bileşenin davranışı bileşenin içinde taşınır.
Kütüphane güncellemesi neden yayına kendiliğinden çıkmıyor
Code component kütüphanesinde yapılan bir güncelleme yayındaki siteye kendiliğinden yansımaz; Designer'da güncelleme onayı gerekir¹⁷. Bunu kontrollü yayın olarak kullanıyoruz: bileşen değişikliği, site tarafında onaylanmadan ziyaretçiye ulaşmıyor.
Katmanlı form koruması: bot doğrulamasından alan izin listesine
İstemci tarafındaki hiçbir kontrol güvenlik sınırı değildir; tarayıcıdaki denetimler atlanabilir, asıl kontrol sunucudadır⁴. Tarayıcıdaki Turnstile bileşeni de formu tek başına korumaz, jetonun sunucuda doğrulanması gerekir⁶. Form korumasını bu yüzden katmanlar halinde tasarladık. Formlarda dışarıdan görülebilen katman bot doğrulamasıdır. Cloudflare Turnstile ziyaretçiye CAPTCHA göstermeden devreye girer⁵; lead formlarında doğrulama kutusu çizilmez⁴. Sunucu tarafındaki katmanlar tasarımda yer alıyor. Sunucu kodu kamuya açık olmadığı için onları gözlenmiş olgu olarak değil, mimarinin tasarım katmanları olarak sayıyoruz: - Sunucu tarafı jeton doğrulaması: jetonlar tek kullanımlıktır, her jeton yalnız bir kez doğrulanır⁶. - Honeypot (gizli tuzak alanı)³. - Köken kontrolü³. - İstek sınırlama; tasarımda Turnstile'ın yerine geçmez, ikisi birlikte durur³. - Kurumsal e-posta filtresi: ücretsiz sağlayıcılar B2B formlarında engelli, bültende serbest; tek kullanımlık adresler her formda engelli⁴. - Alan izin listesi: tasarımda CRM'e yalnız listedeki alanlar kopyalanır³. - Log kuralı: tasarım gereği ziyaretçinin kişisel verisi log'lara yazılmaz³.
Kurumsal e-posta filtresini bilerek güvenlik katmanı saymıyoruz. Tasarım belgemizde yazdığı gibi bu bir kalite filtresidir, kendi alan adını alan biri listeyi aşar; kötüye kullanıma karşı istek sınırlama ve Turnstile gerekir³. Bültende ücretsiz adreslere izin vermemizin nedeni de bu: huninin en üstünde gmail'i engellemek abone kaybettirir⁴.
İki dilli CMS: TR/EN koleksiyon kümeleri ve çevrilmiş slug'lar
SESTEK'in Türkçe sürümü /tr alt dizininde; koleksiyon klasörlerinin ve öğe slug'larının büyük kısmı Türkçeleştirildi²⁷. Dil eşleri Webflow'un otomatik site haritasında hreflang ile bildiriliyor²⁶. Bu yapıyı Webflow Localization üzerinde kurduk.
Klasör ve öğe slug'ları nasıl yerelleşiyor
Webflow Localization'da birincil dilde oluşturulan koleksiyon öğesi tüm dillerde var olur²⁵. Koleksiyon slug'larını dile göre çevirme özelliği Advanced ve Enterprise Localize planlarında bulunur²⁵. SESTEK'te desen açık: /success-stories/axa-insurance sayfasının Türkçe eşi /tr/basari-oykuleri/axa-sigorta²⁷; /industries/bpo sayfasınınki /tr/sektorler/outsource-cagri-merkezi²⁷. Blog yazılarının TR slug'ları da Türkçe²⁷. Çeviri her yerde doğru karar değil. Yazar sayfalarında slug kişi adı olduğu için iki dilde aynı kaldı²⁷; karşılaştırma sayfalarında da rakip ürün adı sabit tutuldu²⁷. Okur bir kişiyi ya da ürünü adıyla arar; adı çevirmek, aranan kelimeyi URL'den silmek demek.
Şablonlarda görünen içerik ilişkileri
Koleksiyonlar şablonlarda birbirine bağlı gösteriliyor. Blog yazısı kategori etiketini ve yazar kartını taşıyor³¹; yazar sayfasında 'Articles by' başlıklı bir yazı listesi var³⁰; kategori sayfası kategori seçiciyle birlikte o kategorinin yazılarını listeliyor²⁹. Başarı öyküsü şablonu sektör, şirket ölçeği, sorun alanı ve kullanılan SESTEK ürünü alanlarını gösteriyor²⁸; sayfanın altında başka başarı öyküleri sıralanıyor²⁸. Otomatik site haritası açıkken Webflow tüm statik ve dinamik sayfalar için hreflang etiketi ekler²⁶ ve her dilde sayfanın dil kodunu ayarlar²⁶. Aşağıdaki tablo, site haritasındaki URL'lerin kümelere dağılımını gösteriyor: 17.09.2026 tarihli bir yapı sayımı, performans ölçüsü değil. Site haritası 250'si EN, 250'si TR olmak üzere 500 URL listeliyor²⁷.
| Küme | EN klasörü | TR klasörü | URL (EN / TR) | Slug yerelleştirme |
|---|---|---|---|---|
| Blog | blog | blog | 89 / 89 | Klasör aynı, öğe slug'ları Türkçe |
| Başarı öyküleri | success-stories | basari-oykuleri | 27 / 27 | Klasör çevrildi, öğeler kısmen |
| Yazarlar | authors | yazarlar | 21 / 21 | Klasör çevrildi, kişi adı sabit |
| Webinarlar | webinars | webinarlar | 15 / 15 | Klasör çevrildi, öğe slug'ları Türkçe |
| Yasal | legal | yasal | 12 / 12 | Klasör ve öğeler çevrildi |
| Podcastler | podcasts | podcastler | 11 / 11 | Klasör ve öğeler çevrildi |
| Karşılaştırmalar | compares | karsilastirmalar | 10 / 10 | Klasör çevrildi, ürün adı sabit |
| Ürünler | products | urunler | 8 / 8 | Klasör çevrildi, öğeler çoğunlukla aynı |
| Blog kategorileri | blog-categories | blog-kategorileri | 8 / 8 | Klasör çevrildi, öğeler aynı |
| Çözümler | solutions | cozumler | 6 / 6 | Klasör ve öğeler çevrildi |
| Sektörler | industries | sektorler | 6 / 6 | Klasör ve öğeler çevrildi |
| CX Insights | cx-insights | cx-insights | 6 / 6 | Klasör aynı, öğe slug'ları Türkçe |
| Kariyer | careers | kariyer | 6 / 6 | Klasör çevrildi, öğeler aynı |
| Hesaplayıcılar | calculators | hesaplayicilar | 4 / 4 | Klasör çevrildi, öğeler çoğunlukla aynı |
| Statik sayfalar | — | — | 21 / 21 | Sayfa bazında (ör. about-us → hakkimizda) |
Üç teslim kanalı: CDN kütüphanesi, code components ve Cloud app
Teslim üç ayrı kanaldan yapılıyor ve kanallar birbirine karışmıyor: CDN üzerinden yüklenen site kütüphanesi, DevLink ile Designer'a giden code component'ler ve formları karşılayan Webflow Cloud app¹⁷. Cloud app sonradan ayrı bir depoya çekildi; formları karşılayan uç orada yazıldı³². Site kütüphanesi CDN öncelikli; build adımı gerektirmiyor²⁴. Projenin ilkesi render'ı bloklayan betik olmaması²⁴. Code component'ler DevLink ile Designer'a aktarılabilen React bileşenleri olarak ayrı bir pakette duruyor²⁰. Sitenin alan adındaki Cloud app sayfalarında ürün demoları da yer alıyor: Türkçe demo sayfalarında ziyaretçi demoları kayıt olmadan, tarayıcıda deneyebiliyor¹⁸. Cloud app sayfalarında sitenin görünümünü korumak gerekiyordu. Navbar Webflow'dan DevLink export ile geldi²⁴. DevLink footer'ı koleksiyon listesi ve grid boşlukları yüzünden kırık render olduğu için kullanılmadı; footer'ı ayrıca yazdık, CMS kolonlarını sunucu tarafında çektik¹⁷.
Bu vakadan çıkan ders: entegrasyon kararı formdan önce verilir
Birinci ders: CRM'e bağlanacak bir form, kimlik bilgisinin nerede duracağı belli olmadan tasarlanmamalı. SESTEK'te sırrın tarayıcıya inemeyeceği kuralı³ formun hedefini baştan belirledi. Form CRM'e değil, sunucu katmanına gönderilecekti; bot doğrulaması, alan kontrolü ve yetkilendirme de o katmana düştü. İkinci ders: pazarlama ekibinin Designer'dan yönettiği bileşen ile geliştiricinin koruduğu sunucu katmanı ayrılınca iki taraf birbirini beklemez. Kütüphane güncellemesinin Designer'da onayla yayına çıkması¹⁷ bu ayrımın parçası. Görünüm değişikliği sunucuya dokunmaz, sunucu değişikliği de bileşeni yeniden yayınlamayı gerektirmez. Üçüncü ders: iki dilli CMS'te slug kararı öğe türüne göre verilir. Kişi ve ürün adları iki dilde sabit kalır²⁷, içerik ve klasör adları çevrilir²⁷. Süren işler de var: iletişim formunun sayfaya alınması⁴ ve native Webflow formları için köprü sürüyor. Köprü tasarımında Webflow'un kendi gönderimi korunuyor, CRM gönderimi ona paralel ikinci bir kanal olarak ekleniyor³².
Kaynak
- Demo İsteyin | SESTEK Yapay Zeka Destekli Çağrı Merkezi Çözümleri
- Product Demos | Sestek
- CRM Lead API (Roicool iç belgesi, yayımlanmadı)
- Durum ve Yapılacaklar (Roicool iç belgesi, yayımlanmadı)
- Cloudflare Turnstile · Cloudflare docs
- Validate the token · Cloudflare Turnstile docs
- Sestek Webflow Code Components (Roicool iç belgesi, yayımlanmadı)
- Outbound Call Demo
- Lead table/entity reference (Microsoft Dynamics 365) | Microsoft Learn
- Create a table row using the Web API | Microsoft Learn
- Use single-tenant server-to-server authentication (Microsoft Dataverse) | Microsoft Learn
- Integrate Microsoft Dynamics 365 CRM with Webflow | Quick connect guide
- Webflow Cloud | Webflow Developer Documentation
- Environments | Webflow Developer Documentation
- Optimizing your app for Webflow Cloud | Webflow Developer Documentation
- Cloudflare - OpenNext
- Webflow Apps — Code Components & Cloud App Rehberi (Roicool iç belgesi, yayımlanmadı)
- Ürün Demoları | Sestek
- Code components | Webflow Developer Documentation
- sestek-webflow-components package.json (Roicool iç belgesi, yayımlanmadı)
- Request a Demo | SESTEK AI Contact Center Solutions
- SESTEK Named Leader in Opus Research 2025 CI Report
- Component architecture | Webflow Developer Documentation
- Sestek (Roicool iç belgesi, yayımlanmadı)
- Localize Collection content – Webflow Help Center
- Localized SEO and locale routing – Webflow Help Center
- sestek.com sitemap.xml (canlı, 17.09.2026)
- Ajman Bank success story (SESTEK)
- Agentic AI blog category (SESTEK)
- Author page (SESTEK)
- Top Strategic Predictions for 2022 and Beyond (SESTEK blog)
- CRM Form Entegrasyonu (Roicool iç belgesi, yayımlanmadı)
- SESTEK formlarının Dynamics 365 entegrasyonu (Roicool iç belgesi, yayımlanmadı)



















