Search by

pollora / meilifacets

pollora

Faceted search, filtering and suggestions powered by Meilisearch for Pollora projects.

Package info

github.com/Pollora/MeiliFacets

Type:laravel-library

pkg:composer/pollora/meilifacets

Statistics

Installs: 94

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 3

0.3.0 2026-10-19 13:46 UTC

This package is auto-updated.

Last update: 2026-10-19 13:46:34 UTC


README

MeiliFacets: Meilisearch facets and site search for Pollora

Latest Stable Version Total Downloads License

MeiliFacets is a Pollora module that adds faceted product listings and a site-wide search panel, served by Meilisearch straight from the visitor's browser. It is for WooCommerce and content sites built on Pollora: the first page is rendered by PHP with the URL's filters applied, and every later click is one request to the engine, with no WordPress page load in the loop.

You want to…

Installation

composer require pollora/meilifacets:^0.3 -W

MeiliScout 2.5.1 or later comes with the module. The project's composer.json needs an installer-paths rule and merge-dev: false first, and the module is then enabled in modules_statuses.json: the whole sequence is in Installation.

Requirements

PHP 8.4 or later
Framework Pollora 13.x from 13.35.3 (pollora/framework >=13.35.3 <14), on Laravel 13. Laravel modules (nwidart/laravel-modules) ship with Pollora
Indexing MeiliScout (amphibee/meiliscout), a WordPress plugin, 2.5.1 or later
Engine a Meilisearch server
Products WooCommerce, for the product listing and its prices. The site search works without it
Optional ext-intl, so that facet values ordered by name follow the site's language

Quick start

A product listing, composed from the module's Blade components:

<x-meilifacets::listing>
    <x-meilifacets::listing.active-values />
    <x-meilifacets::listing.sort />
    <x-meilifacets::listing.reset />
    <x-meilifacets::listing.facets />
    <x-meilifacets::listing.results />
    <x-meilifacets::listing.pagination />
</x-meilifacets::listing>

A search panel in the header:

<header class="site-header">
    {{-- logo, menu… --}}
    <x-meilifacets::search />
</header>

What it is

Two features, both served by Meilisearch:

  • Listing filters. Facets by taxonomy or product attribute, a price range, sorting, pagination, active filters, a search field that narrows the list, and a mobile drawer.
  • Site search. A magnifier in the header opens a panel with one section per content type: products, posts, pages and any indexed custom post type, with a result count and a link to the full results.

What it does not do: it does not index anything itself, and it does not replace WordPress's routing or templates. MeiliScout, a WordPress plugin, builds and pushes the documents.

How it works

First render
  browser ──► WordPress / Pollora ──► Meilisearch
  the filters of the URL are applied by PHP

Every later gesture
  browser ──► Meilisearch
  one request, no WordPress in the loop

Indexing
  WordPress ──► MeiliScout ──► Meilisearch
  MeiliFacets adds its fields to each document
  • The server renders the first page with the filters of the URL already applied. The page is complete without JavaScript, and search engines see real content.
  • After that, every check, sort, page or search term is a single request from the browser to Meilisearch. The client rewrites the address bar, so a filtered view can be bookmarked and shared.
  • The engine computes the results and the facet counts in a few milliseconds. A full WordPress page load is avoided on every click, while WordPress keeps the URLs, the routing and the SEO.
  • MeiliScout indexes, MeiliFacets queries. The module adds its own fields (facets, card, price…) to the documents MeiliScout builds, and declares the index settings it needs.

What you get without writing PHP

On a WooCommerce project, with MeiliScout indexing products:

  • a product listing named products, filtered by category and brand;
  • sorting by relevance, price low to high, price high to low and newest; « On sale » is added when you declare a price filter;
  • cards with the image, title, link and the price as the shop displays it, taxes included or not;
  • a site search over every public post type MeiliScout indexes, products first.

Everything else (other facets, the price filter, your own card, other sorts) is a configuration key, a view override or a container binding. See Quick start.

Design principles

  • The URL is the state. WordPress's own paths are kept, filters travel as query parameters, and the server applies them on first render.
  • Behaviour in the module, appearance in the theme. Every view can be overridden from the theme. The stylesheets are neutral and tuned with CSS custom properties.
  • Hooks, not classes. The browser client binds to data-meili attributes, never to a class name. A theme changes tags and classes freely as long as it keeps the hooks.
  • Every shop-specific choice is a contract with a default. Facets, sorts, the card, the searched fields and the searched types each sit behind a PHP interface. A project with nothing to declare gets a working listing; a project that binds its own implementation wins.
  • The browser key is public, so the index exposes little. The search key travels to every visitor. The index only lets it read ID, card and parent_id, and it must only hold published content. See Going to production.

Documentation

Installing a module with Composer, and the installer-paths rule it needs, is covered on pollora.dev/advanced/modules. The module's own guide lives in docs/:

Reading this documentation

  • Commands are written without a container runner: php artisan …, wp meiliscout index, composer …. Prefix them with yours when PHP runs in a container (ddev exec php artisan …, ddev wp …, docker compose exec …).
  • <theme> stands for the active theme's folder. A view override lives under <theme>/resources/views/modules/meilifacets/….
  • Component tags are written with their full prefix: <x-meilifacets::listing.facet>.

Map

Section Pages
Getting started Installation · Going to production · Quick start
Listing and filters How a listing works · Facets · Price filter · Results, sorting and pagination · Mobile drawer and filter bar · Listing other content
Site search Site search · Composing the search panel · Searchable content types
Relevance and indexing What gets indexed · Search relevance · Indexed prices (WooCommerce)
Customising Overriding views · Your own card · Styles and design tokens · PHP extension points · Translating the interface
Accessibility Accessibility and motion
Reference Overview · Blade components · data-meili hooks · CSS custom properties · Configuration and environment · PHP contracts · WordPress filters and actions · Index settings and document fields · Errors and console messages · Commands
When something goes wrong Troubleshooting and FAQ
Releases Changelog · Upgrading

The maintainers' design notes, in French, are in docs/internal/: decisions, measurements and known traps gathered while building the module. They are not needed to use it.

Development

Run these from a clone of the module's repository, not from a copy installed in a project. The repository keeps its own node_modules, which only serves the system that installed it. Node 24.12 or later is required.

npm install
composer install

composer check   # Pint, ESLint, tsc, Rector, standalone PHP tests, client tests, bundle up to date
composer test    # standalone PHP tests only (Unit suite)
npm test         # client tests only
composer build   # rebuild resources/assets/dist after changing the client

The Feature tests render Blade views and need a host application. Run them from a Pollora project where the module is installed, with a PHPUnit suite that includes Modules/MeiliFacets/tests/Feature.

Commits follow Conventional Commits. Before opening a pull request, composer check and the Feature tests should both pass. The current release is 0.3.0, a beta: see the changelog.

Contributing

Contributions are welcome: see the contributing guide. Report security issues privately, as described in the security policy.

License

MeiliFacets is open-source software licensed under the GPL-2.0-or-later. © RuBee group