7 marca 2025 (updated: 7 marca 2025)
Chapters
Zobacz, jak szybko stworzyć interfejs wyszukiwania z Algolia InstantSearch.
W poprzednim artykule: Filtrowanie geograficzne z Algolia Geo Search, MapBox i Next.js, omówiliśmy, jak filtrować nasze wyniki na podstawie aktualnej lokalizacji geograficznej przy użyciu Algolia API. Rozmawialiśmy również o tym, czym jest Algolia i jak działa. W dzisiejszym artykule wykorzystamy tę wiedzę, ale skupimy się na innej funkcjonalności oferowanej przez zespół Algolia, a mianowicie InstantSearch.
InstantSearch to biblioteka UI, która umożliwia szybkie tworzenie interfejsów wyszukiwania. Oferuje gotowy zestaw tzw. Widgetów, które są predefiniowanymi, gotowymi do użycia blokami kodu, które można natychmiast włączyć i wykorzystać w naszym projekcie. Widgety są również w pełni konfigurowalne. Dodatkowo mamy możliwość stworzenia własnych widgetów. Więcej informacji na ten temat można znaleźć tutaj.
W środowisku React wspomniane widgety to nic innego jak komponenty. Dodatkowo Algolia oferuje specjalne hooki, które ułatwiają komponowanie lub tworzenie własnych widgetów od podstaw.
W kontekście projektu użyjemy frameworka Next.js. Nie będziemy omawiać domyślnej konfiguracji projektu w Next, przesyłania danych do Algolia ani podstawowej integracji z Mapbox. Zakładam, że śledzisz mnie od poprzednich artykułów. Jeśli nie, gorąco zachęcam do przeczytania jak stworzyć niestandardową mapę za pomocą Mapbox Studio oraz jak filtrować dane na mapie za pomocą API Algolia.
Na początek musimy najpierw założyć konto w panelu Algolia i przesłać dane. Użyjemy tego samego zestawu danych, co w poprzednim artykule. Szczegółowa instrukcja znajduje się tutaj: Geograficzne filtrowanie z Algolia Geo Search, MapBox i Next.js.
Zacznijmy od zainstalowania niezbędnych bibliotek. Oprócz bibliotek z poprzedniego artykułu, będziemy potrzebować między innymi biblioteki react-instantsearch-hooks-web. Jest to biblioteka przygotowana specjalnie dla środowiska React, oferująca zestaw predefiniowanych widgetów i hooków. Dodatkowo użyjemy również Tailwind CSS. Jest to biblioteka zawierająca zestaw klas CSS, które umożliwiają bardzo szybkie stylizowanie bez potrzeby tworzenia arkuszy stylów. Na stronie Tailwind znajdziesz szczegółową instrukcję jak zainstalować Tailwind w projekcie Next.js. Pamiętaj, aby dodać dyrektywy Tailwind do pliku global.css!
Dobrze, zacznijmy kodować! Jeśli śledzisz mnie od ostatniego artykułu, powinieneś wiedzieć, że nasze dane w Algolia wyglądają tak:
Źródło: Algolia
Mamy kilka pól dostępnych do filtrowania danych. Oprócz pola _geolock, które już zostało użyte w poprzednim artykule, chcemy wykorzystać pola takie jak name, country i links_count, które dla przykładu założymy, że reprezentuje popularność danego lotniska.
Najpierw stwórzmy interfejs Airport, który odzwierciedla typ naszych danych, które posiadamy w Algolia. Będzie nam potrzebny w następnej części posta. Stwórzmy folder components w głównym katalogu naszego projektu, a w nim plik types.ts. Utworzony interfejs powinien wyglądać tak:
Aby używać wbudowanych widgetów, muszą być one opakowane w komponent główny o nazwie InstantSearch, który odpowiada za komunikację z Algolia. Stwórzmy więc komponent AirportsSearch, który z kolei będzie renderował komponent InstantSearch. Będzie on przyjmował argumenty takie jak client i indexName, które są wymagane do nawiązania połączenia z Algolia. Dodatkowo przekażemy prop children, który będzie potrzebny do renderowania mapy i widoku listy. Użyjemy również widgetu Configure zaimportowanego z biblioteki react-instantsearch-hooks-web. Umożliwia on przekazywanie parametrów wyszukiwania do Algolia. W naszym przypadku jedynym parametrem, który przekażemy, jest hitsPerPage, który określa maksymalną liczbę wyników zwracanych przez Algolia. Nie musimy ograniczać się do tego parametru. Pełna lista dostępnych parametrów znajduje się tutaj. Utworzony komponent powinien wyglądać tak:
Jak widzimy w komponencie, są jeszcze trzy komponenty, których jeszcze nie omówiłem, a mianowicie CountryFilter, PopularityFilter i CurrentFilters. Zróbmy to teraz.
Komponent CountryFilter to nic innego jak wrapper dla widgetu RefinementList dostarczonego przez Algolia. Zgodnie z dokumentacją, jest to jeden z najpopularniejszych i najczęściej używanych widgetów. Umożliwia filtrowanie danych za pomocą listy wielokrotnego wyboru dla danego atrybutu. W naszym przypadku chcemy, aby użytkownik mógł filtrować lotniska według kraju, w którym się znajdują. Gorąco zachęcam do zapoznania się z dokumentacją i dostępnymi propsami, które widget przyjmuje.
Komponent PopularityFilter to również wrapper, ale dla widgetu RangeInput. To prosty widget, który pozwala nam wybrać zakres między dwoma liczbami. Podobnie jak w przypadku RefinementList, musimy ustawić odpowiednie pole, na którym powinien działać. Musimy również pamiętać, że to pole musi być liczbowe.
Musimy pamiętać, że aby powyższe widgety działały, każdy z używanych atrybutów musi być dodany do attributesForFaceting w głównym panelu Algolia. Aby to zrobić, przejdź do Configuration -> Facets i dodaj atrybuty jako Attributes for faceting. W naszym przypadku wygląda to tak:
Źródło: Algolia
Ostatnim komponentem jest CurrentFilters. Podobnie jak w przypadku poprzednich komponentów, jest to wrapper dla widgetu Algolia. W tym przypadku jest to CurrentRefinements. Jest to bardzo przydatny widget, który wyświetla aktualne filtry.
Dodajmy powyższe komponenty i renderujmy AirportsSearch w pliku pages/index.tsx. Jako propsy przekaż SearchClient i indexName, które zostały wcześniej utworzone, odpowiadające nazwie naszego indeksu w panelu Algolia. Jako dzieci renderuj mapę i komponenty listy, które omówimy wkrótce. Cały plik wygląda tak:
Dobrze, przejdźmy do Mapy. Sam komponent niewiele różni się od tego, który stworzyliśmy w poprzednim artykule. Jedyną różnicą jest sposób, w jaki uzyskujemy dane. W poprzednim przypadku użyliśmy API Algolia, aby uzyskać nowe lotniska i renderować je na mapie po każdej zmianie współrzędnych geograficznych. Użyliśmy niestandardowej klasy AlgoliaApi oraz biblioteki react-query.
W tym podejściu nie potrzebujemy już tych rzeczy. Nadal będziemy reagować na zmiany współrzędnych, ale aspekt pobierania danych będzie po stronie InstantSearch. Wszystko, co musimy zrobić, to nadpisać nasze filtry po każdej zmianie współrzędnych, a do tego użyjemy hooka useInstantSearch. Całość wygląda tak:
Aby nasze widgety wyglądały ładniej, zainstalujmy również pakiet instantsearch.css używając polecenia npm install instantsearch.css i zaimportujmy następujące style w pliku _app.tsx - import "instantsearch.css/themes/satellite.css". Uruchommy nasz projekt i sprawdźmy, jak działają filtry.
Źródło: Algolia
Udało się! Jak widzimy, nasze lotniska są filtrowane na podstawie kraju, współrzędnych i popularności. Jak zapewne pamiętamy, mamy jeszcze jeden komponent do stworzenia. Załóżmy, że chcemy, aby użytkownik mógł przeglądać lotniska w formie listy oraz mieć możliwość wyszukiwania po nazwie, oprócz mapy.
Więc dodajmy komponent AirportList i renderujmy go w pliku index.tsx tuż poniżej komponentu map. Sam komponent będzie składał się z kilku rzeczy. Pierwszą będzie przycisk, który po naciśnięciu wyświetli lub ukryje naszą listę. Drugą rzeczą będzie widget SearchBox, który pozwoli użytkownikom wyszukiwać lotniska, filtrując je po nazwie, na przykład. Trzecią rzeczą będzie widget Hits, który wyświetla listę uzyskanych wyników. Może przyjąć prop hitComponent jako jeden ze swoich parametrów, do którego możemy przekazać komponent, który powinien być wyświetlany dla każdego renderowanego rekordu. Ostatnią rzeczą będzie widget Pagination. Cały plik wygląda tak:
I tak działa nasza lista:
Źródło: Algolia
Algolia InstantSearch to biblioteka, która umożliwia szybkie stworzenie całego systemu interaktywnego wyszukiwania przy minimalnym wysiłku. Jak widzieliśmy, implementacja jest bardzo prosta, a InstantSearch jest bardzo dobrze zoptymalizowany pod kątem szybkości. Algolia wspiera również inne frameworki, takie jak Vue czy Angular. Zdecydowanie polecam zapoznanie się z dostępnymi opcjami w dokumentacji Algolia i ponowne eksperymentowanie z nimi.
11 marca 2025 • Maria Pradiuszyk
11 marca 2025 • Maria Pradiuszyk