Hello Velo and Wix Studio Community,
I’m facing a complex and persistent challenge when filtering a repeater using URL query parameters coming from a Header search bar. I have exhausted standard Velo solutions and believe this is a deep-rooted Single Page Application (SPA) behavior issue.
The Problem
When a user is on the product listing page (/satilik-yatlar) and performs a second search using the global Header search bar:
-
URL Updates Correctly: The URL successfully changes (e.g., from
.../satilik-yatlar?searchQuery=YachtAto.../satilik-yatlar?searchQuery=YachtB). -
Filter Fails: The
#dynamicDatasetfilter does not update, and the#repeater1continues to display the results from the first search.
Analysis & Root Cause
The issue occurs because the search button click executes a wixLocation.to(newUrl) call from the Masterpage code. Since the URL path (/satilik-yatlar) remains the same, Wix performs a soft navigation (SPA transition) instead of a full page reload.
-
The page’s $w.onReadyfunction does not re-run. -
The wixLocation.onChangelistener does not reliably trigger in the new Wix Studio/Velo environment (despite being the standard solution).
Solutions Attempted (And Why They Failed)
I have tried the most common and advanced Velo solutions without success:
-
Standard
wixLocation.onChange: Implemented the filtering logic inside a reusable function and called it onwixLocation.onChange. Result: The listener rarely fires when only the query parameter changes on the same path. -
Header Code Relocation: Moved the search code out of the Masterpage and onto the Home page (or another page) to test. Result: The behavior remains the same, confirming it’s an SPA issue, not a scope issue.
-
Aggressive Cache Control (Meta Tags): Tried adding aggressive
no-cachemeta tags to the page settings. Result: No change in Velo execution behavior. -
Forced Hard Refresh (using
window.location.href): Attempted to use native browser navigation to force a full page reload. Result: Leads to continuous Velo Type Script/Linter errors (“Cannot find name ‘window’,” “Property ‘location’ does not exist,” etc.), making the code impossible to publish.
Here are my search bar and dynamic page codes
import wixLocation from 'wix-location';
$w.onReady(function () {
$w("#button3").onClick(() => {
const aramaTerimi = $w("#input7").value;
if (aramaTerimi && aramaTerimi.trim().length > 0) {
const encodedTerm = encodeURIComponent(aramaTerimi.trim());
// Yeni arama sorgusu ile yönlendir
wixLocation.to(`/satilik-yatlar?searchQuery=${encodedTerm}`);
} else {
// Arama terimi yoksa sadece liste sayfasına yönlendir
wixLocation.to(`/satilik-yatlar`);
}
});
});
import wixLocation from 'wix-location';
import wixData from 'wix-data';
// Filtreleme mantığı, sadece URL'den gelen query objesiyle çalışır.
function applyFilter(query) {
const dataset = $w("#dynamicDataset");
const repeaterId = "#repeater1";
// Görsel atlamayı önlemek için repeater'ı her zaman önce gizle
$w(repeaterId).hide();
dataset.setFilter(wixData.filter()); // Önceki filtreleri temizle
let filter = wixData.filter();
let shouldFilter = false;
// Dataset hazır olduğunda filtreyi uygula
dataset.onReady(() => {
// --- 1. ÖNCELİK: Tekli Arama Çubuğu Filtresi (yat_adi) ---
if (query.searchQuery) {
const aramaTerimi = query.searchQuery;
filter = filter.contains("yat_adi", aramaTerimi);
shouldFilter = true;
}
// --- 2. İKİNCİL ÖNCELİK: Çoklu Filtreleme Sistemi ---
else {
// Dropdown Filtreleri
if (query.tekne_tipi) {
filter = filter.eq("tekne_tipi", query.tekne_tipi); shouldFilter = true;
}
if (query.marka) {
filter = filter.eq("marka", query.marka); shouldFilter = true;
}
// Sayısal Alanlar (Yıl, Fiyat, Boy)
if (query.minYl && !isNaN(parseInt(query.minYl))) { filter = filter.ge("yl", parseInt(query.minYl)); shouldFilter = true; }
if (query.maxYl && !isNaN(parseInt(query.maxYl))) { filter = filter.le("yl", parseInt(query.maxYl)); shouldFilter = true; }
if (query.minFiyat && !isNaN(parseInt(query.minFiyat))) { filter = filter.ge("fiyat", parseInt(query.minFiyat)); shouldFilter = true; }
if (query.maxFiyat && !isNaN(parseInt(query.maxFiyat))) { filter = filter.le("fiyat", parseInt(query.maxFiyat)); shouldFilter = true; }
if (query.minBoy && !isNaN(parseFloat(query.minBoy))) { filter = filter.ge("boy", parseFloat(query.minBoy)); shouldFilter = true; }
if (query.maxBoy && !isNaN(parseFloat(query.maxBoy))) { filter = filter.le("boy", parseFloat(query.maxBoy)); shouldFilter = true; }
}
// --- 3. FİLTREYİ UYGULA VE GÖSTER ---
if (shouldFilter) {
dataset.setFilter(filter)
.then(() => {
if (dataset.getTotalCount() > 0) {
$w(repeaterId).show();
}
})
.catch((error) => {
console.error("Filtreleme hatası:", error);
});
} else {
// Hiçbir parametre yoksa, tüm listeyi göster
dataset.setFilter(wixData.filter())
.then(() => {
$w(repeaterId).show();
});
}
}); // dataset.onReady sonu
}
// ANA BLOK: Sayfa yüklendiğinde çalışır
$w.onReady(function () {
// Filtreyi doğrudan URL'deki mevcut query ile uyguluyoruz.
applyFilter(wixLocation.query);
// NOT: wixLocation.onChange kalıcı olarak kaldırıldı.
});
Need help! Thanks!