A recipe search site built with Drupal 11 and drupal/meilisearch, the Meilisearch backend for Search API. One command gives you 116 recipes, typo-tolerant search that updates as you type, facets and highlighted excerpts.
git clone https://github.com/meilisearch/drupal-meilisearch-demo.git
cd drupal-meilisearch-demo
cp .env.example .env
docker compose up --buildYou only need Docker. The image installs drupal/meilisearch from drupal.org and runs Meilisearch next to Drupal.
The first start installs Drupal, creates the recipes and indexes them, which takes a minute or two. Then open http://localhost:8080. On OrbStack, http://drupal.drupal-meilisearch-demo.orb.local works too.
To log in, use admin / admin (a deployed demo sets its own, see Deploy).
-
Type. Results, facet counts and highlights follow every keystroke. The green pill is Meilisearch's own processing time.
-
Click the Try chips under the search box:
Chip What it shows chikenTypo tolerance: chicken recipes, with Chicken highlighted tiramiPrefix search: the last word matches as you type "coconut milk"Phrase search curry -chickenLeaving a word out vegan dessertCuisine, meal and diet are searchable too -
Open Under the hood. It shows the request drupal/meilisearch sent for this page: the query, the filter built from the facets, the sort, highlighting. Keep it open while you type and click.
-
Pick two cuisines. Cuisine is an OR facet: the filter becomes
(cuisine = "Indian" OR cuisine = "Thai")and the other cuisines keep their counts, through a second query in the same multi-search. -
Filter and sort: Under 30 min, Top rated, Quickest.
-
Edit a recipe. Log in (
admin/admin), change a title, search for it: it is indexed on save.
Press / to jump to the search box and Esc to clear it.
In the admin, Search settings (top right) opens the Recipes index; its Processors tab has the Meilisearch highlighting settings.
| Part | Where |
|---|---|
| Stack: Meilisearch, and Drupal on SQLite | compose.yaml, Dockerfile |
| First-start install | docker/entrypoint.sh |
| Meilisearch URL and key from the environment (the recommended setup) | docker/settings.demo.php |
| Content model, server, index, facets, blocks and recipes | web/modules/custom/meilisearch_demo/src/DemoSetup.php |
| The search view | web/modules/custom/meilisearch_demo/config/demo/views.view.recipes.yml |
| Theme and live search | web/themes/custom/meili_kitchen |
Try chips, and recording the request for Under the hood (hook_meilisearch_search_params_alter()) |
web/modules/custom/meilisearch_demo/meilisearch_demo.module |
| Recipe data (written for this demo) | scripts/recipes.py builds data/recipes.json |
Live search is a small script: it fetches the next results page from Drupal and swaps the results and the facets. Every search still goes through Views, Search API and the module.
To try changes to drupal/meilisearch, build the demo from a local checkout of the module instead of the drupal.org release. In .env:
COMPOSE_FILE=compose.yaml:compose.module.yaml
MEILISEARCH_MODULE_PATH=../meilisearch-drupalThen rebuild and keep it in sync while you edit:
docker compose up --build -d
docker compose watchThis syncs the theme, the demo module and the module's src/. Clear caches after changes to services or plugins:
docker compose exec drupal vendor/bin/drush crThe image runs anywhere that runs a container with a persistent disk. It installs drupal/meilisearch from drupal.org; the site (SQLite database and uploads) lives in /opt/drupal/web/sites/default/files, which must be on that disk. Set:
| Variable | Value |
|---|---|
MEILISEARCH_URL, MEILISEARCH_API_KEY |
A Meilisearch Cloud project, or any reachable instance |
DRUPAL_ADMIN_PASSWORD |
The admin password, applied on every start |
TRUSTED_HOST_PATTERNS |
The site's host names as regular expressions, comma-separated, for example ^demo\.example\.com$ |
MEILISEARCH_INDEX_PREFIX |
Optional: an index prefix, so the demo never touches other indexes of the project |
The container listens on port 80. The first start installs Drupal and indexes the recipes, which takes a few minutes; the logs show [demo] Ready when it is done.
docker compose down -vThe next up installs everything again.
- Port already in use: set
DEMO_PORTorMEILISEARCH_PORTin.env. - "400 Bad Request" in the browser: fixed in the image (browsers send every
localhostcookie to every port, which can exceed Apache's default header size). Rebuild withdocker compose up --build, or use the OrbStack URL. - Search feels slow: each search fetches the next page from Drupal in the background (about 50–250 ms here; Meilisearch's share is a few milliseconds, shown in the pill). A busy machine slows Drupal down first.
- The install fails at the Meilisearch step: check
docker compose logs meilisearch, thendocker compose down -v && docker compose up. - The build fails on
drupal/meilisearchwithcompose.module.yaml:MEILISEARCH_MODULE_PATHmust point at the module's root, the folder with itscomposer.json.
Semantic and hybrid search (they need an embedder), Cloud click analytics, location search and multilingual content are described in the module's documentation.
GPL-2.0-or-later, like Drupal. See LICENSE.txt.
