Başka bir mağazanın sitesine arama sonuçları eklemek
Farklı mağazalara tek kod dosyasıyla arama sonuçları eklemek: markaya özel ayarlar, sayfaya yerleşim ve eski sürümle birlikte çalışma.

Bir mağazanın arama sonuç sayfası, mağazanın kendi sayfasıdır. Header'ı, footer'ı, URL formatı, stil dosyası, script'leri (belirli bir işi yapan kod dosyası) onundur.
Temmuz 2025'te, Revotas'ın o sayfanın içine koyabileceği bir sonuç sayfası yazmaya başladım. Mağazaları biz barındırmıyoruz ve onlara deploy (uygulamanın yeni sürümünü sunucuya yükleyip çalışır hale getirme) edemiyoruz. Ürün ızgarası, filtreler, sıralama, sayfalama, önerilen aramalar, sepete ekleme; hepsi tek bir script etiketinden geliyor.
İlk sürüm tek mağazada çalıştı. Bu yazı, kodu on kez kopyalamadan onuncu mağazada da çalışması için ne gerektiğini anlatıyor.
Sayfa bir günde, ürün üç ayda
İlk commit'lerin (kod deposuna kaydedilen değişiklik paketi) hepsi 28 Temmuz 2025 tarihli. O günün sonunda bir sonuç düzeni, ürün ızgarası, filtre paneli ve test modu vardı.
Bir ay sonra gerçek veri okuyordu. 25 Ağustos'ta arama API'sini (yazılımların birbirine istek göndermesini sağlayan arayüz) ve sayfalamayı bağladım. Ertesi gün filtrelemeyi tarayıcıya taşıdım, 1 Eylül'de de bir ürünün hem liste hem indirimli fiyatı olduğunda fiyatın nasıl çalışacağını düzelttim.
Sonra kimsenin görmediği kısım geldi. Ekim'den Aralık'a kadar iş neredeyse tamamen tek bir soruyla ilgiliydi: mağazadan mağazaya ne değişiyor ve bu nerede duruyor?
Bu dosyaların kaydı, 28 Temmuz 2025 ile Mart 2026 arasında 80 commit; hepsi benim. Sayfa script'i 9.613 satır ve 154 fonksiyon. Mağazanın arama kutusunu devralan script 4.099 satır daha.
Mağaza başına fork ölçeklenmiyor
İkinci mağazanın arama URL'i farklıydı. Üçüncüsü sonuçlarını başka bir container'da tutuyordu. Her birinin kendi renkleri, kendi fontu, hangi filtrelerin önemli olduğuna dair kendi fikri vardı.
Bunu çözmenin hızlı yolu script'i kopyalayıp düzenlemek. İş böyle başladı ve bedeli hemen ortaya çıktı: bir kopyadaki düzeltmeyi diğerinde yeniden yapmak gerekiyordu.
22 Ekim'de mağazaya özel her şeyi tek bir config (uygulamanın davranışını belirleyen ayarlar) nesnesine çıkardım. Mağazanın snippet'i bu nesneyi script yüklenmeden önce tanımlıyor. Script'in kendisi artık hiçbir mağaza hakkında bir şey bilmiyor.
Config gerçekten değişen şeyleri tutuyor:
- Site ve URL formatı. Ana URL, arama yolu ve sorgu parametresinin adı. Bir mağaza
/search?q=ile arıyor, bir başkası farklı bir yol ve farklı adlı bir parametreyle. - Nereye yerleşeceği. Hedef için bir CSS (sayfanın renklerini, boyutlarını ve yerleşimini belirleyen stil kuralları) seçici ve bir ekleme modu: önüne, arkasına ya da yerine.
- Filtreler ve sıralama. Hangi filtre bölümlerinin görüneceği ve hangi sıralama seçeneklerinin sunulacağı.
- Tema. Renkler, font aileleri, ağırlıklar ve boyutlar; header'ı her şeyin üstünde duran mağazalar için bir z-index tabanı ve ofsetleri.
- Metin. Her etiket ve mesaj. Başka dilde bir mağaza, bir config değişikliği.
Her okuma, bir yol ve bir varsayılan değer alan tek bir yardımcı fonksiyondan geçiyor. Hiçbir şey ayarlamayan mağaza yine çalışan bir sayfa alıyor.
Repoda şu an on mağazanın config'i var. Yeni bir mağazanın başladığı dosya 639 satır ve yorum olarak yazılmış bir kurulum rehberiyle açılıyor: değiştirmeniz gereken ayarlar, değiştirebilecekleriniz ve sırasıyla adımlar.
Kontrol etmediğim bir sayfanın içine yerleşmek
Sayfa, mağazanın kendi sonuçlarının duracağı yerde görünmeli. Bazı mağazalarda o element script'im çalıştığında yerinde. Bazılarında sonradan, mağazanın kendi JavaScript'iyle geliyor.
Bu yüzden yerleşme küçük bir durum makinesi. Hedef oradaysa ekleme modunu uygula. Değilse DOM'u (tarayıcının sayfadaki öğeleri temsil ettiği yapı) bir zaman aşımıyla izle ve hedef geldiğinde bağlan. Yerine geçme modunda yeni container hedefin özniteliklerini devralıyor, çünkü mağazanın stil dosyası çoğu zaman o elementin id'sine bağlı.
Geçişi bir yükleme ekranı örtüyor. Düzen hazır olduğunu bildirince kapanıyor; bir koruma zamanlayıcısı da ne olursa olsun 10 saniye sonra kapatıyor. Hiç gitmeyen bir yükleme ekranı, aniden beliren bir sayfadan kötüdür.
Hataların çoğu URL'lerden çıktı
İlk aylardaki hataların çoğu URL'lerle ilgiliydi.
En kötüsü, içinde alan adı iki kez geçen adresler üretiyordu. Bir mağazanın config'inde protokollü bir ana URL vardı, arama yolu başka bir yerden kendi host'uyla geliyordu ve ikisini birleştirmek neredeyse doğru görünen bir link veriyordu. 3 Kasım'da ana URL'i ve arama yolunu ayrı ayrı normalize eden, bunlardan bir şey üretilmeden önce yinelenen alan adını temizleyen yardımcılar ekledim.
Üç gün sonra önerilen aramaların nasıl yönlendirdiğini değiştirdim. Sayfayı pushState ve bir fetch ile yerinde değiştiriyorlardı. Bunu normalize edilmiş arama URL'ine tam sayfa geçişiyle değiştirdim ve bir mağazanın her yerde tam sayfa geçişini zorlayabileceği bir bayrak ekledim.
Aynı mağazada eski ve yeni
Bir mağaza sonuç sayfasını körlemesine değiştiremez. Bu yüzden snippet koşullu yükleniyor.
URL'deki bir işaret yeni sayfayı açıyor. İşaret varsa ziyaretçi yeni sonuç sayfasını görüyor. Yoksa mağazanın mevcut araması eskisi gibi çalışıyor. İkisi de aynı canlı sitede, aynı snippet'in içinde duruyor ve ekip ikisini gerçek sorgularda karşılaştırabiliyor.
Canlıya geçmek tek satır: işareti boş string (metin değeri) yapmak.
Tarayıcıda filtreleme ve sınırı
Renk ve fiyat filtreleri tarayıcıda, zaten yüklenmiş ürünler üzerinde çalışıyor. Debounce (peş peşe gelen işlemleri kısa süre bekleyip tek seferde çalıştırma) var, yani fiyat yazarken her tuşta ızgara yeniden çizilmiyor. Tıklama başına istek yok.
Fiyat önce indirimli fiyatı kullanıyor, o yoksa liste fiyatına düşüyor. İkisi de olmayan ürün, sıfır fiyatlı sayılmak yerine fiyat filtreli sonucun dışında bırakılıyor.
Yeni bir arama başlatmak aktif filtreleri temizliyor. Aynı aramayı tekrarlamak filtreleri koruyor. Script ikisini ayırt ediyor, çünkü "kırmızı, 500 altı" filtresini ilgisiz bir sorguya taşımak boş sonuç döndürür ve bozuk görünür.
Sınır açık: tarayıcı tarafındaki bir filtre yalnızca çekilmiş olanı görür. Marka filtresi bu yüzden farklı çalışıyor. Marka seçmek, o markaların bütün sayfalarını çekiyor ve filtrelemeden önce ürünleri birleştiriyor.
Bundan aklımda kalanlar
- Neyin değiştiğine erken karar ver. Asıl tasarım işi config şemasıydı. O var olduktan sonra yeni mağaza bir branch (ana koddan ayrı ilerletilen geliştirme dalı) değil, bir dosya oldu.
- Her ayara bir varsayılan ver. Eksik bir anahtar makul bir şeye düşmeli, birinin mağazasında exception'a değil.
- Kurulum rehberini ayarların olduğu yere yaz. Mağaza ekleyen kişinin önünde wiki değil, config açık.
- Eskiyi ve yeniyi birlikte yayınla. URL'deki bir anahtar, her geçişi tek bir string'i silerek geri alınabilir yaptı.
Bu yazı İngilizce aslından Türkçeye çevrilmiştir.


Bu yazıya bırakılan notlar
Katıl
Yükleniyor…
Bir yorum bırak.
Bu yazıya not eklemek için giriş yap.
Sadece adın ve avatarın kullanılır.