Skip to main content

Overview

Product search lets customers find products by typing keywords, browsing faceted filters, and navigating directly to products via URLs. This guide walks through building search and discovery features using Lunar’s Search facade and Url model. The examples below use standard Laravel controllers and Blade templates. The same concepts apply whether the storefront is built with Livewire, Inertia, or a headless API.

Search Setup

Lunar’s search system is provided by the lunarphp/search add-on package. It is built on top of Laravel Scout with a driver-based architecture that supports Meilisearch, Typesense, and a database fallback. The Search facade provides a consistent API regardless of which driver is active.

Installing the Search Package

This installs the Search facade, search indexers, and data classes used throughout this guide.

Installing a Search Driver

For production storefronts, install either Meilisearch or Typesense. The database driver works out of the box but lacks faceting and advanced relevance features.
Set the driver in the application’s .env file:

Indexing Products

After configuring the driver, import existing products into the search index:
Lunar automatically keeps the index in sync as products are created, updated, or deleted.

Searchable Models

The following models are searchable by default:

Searching Products

Use the Search facade to query products. The query() method accepts a search string, and get() returns a Lunar\Search\Data\SearchResults object. Products are the default model, so no additional configuration is needed.
To search a different model, use model() to specify it:

Search Results

The SearchResults object contains everything needed to render a results page: Each SearchHit contains:

Building a Search Controller

Displaying Search Results

Search hits contain the indexed document data, not Eloquent models. The indexed fields for products include id, status, product_type, brand, thumbnail, skus, and any attributes marked as searchable. To load full Eloquent models from search results, collect the IDs and query the database.

Loading Eloquent Models from Results

When full model data is needed (for example, to use the Pricing facade or access relationships), load the models from the hit IDs:

Sorting Results

Use the sort() method with a field:direction string to control result ordering.
The sortable fields for products are created_at, updated_at, skus, and status. Additional sortable fields can be configured in a custom indexer.

Letting Customers Choose a Sort Order

Faceted Filtering

Facets allow customers to narrow results by attributes like brand, size, or color. Facets are configured per model in the search configuration and are only available when using Meilisearch or Typesense.

Configuring Facets

Publish the search configuration and define facets for the Product model:
Each key in the facets array corresponds to a field in the product’s search index. Additional facets can be added for any indexed field.

Displaying Facets

After executing a search, the facets property on the results contains the available facet groups with value counts.
Each SearchFacet has: Each SearchFacetValue has:

Applying Facet Filters

Pass filters as an associative array to the filter() method. Multiple values for the same facet use OR logic.
Filters can also be added individually:

URL-Based Product Resolution

Lunar stores SEO-friendly slugs in the Lunar\Models\Url model. Products, collections, and brands all support URL resolution through the HasUrls trait.

Defining a Catch-All Route

A common pattern is to define a catch-all route that resolves the URL to the correct model type:

Resolving the URL

Working with URLs on Models

Searchable Attributes

Product attributes marked as searchable in the admin panel are automatically included in the search index. This means customers can search by any attribute value, such as material, color, or specifications. The search index for a product includes:
To make an attribute searchable, edit the attribute in the Lunar admin panel and enable the “Searchable” option. After changing searchable attributes, reimport the search index with php artisan scout:import "Lunar\Models\Product".

Routes

Putting It All Together

Here is a complete search controller with faceted filtering and sorting:

Next Steps

  • Review the Search reference for the full list of searchable models and configuration options.
  • Review the Search add-on for advanced search engine configuration.
  • Review the Extending Search guide for customizing indexers and adding custom fields to the search index.
  • Review the Product Listing Page guide for collection-based product browsing as an alternative to search.