#search-engine #leptos #meilisearch #integration #resources #helper #wrapping

leptos_meilisearch

A Leptos integration for Meilisearch, wrapping them in a Resource and helps with useful helper functions und utils

12 releases (5 breaking)

0.6.2 May 24, 2024
0.5.0 May 5, 2024
0.4.0 Mar 24, 2024
0.1.0 Nov 5, 2023

#1524 in Web programming

MIT license

48KB
630 lines

Leptos Meilisearch Integration

leptos_meilisearch is an integratin helper for meilisearch. It's wrapping the meilisearch_sdk struct to make it compatible with leptos. You can manipulate the SearchQuery with a built-in wrapped resource system. This allows to use the leptos resource and communicate easily with you meilisearch search engine.

Table of Contents

Leptos compatibility

Crate version Compatible Leptos version
<= 0.1 0.5
0.2 0.6
0.3 0.6
0.4 0.6

Installation

To use the leptos_meilisearch integration in your project, you need to add it along with its dependencies to your Cargo.toml file.

[dependencies]
leptos_meilisearch = "0.2"

Usage

The leptos_meilisearch is really just a wrapper class arounnd the meilisearch_sdk. The documentation for meilisearch itself is quite good, which I really recommend! But this library should help to work much easier with leptos.

Initialization and Example

use std::collections::HashMap;

use chrono::{DateTime, FixedOffset};
use leptos::*;
use leptos_meilisearch::*;

// This is how the struct for a Product looks like in the meilisearch `products`
// index.
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Product {
    pub id: String,
    pub name: String,
    pub description: String,
    pub preview_image_url: Option<String>,
    pub price: f32,
    pub tax: f32,
    pub created: DateTime<FixedOffset>,
    pub updated: DateTime<FixedOffset>,
    pub categories: HashMap<String, String>,
}

// This is how the struct for an User looks like in the meilisearch `users`
// index.
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct User {
    pub id: String,
    pub name: String,
    pub roles: Vec<String>,
}

#[component]
pub fn App() -> impl IntoView {
    provide_meta_context();

    let meilisearch_parameters = AuthParameters {
        host: "https://your-api-endpoint".to_string(),
        api_key: Some(
            "your-search-api-key".to_string(),
        ),
    };

    // Initializing needs to define the structured design of the Meilisearch
    // view. This can be done by definining a struct an implement `Deserialize`
    // for it.
    SingleSearch::<Product>::init(
        meilisearch_parameters.clone(),
        "products",
        &SearchQueryBuilder::default()
            .hits_per_page(12_usize)
            .facets(Selectors::Some(vec!["categories"])),
    )
    .expect("unable to init meilisearch");

    // You can initialize also multiple systems, if you have products and for
    // example users, which accessible under different indexes.
    SingleSearch::<User>::init(
        meilisearch_parameters.clone(),
        "products",
        &SearchQueryBuilder::default(),
    )
    .expect("unable to init meilisearch");

    view! {
        <Stylesheet id="leptos" href="/pkg/main.css"/>

        <Link rel="shortcut icon" type_="image/ico" href="/favicon.ico"/>

        <Router>
            // Your app with router
        </Router>
    }
}

// In this example you can see how you can manipulate the `SearchQuery`, for
// example a live search query
#[component]
pub fn ProductSearchBar() -> impl IntoView {
    let products = expect_context::<SingleSearch<Product>>();

    view! {
       <input
           type="search"
           id="products-search"
           on:input=move |ev| {
               products
                  .search_query()
                  .update(move |search_query| {
                      search_query.query = Some(event_target_value(&ev));
                   })
           }
       />
    }
}

// Here you can see a list of products, which can be fetched from the
// Meilisearch resource. The **leptos_meilisearch** library has also some helper
// function, for example `hits`, which return just the hits.
#[component]
pub fn ProductList() -> impl IntoView {
    let products = expect_context::<SingleSearch<Product>>();
    // You can also fetch multiple meilisearch resources at the same time.
    let _users = expect_context::<SingleSearch<User>>();

    view! {
        <For
            each=move || {
                products
                    .hits()
                    .map(|search_result| {
                        search_result
                            .into_iter()
                            .map(|hit| hit.result)
                            .collect::<Vec<Product>>()
                    })
                    .unwrap_or_default()

            }

            key=|product| product.id
            children=move |product: Product| {
                view! {
                    <h1>{product.name}</h1>
                    <h2>{product.price}</h2>
                }
            }
        />
    }
}

License

leptos_meilisearch is distributed under the MIT License. For more information, see the LICENSE file.

Dependencies

~28–45MB
~844K SLoC