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’sSearch 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 thelunarphp/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
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..env file:
Indexing Products
After configuring the driver, import existing products into the search index:Searchable Models
The following models are searchable by default:Searching Products
Use theSearch 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.
model() to specify it:
Search Results
TheSearchResults 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 thePricing facade or access relationships), load the models from the hit IDs:
Sorting Results
Use thesort() method with a field:direction string to control result ordering.
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 theProduct model:
Displaying Facets
After executing a search, thefacets property on the results contains the available facet groups with value counts.
SearchFacet has:
Each
SearchFacetValue has:
Applying Facet Filters
Pass filters as an associative array to thefilter() method. Multiple values for the same facet use OR logic.
URL-Based Product Resolution
Lunar stores SEO-friendly slugs in theLunar\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 assearchable 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:
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.