Ajax-filtrering
Teknisk dokumentation för Shoporamas /ajax-slutpunkt för filtrering av produkter. För utvecklare och temadesigners.
Alla Shoporama-butiker har en inbyggd /ajax-ändpunkt som returnerar produkter i JSON-format. Det gör det möjligt att bygga dynamisk filtrering, lazy loading och oändlig rullning utan att ladda om sidan, så att kunden får en snabb och modern upplevelse.
Den här artikeln riktar sig främst till utvecklare och dem som bygger eller anpassar sitt eget tema. Om du använder Delaware-temat har du redan ajax-filtrering som standard och behöver inte själv anropa endpointen.
Så här anropar du endpointen
Ett enkelt anrop som hämtar produkter från en eller flera kategorier:
fetch('/ajax?categories=123&limit=24')
.then(response => response.json())
.then(products => {
products.forEach(p => console.log(p.name, p.price));
});
Som standard returnerar endpointen en JSON-array med produkter. Om du även vill ha med metadata och paginering lägger du till include_meta=1 och include_pagination=1. Då får du istället ett objekt med products, meta och pagination.
Tillgängliga parametrar
Flera av parametrarna tar pipe-separerade värden, så att du kan filtrera på flera saker samtidigt. Till exempel categories=12|34|56.
| Parameter | Beskrivning |
|---|---|
| categories | Kategori-ID:n, separerade med vertikalstreck. Om flera ID:n anges returneras produkter som ingår i minst en av kategorierna (OR). Lägg till match=all för att endast få produkter som ingår i alla angivna kategorier (AND) |
| force_categories | Samma som categories, men tvingar fram kategorierna utan att låta andra filter begränsa dem ytterligare |
| price_range | Prisintervall i form av min|max, t.ex. 100|500 |
| attribute_values | ID:n på attributvärden (t.ex. färg, storlek), separerade med vertikalstreck. Flera värden matchas som OR. Lägg till match=all för att kräva att produkten har alla angivna värden (AND), t.ex. både en färg och en storlek |
| attribute_tags | Filtrera attributvärden via deras tagg istället för ID, t.ex. red|blue |
| attribute_tags_in_stock | Samma som attribute_tags, men endast varianter som finns i lager |
| attribute_tag | Filtrerar på ett helt attribut (inte ett specifikt värde) utifrån dess tagg, t.ex. endast produkter som har attributet ”färg” |
| extension[id] | Filtrera på extrafält. id är extrafältets ID, och värdet kan vara separerat med vertikalstreck |
| brands | Varumärkes-ID:n, separerade med vertikalstreck |
| suppliers | Leverantörs-ID:n, separerade med vertikalstreck |
| landing_pages | Landningssid-ID:n, separerade med vertikalstreck |
| product_ids | Specifika produkt-ID:n, separerade med vertikalstreck |
| atags | Filtrera efter produkttaggar |
| sort + sort_order | Sortera resultatet. sort_order är asc eller desc (standard) |
| limit / offset | Paginering. limit kan högst vara 1000, och högre värden beskärs automatiskt |
| meta | Specifikt meta-fält som ska ingå i varje produkt. Använd _all för alla meta-fält, eller separera flera namn med pipe-tecken |
| only_in_stock_variants | Returnera endast varianter som finns i lager i fältet variant_stock för varje produkt |
| include_meta | Ställ in på 1 för att få med attribut, kategorier och varumärken i resultatet (bra för att bygga filtergränssnitt) |
| include_pagination | Ställ in på 1 för att få offset, limit, count och total |
| pretty | Ställ in på 1 för snyggt formaterad JSON (bra för felsökning) |
| rebuild | Ställ in på 1 för att tvinga fram en ny generering av cachen för den specifika URL:en |
Filtrering med AND (match=all)
När du skickar flera kategorier eller attributvärden matchar slutpunkten som standard med OR: en produkt ingår om den stämmer överens med minst ett av värdena. Det fungerar bra för breda översikter, men vid facettfiltrering vill du ofta ha det omvända, nämligen endast de produkter som matchar alla de valda värdena samtidigt.
Lägg till match=all för att växla till AND-logik. Då måste produkten ha vart och ett av de angivna värdena för att ingå. Det är precis vad du behöver när en kund väljer både en färg och en storlek i ditt filter:
// Endast produkter som har BÅDE värdet 401815 OCH 401822
fetch('/ajax?attribute_values=401815|401822&match=all&limit=50')
.then(response => response.json())
.then(products => { /* ... */ });
match=all fungerar både på categories och attribute_values. Utan parametern används OR som tidigare.
Observera: Den äldre parametern exclude=1 gör exakt samma sak som match=all och fungerar fortfarande av hänsyn till bakåtkompatibilitet. Namnet är missvisande, eftersom den inte exkluderar någonting, så använd match=all i ny kod.
Observera: Parametrarna category_id, tag, extra_field[..], price_from och price_to finns inte längre. Använd istället categories, atags, extension[id] och price_range. Felaktiga namn ger helt enkelt 0 resultat eller ignoreras, utan att ett felmeddelande visas.
Exempel: Kategori, prisintervall och färg
Hämta röda produkter mellan 100 och 500 kr från två kategorier, sorterade efter pris i stigande ordning:
const params = new URLSearchParams({
categories: '12|34',
price_range: '100|500',
attribute_tags: 'red',
sort: 'price',
sort_order: 'asc',
limit: 24
});
fetch('/ajax?' + params)
.then(r => r.json())
.then(products => renderProducts(products));
Exempel: Filtrera med extrafält och hämta metadata
Extra fält (på engelska ”extension fields”) anges med fältets ID inom klammerparenteser. Du hittar ID:t under Inställningar → Utökade fält i admin. Exempel där extrafält 5 (t.ex. ”material”) ska vara antingen ”bomull” eller ”linne”:
// extension[5]=bomuld|linned
fetch('/ajax?categories=12&extension[5]=' + encodeURIComponent('bomuld|linned') + '&include_meta=1&include_pagination=1&limit=24')
.then(r => r.json())
.then(data => {
console.log(data.products);
console.log(data.meta.attributes);
console.log(data.pagination);
});
Fält för varje produkt i svaret
Varje produkt i products-arrayen har bland annat följande fält:

- product_id, own_id, name, description, list_description
- price, real_price, sale_price, price_dk (formaterat enligt danska standarder)
- stock, attr_stock, variant_stock, stock_string_da
- brand_name, supplier_id, supplier_name, profile_name
- category_ids, category_names
- miniatyrbild (200x200), miniatyrbilder (array med alla bilder i 200x200), url
- genomsnittligt_betyg, online_sedan, leveranstid, leveranstid_vid_slut_i_lager, ungefärlig_frakt
- har_kampanjer, kampanjinfo
- meta_values (fylls endast i om du skickar meta=...)
Om webbutiken har aktiverat "dölj lager via ajax" kommer stock, attr_stock och lagerkvantiteter i variant_stock att vara null, så att lagernumren inte läcker ut offentligt.
Cachelagring
Endpunkten cachas på servern i 12 timmar per unik URL. Svaret skickas också med korrekta Last-Modified- och Expires-headers, så att webbläsare och mellanliggande cacher kan returnera ett snabbt 304 Not Modified om innehållet är oförändrat. Detta ger snabba svarstider, men innebär också att ändringar av en produkt först träder i kraft efter att cachen har löpt ut. Du kan tvinga fram en ombyggnad av cachen för en viss URL genom att lägga till rebuild=1.
Läs mer i artikeln Cache i Shoporama, som går igenom cache-lagren i allmänhet.
Implementering i ditt tema
För att bygga en komplett AJAX-filtrerad produktlista måste utvecklaren vanligtvis:
- Skapa ett filtergränssnitt med kryssrutor eller rullgardinsmenyer baserat på meta.attributes, meta.brands och meta.categories
- Övervaka ändringar i filtren och sammanställa dem till en frågesträng
- Anropa /ajax med de valda parametrarna
- Uppdatera produktlistan dynamiskt och visa paginering utifrån pagination.total
Tips: Läs mer om filtrering i allmänhet i avsnittet Filtrering i din webbshop. Om du använder Delaware-temat har du redan AJAX-filtrering som standard.
Vanliga frågor
Var hittar jag ID:t för ett extrafält eller ett attributvärde?
I admin under Inställningar → Utökade fält för extrafält och under Inställningar → Profiler för attributvärden. ID:n visas i listan eller i URL:en när du redigerar ett fält.
Varför får jag inga resultat när jag använder category_id=123?
Därför att parametern inte finns. Byt till categories=123 (i plural). Det är ett av de vanligaste felen när man skapar AJAX-filtrering för första gången. Kontrollera samtidigt att du inte använderprice_from/price_to eller extra_field[...], som inte heller finns.
Mina ändringar på en produkt syns inte på /ajax. Vad ska jag göra?
Endpunkten cachas i 12 timmar. Vänta, eller hämta URL:en med &rebuild=1 för att tvinga fram en ny generering av just den URL:en.
Påverkar många AJAX-anrop hastigheten på min webbplats? (Mikkel, utvecklare)
Cachen ser till att upprepade anrop går snabbt. Var dock försiktig med att göra ett nytt anrop för varje enskilt tangenttryck i ett sökfält. Använd ”debounce” så att du först skickar en begäran när användaren har väntat i 200–300 ms. Webbläsaren utnyttjar också If-Modified-Since, så oförändrade svar returneras som 304 och nästan ingen bandbredd förbrukas.
Får jag samma resultat som på kategorisidan?
I stort sett. /ajax följer samma regler som ProductFactory använder på kategorisidorna, så filtrering, sortering och synlighet (t.ex. dolda produkter) fungerar på samma sätt.
Kan jag göra en sökning på /ajax? (Sofie, nyanställd)
/ajax accepterar inte en fritextsökningsparameter. För sökning måste du använda Shoporamas dedikerade sök-endpoint i temat (vanligtvis /search) eller filtrera på product_ids om du själv sköter sökningen och bara vill hämta data om en känd lista med produkter.
Hur många produkter får jag hämta i ett enda anrop? (Jonas, skala)
Du kan hämta upp till 1 000 produkter i ett enda anrop. Om du begär fler begränsas svaret automatiskt till 1 000, och butiken får samtidigt ett meddelande i admin under Meddelanden så att du kan upptäcka det. I praktiken bör du ligga något lägre. Ett par hundra per förfrågan håller JSON-payloaden liten och svaret snabbt, vilket är särskilt viktigt för mobilanvändare. Använd limit och offset för att räkna sidor, eller hämta nästa batch först när användaren bläddrar.
Blir mina kunders lagerstatus offentliggjord? (Malene, marknadsföring)
Som utgångspunkt innehåller svaret lagerantal. Om det ska döljas (så att konkurrenter eller robotar inte kan se hur mycket ni har i lager) kan er utvecklare aktivera ”dölj lager via ajax” i webbutiken, varpå lagerfälten skickas som null.
Kan jag använda /ajax som ett ”riktigt” REST-API? (Mikkel, utvecklare)
Nej, det är en offentlig, cachevänlig produkt-endpoint avsedd för frontend-användning. Om du behöver skapa, uppdatera eller integrera på en djupare nivå ska du istället använda det egentliga REST-API:et, som kräver en API-nyckel.
Behöver jag oroa mig för att filtreringen fungerar olika för kunder på olika språk?
Endpunkten körs i samma webbshop-kontext som startsidan, så priser, valuta och synlighet följer den webbshop som kallas ramverk. Om du har flera webbshoppar eller språk, kom ihåg att varje webbshop har sin egen URL och därmed sin egen /ajax-cache.
Behöver du hjälp med att bygga in AJAX-filtrering i ditt tema, eller har du tekniska frågor? Skriv till support@shoporama.dk.
Relaterade artiklar
Filtrering i din webbshop
Guide till hur du ställer in filtrering i din Shoporama-webbutik så att kunderna kan filtrera produkter.
Konfiguration och anpassning med Delaware-tema
Komplett guide för att ställa in Delaware-temat på din Shoporama-webbutik. Sidfot, megameny, färger, betalningsikoner, Trustpilot, Instagram-länk...
REST API
Komplett guide till Shoporamas REST API: autentisering, alla slutpunkter, exempel och Swagger-dokumentation.
Importera extra fält på produkter
Guide till import av extra fält via CSV-import av produkter i Shoporama.
Cache i Shoporama
Hur cachelagring fungerar i Shoporama. Hur ofta cacher byggs, när dina ändringar träder i kraft och hur du tvingar fram en återställning.