Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Serverseitige Suche mit searchCriteria-Filtern

Serverseitige Suche mit searchCriteria-Filtern

~13 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Zum Abschluss der funktionalen Kapitel bauen wir eine ECHTE Suche – nicht Client-seitiges Filtern eines bereits geladenen Arrays, sondern eine Anfrage, die Magento SELBST nach passenden Produkten durchsuchen lässt.

Warum serverseitig statt Client-seitig filtern?

Ein Client-seitiger Filter (produkte.filter(p => p.name.includes(suchbegriff))) würde NUR innerhalb der bereits geladenen 12 Produkte der aktuellen Seite suchen – ein Produkt auf Seite 5 würde bei einer Suche auf Seite 1 schlicht NICHT gefunden. Eine serverseitige Suche durchsucht dagegen den GESAMTEN Produktkatalog, unabhängig von Pagination.

filterGroups: Magentos Such-Syntax

searchCriteria[filterGroups][0][filters][0][field]=name
searchCriteria[filterGroups][0][filters][0][value]=%25Hemd%25
searchCriteria[filterGroups][0][filters][0][condition_type]=like

condition_type=like zusammen mit %-Platzhaltern im value (URL-kodiert als %25) entspricht einer SQL-"LIKE %Hemd%"-Suche – findet also "Hemd" an JEDER Stelle des Produktnamens, nicht nur am Anfang.

fetchProducts() um eine Suchoption erweitern

src/api/magentoApi.js
// ... vorheriger Code ...

export async function fetchProducts({
  seite = 1,
  sortierFeld = 'name',
  richtung = 'ASC',
  suchbegriff = '',
} = {}) {
  const params = new URLSearchParams({
    'searchCriteria[pageSize]': PAGE_SIZE,
    'searchCriteria[currentPage]': seite,
    'searchCriteria[sortOrders][0][field]': sortierFeld,
    'searchCriteria[sortOrders][0][direction]': richtung,
  });

  if (suchbegriff.trim() !== '') {
    params.set('searchCriteria[filterGroups][0][filters][0][field]', 'name');
    params.set('searchCriteria[filterGroups][0][filters][0][value]', `%${suchbegriff}%`);
    params.set('searchCriteria[filterGroups][0][filters][0][condition_type]', 'like');
  }

  const data = await magentoFetch(`/products?${params.toString()}`);
  return {
    produkte: data.items,
    gesamtAnzahl: data.total_count,
    seitenAnzahl: Math.ceil(data.total_count / PAGE_SIZE),
  };
}

components/SearchBar.jsx

src/components/SearchBar.jsx
import { useState } from 'react';

function SearchBar({ onSuchen }) {
  const [eingabe, setEingabe] = useState('');

  function absenden(event) {
    event.preventDefault();
    onSuchen(eingabe);
  }

  return (
    <form onSubmit={absenden}>
      <input
        type="text"
        placeholder="Produkt suchen..."
        value={eingabe}
        onChange={(event) => setEingabe(event.target.value)}
      />
      <button type="submit">Suchen</button>
    </form>
  );
}

export default SearchBar;

ProductListPage.jsx: Suche integrieren

src/pages/ProductListPage.jsx
import { useEffect, useState } from 'react';
import { fetchProducts } from '../api/magentoApi';
import Pagination from '../components/Pagination';
import ProductCard from '../components/ProductCard';
import SearchBar from '../components/SearchBar';

function ProductListPage() {
  const [produkte, setProdukte] = useState([]);
  const [seitenAnzahl, setSeitenAnzahl] = useState(1);
  const [aktuelleSeite, setAktuelleSeite] = useState(1);
  const [suchbegriff, setSuchbegriff] = useState('');
  const [ladend, setLadend] = useState(true);

  useEffect(() => {
    setLadend(true);
    async function laden() {
      const ergebnis = await fetchProducts({ seite: aktuelleSeite, suchbegriff });
      setProdukte(ergebnis.produkte);
      setSeitenAnzahl(ergebnis.seitenAnzahl);
      setLadend(false);
    }
    laden();
  }, [aktuelleSeite, suchbegriff]);

  function neueSuche(begriff) {
    setSuchbegriff(begriff);
    setAktuelleSeite(1); // WICHTIG: bei neuer Suche zurück auf Seite 1
  }

  return (
    <div>
      <h1>Produkte</h1>
      <SearchBar onSuchen={neueSuche} />
      {ladend ? (
        <p>Lade Produkte...</p>
      ) : (
        <>
          <ul>
            {produkte.map((produkt) => (
              <ProductCard key={produkt.sku} produkt={produkt} />
            ))}
          </ul>
          <Pagination
            aktuelleSeite={aktuelleSeite}
            seitenAnzahl={seitenAnzahl}
            onSeiteWechseln={setAktuelleSeite}
          />
        </>
      )}
    </div>
  );
}

export default ProductListPage;

[aktuelleSeite, suchbegriff] als Abhängigkeiten sorgen dafür, dass eine neue Anfrage sowohl bei Seitenwechsel ALS AUCH bei neuer Suche ausgelöst wird – und setAktuelleSeite(1) in neueSuche() verhindert den subtilen Bug, auf Seite 3 einer neuen, kürzeren Ergebnisliste zu landen, die vielleicht nur 1 Seite hat.

Tipp: Suchen Sie nach einem Wortteil, den Sie in MEHREREN Ihrer echten Produktnamen vermuten – erscheinen wirklich nur passende Treffer, UND funktioniert die Pagination innerhalb der gefilterten Ergebnisse korrekt, funktioniert die serverseitige Suche wie gewünscht.