Magento 2 Extension v1.5.0 Buy — $199

TypesenseSearch for Magento 2

A drop-in Typesense integration that replaces Magento's default search with a blazing-fast, typo-tolerant, faceted search engine — with real-time autocomplete, AI query rewriting, and a fully configurable storefront results page.

Real-time Search
Autocomplete, search-as-you-type with sub-10 ms responses from Typesense.
🎯
Faceted Filtering
Category, color, size, price slider and any custom product attribute.
🤖
AI Query Rewriting
Optional AI layer strips price intents and rewrites queries before hitting Typesense.
🔄
Incremental Indexing
Product, category, page, and suggestion indexers — with Mview-based queue support.
👤
Personalization
Boosts products each shopper has clicked, carted, or purchased to the top of their results.

Requirements

Dependency Version Notes
Magento Open Source / Adobe Commerce 2.4.x Tested on 2.4.6 – 2.4.9
PHP 8.1 – 8.3 Required by Magento framework
Typesense Server 0.25+ Self-hosted or Typesense Cloud
typesense/typesense-php ^4.8 Installed via Composer
php-http/curl-client ^2.3 HTTP transport for the PHP client

Installation

Install via Composer after configuring your credentials. See your dashboard for your license key.

1
Add the repository to your project (one-time)
composer config repositories.ayasoftware composer https://www.ayasoftware.com/repo
2
Add your credentials to auth.json (one-time)
composer config --global http-basic.www.ayasoftware.com your@email.com YOUR_LICENSE_KEY

Your license key is available in the Ayasoftware dashboard.

3
Require the extension
composer require ayasoftware/typesensesearch
4
Enable the module and run setup
bin/magento module:enable Ayasoftware_TypesenseSearch
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f en_US
bin/magento cache:flush
💡
In a devcontainer environment the setup commands run inside the php container. Run them from /workspace/magento.

Typesense Server

The module requires a running Typesense server. It can be self-hosted or provisioned via Typesense Cloud.

Self-hosted (recommended for development)

Download the binary and start the server with your data directory and API key:

/path/to/typesense-server \
  --data-dir=/var/typesense-data \
  --api-key=YOUR_API_KEY \
  --listen-port=8108 \
  --enable-cors

Nginx proxy (recommended for Codespaces / cloud)

When the Typesense port is not directly reachable from the browser, add a proxy block to your Nginx config so the storefront can reach Typesense through the existing :8000 port:

nginx.conflocation /typesense/ {
    proxy_pass       http://php:8108/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Then set the Public Path field to /typesense in the Magento admin config (see below). The storefront JS will automatically route all Typesense requests through the Nginx proxy.

⚠️
On container restarts, the Typesense process must be restarted manually unless you configure auto-start. See the Auto-Start section.

Magento Configuration

Navigate to Stores → Configuration → Ayasoftware → Typesense Search.

Credentials

FieldConfig PathDescription
Enable Frontend typesense_general/credentials/enable_frontend Globally enables/disables the extension
Search API Key typesense_general/credentials/search_only_api_key Read-only key exposed to the browser
Admin API Key typesense_general/credentials/admin_api_key Full-access key used by PHP indexers (never sent to browser)
Node (internal) typesense_general/credentials/node Hostname/IP used by PHP (e.g. localhost)
Public Node typesense_general/credentials/public_node Hostname used by the browser (e.g. your Codespace domain)
Public Path typesense_general/credentials/public_path Proxy path prefix, e.g. /typesense. When set, browser requests route through Nginx.
Port typesense_general/credentials/port Internal port (default 8108)
Public Port typesense_general/credentials/public_port Browser-facing port (e.g. 443 behind Nginx)
Protocol typesense_general/credentials/protocol http for internal, https for public
Index Prefix typesense_general/credentials/index_prefix Prefix for Typesense collection names, e.g. magento_

Search Result Page

FieldConfig PathDefault
Enable Result Page typesense_search_result/instant_search_result/enable_result_page 1
Products Per Page typesense_search_result/instant_search_result/page_per_product 12
Enable Price Slider typesense_search_result/instant_search_result/enable_price_slider 1
Enable Add to Cart typesense_search_result/instant_search_result/enable_addtocart 0

Search Filters

Filters are configured under Stores → Configuration → Ayasoftware → Typesense Search → Search Result → Search Filters.

Each filter row has three columns:

  • Attribute — the Typesense field name (must be marked facet: true in the schema)
  • Label — display name shown in the filter sidebar
  • OptionSearchable, Not Searchable, or Filter Only

Default filter set (v1.2.1)

AttributeLabelMode
categoryCategoryFilter Only
colorColorFilter Only
sizeSizeFilter Only
materialMaterialFilter Only
genderGenderFilter Only
pricePricePrice Slider
💡
Only attributes indexed as facet: true in the Typesense schema can be used as filters. Run the product indexer to rebuild the schema after adding new attributes.

Price Slider

The price slider renders a jQuery UI range input in the filter sidebar. Enable it at Search Result → Enable Price Slider and add price to Search Filters.

Behaviour

  • The slider's min / max bounds are fixed to the unfiltered price range of the current keyword. Applying a price filter does not shrink the bounds — you can always widen the range back.
  • The search fires only when the handle is released (not on every pixel drag), keeping the UI responsive.
  • The price range input is editable — type any value (e.g. 100 - 500 or $100 – $500) and press Enter to apply.
  • Removing the price filter chip resets the handles to the full absolute range.

Customising slider CSS

typesense.css/* Slider track */
#price-range.ui-slider {
    background: #dde8f5;
    height: 6px;
    margin: 38px 10px 10px;
}

/* Drag handles */
#price-range.ui-slider .ui-slider-handle {
    background: #1979C3;
    height: 22px;
    width: 22px;
}

/* Tooltip bubble */
.ts-price-tooltip {
    background: #1979C3;
    color: #fff;
    padding: 2px 6px;
    border-radius: 4px;
}

Items Per Page

Two config values control the per-page selector in the search results toolbar:

Config PathValueEffect
typesense_search_result/instant_search_result/page_per_product 12 Default number of products fetched per page
catalog/frontend/grid_per_page_values 12,24,36 Options shown in the "Show N per page" dropdown

Set via CLI:

bin/magento config:set typesense_search_result/instant_search_result/page_per_product 12
bin/magento config:set catalog/frontend/grid_per_page_values 12,24,36
bin/magento cache:clean config

Personalization

When enabled, search results and category pages boost products based on each shopper's individual behaviour — clicks, add-to-cart events, and purchases. A visitor with no recorded history sees the standard ranking unchanged.

How it works

At page render time the extension queries the ayasoftware_search_events table for the current visitor, computes a weighted score per product, and injects a Typesense _eval() expression into the sort_by parameter. Products with higher scores float toward the top of results for that specific visitor.

  • Logged-in customers — history is scoped by customer_id and persists across sessions and devices.
  • Guests — history is scoped by the session cookie (typesense_search_session) for the duration of the browser session.
  • Boost scores are cached in Redis for 15 minutes per visitor to avoid repeated DB queries on every page load.
  • A manual sort selection by the shopper (price, newest, etc.) always overrides personalisation.

Configuration

Navigate to Stores → Configuration → Ayasoftware → Typesense Search → Personalization.

FieldConfig PathDefaultDescription
Enable Personalization typesense_personalization/settings/enabled No Master toggle. Off by default.
History Window (days) typesense_personalization/settings/history_days 30 How many days of past events to include in the score calculation.
Max Products to Boost typesense_personalization/settings/max_boosts 20 Cap on the number of products included in the _eval() formula. Keep ≤ 20 to avoid bloating search requests.
Click Weight typesense_personalization/settings/click_weight 1 Score per product click event.
Add to Cart Weight typesense_personalization/settings/add_to_cart_weight 3 Score per add-to-cart event.
Purchase Weight typesense_personalization/settings/order_weight 5 Score per order event. A single purchase outweighs five clicks.
Enable A/B Test typesense_personalization/settings/ab_test_enabled No Split visitors into control (standard ranking) and treatment (personalised ranking) groups. Requires Personalization to be enabled.

Database migration

Version 1.3.0 adds a customer_id column to ayasoftware_search_events. Run the following after upgrading:

bin/magento setup:upgrade
bin/magento cache:flush
💡
Personalization improves over time. A brand-new store with no event history will see no effect until shoppers start interacting with search results. The first noticeable impact typically appears after a few days of normal traffic.

Performance under load

Two changes in v1.4.0 address concurrency pressure at scale:

  • Cache stampede prevention (ProfileBuilder) — The 15-minute TTL now has jitter (base 900 s + a random 0–120 s), so users who start sessions in the same window don't expire in lockstep and trigger the expensive GROUP BY rebuild all at once. On a cache miss, a lock ensures only one request per user rebuilds the profile — concurrent requests for the same key return empty immediately (personalization is a boost, not a hard requirement) rather than dog-piling the database. Late arrivals pick up the warm cache on the next request.
  • Async analytics writes — The bigger pressure point wasn't Redis at all — it was the synchronous MySQL INSERT on every click and search event, which hits connection limits well before the cache layer becomes a concern. That path is now asynchronous: the Track controller publishes the event to a message queue and the request returns as soon as it's enqueued, while a background consumer handles the actual insert. It reuses the existing queue infrastructure, so there are no new dependencies.

Net effect: read pressure is spread across time and deduplicated per user, and write pressure is decoupled from the request lifecycle entirely.

ℹ️
The analytics consumer must be running for events to reach the database. Start it with bin/magento queue:consumers:start typesense.analytics.event or add it to your supervisor / cron configuration.

Running Indexers

The extension ships four indexers. Run them in this order for a full initial index:

# Prerequisite — rebuild Magento's category product index first
bin/magento indexer:reindex catalog_category_product catalog_product_category

# Typesense indexers
bin/magento indexer:reindex typesense_products typesense_categories typsense_pages suggestions
⚠️
The product indexer uses an INNER JOIN on catalog_category_product_index_store{N}. Products not present in that index will be silently excluded from Typesense. Always rebuild catalog_category_product before re-indexing products.

Indexer reference

Indexer IDWhat it indexes
typesense_productsCatalog products — name, attributes, price, images, stock
typesense_categoriesCategory tree
typsense_pagesCMS pages
suggestionsPopular search suggestions

Partial re-index (Update on Schedule)

Set the indexers to Update by Schedule in the Magento admin and ensure the cron is running. Product saves, stock changes, and category updates will queue incremental re-index jobs automatically.

Auto-Start on Container Restart

For devcontainer environments, add the provided startup script to postStartCommand so Typesense starts automatically on every container boot.

1. Create the startup script

Save as .devcontainer/bin/start-typesense.sh:

start-typesense.sh#!/usr/bin/env bash
set -u

# Re-exec detached so postStartCommand doesn't kill us when it returns
if [ -z "${_TS_DETACHED:-}" ]; then
    _TS_DETACHED=1 setsid -f "$0" "$@" </dev/null >>/workspace/typesense-data/typesense.log 2>&1
    exit 0
fi

BINARY=/workspace/typesense-bin/typesense-server
DATA_DIR=/workspace/typesense-data
API_KEY=${TYPESENSE_API_KEY:-localdev_key_123}

# Kill stale instance and clear lock files
for p in /proc/[0-9]*; do
    cmdline=$(tr '\0' ' ' < "$p/cmdline" 2>/dev/null) || continue
    case "$cmdline" in *typesense-server*) kill "${p#/proc/}" 2>/dev/null ;; esac
done
sleep 1
rm -f "$DATA_DIR/db/LOCK" "$DATA_DIR/meta/LOCK"

exec "$BINARY" \
    --data-dir="$DATA_DIR" \
    --api-key="$API_KEY" \
    --listen-port=8108 \
    --enable-cors

2. Register in devcontainer.json

devcontainer.json"postStartCommand": {
    "forward-ports": "/bin/bash .devcontainer/bin/forward-ports.sh",
    "typesense":     "/bin/bash .devcontainer/bin/start-typesense.sh"
}
The script clears stale RocksDB LOCK files automatically, preventing the segfault that occurs when a previous instance was killed abruptly.

Troubleshooting

"Configuration issues try again" on the storefront

The Typesense client failed to connect. Check in order:

  1. Typesense server is running: curl http://localhost:8108/health should return {"ok":true}
  2. Nginx proxy is responding: curl http://nginx:8000/typesense/health
  3. Search API key and node/port are correctly saved in Magento config
  4. Run bin/magento cache:flush after any config change

Products missing from search results

  1. Confirm the product is enabled with visibility set to Catalog, Search
  2. Confirm the product is assigned to a website
  3. Rebuild catalog_category_product first, then re-run typesense_products
  4. Check the Typesense collection: curl -H "X-TYPESENSE-API-KEY: <key>" http://localhost:8108/collections/magento_default-products/documents/search?q=<sku>&query_by=sku

Filters not showing on results page

  1. Verify Search Filters is not empty in admin config
  2. Verify each filter attribute is listed as facet: true in the Typesense collection schema
  3. Flush full_page and block_html caches after any config change

Typesense crashes with segfault on restart

Stale lock files from a previous killed process. Remove them:

rm -f /workspace/typesense-data/db/LOCK /workspace/typesense-data/meta/LOCK

Then restart the server. The auto-start script (v1.2.1+) handles this automatically.

Checking the Typesense index

# List collections and document counts
curl -s -H "X-TYPESENSE-API-KEY: <key>" http://localhost:8108/collections \
  | python3 -c "import sys,json; [print(c['name'], c['num_documents']) for c in json.load(sys.stdin)]"

Changelog

v1.5.0 June 15, 2026
  • Feat
    A/B Testing for Personalisation — Split visitors deterministically into control (standard ranking) and treatment (personalised ranking) groups. Assignment is a hash of the visitor identity so it is sticky across requests with no extra state. Configure via Stores → Configuration → Ayasoftware → Typesense Search → Personalization: toggle, experiment name (changing it reshuffles assignments), and traffic split %.
  • Feat
    A/B Results in Analytics Dashboard — When both variants have recorded data a side-by-side comparison panel appears automatically, showing CTR, add-to-cart rate, conversion rate, and revenue per variant with a Δ% column and winner highlighting.
  • Impr
    ab_variant column added to ayasoftware_search_events (nullable — null means experiment was off) and ayasoftware_search_analytics (not null, default none). Run bin/magento setup:upgrade after updating.
  • Impr Analytics aggregation now groups by variant, so control and treatment metrics accumulate in separate rows without affecting existing non-experiment data.

v1.4.0 June 15, 2026
  • Impr
    Cache stampede prevention — Personalization profile TTL now includes a random 0–120 s jitter so sessions that start together don't expire together. A per-user lock on cache miss ensures only one request rebuilds the profile; concurrent requests degrade gracefully to unranked results rather than piling onto the database.
  • Impr
    Async analytics writes — The Track controller now publishes events to the typesense.analytics.event message queue instead of inserting directly into MySQL. The web request returns immediately; a background consumer handles the insert. Requires bin/magento queue:consumers:start typesense.analytics.event.

v1.3.0 June 12, 2026
  • Feat
    Personalization Signals — Search results and category pages now boost products based on each shopper's click, add-to-cart, and purchase history. Works for both logged-in customers and guests. Scores are cached in Redis; degrades gracefully for first-time visitors.
  • Feat
    New Personalization admin config group — enable/disable toggle, history window, max products to boost, and per-event-type weight controls (click / add to cart / purchase).
  • ImprAnalytics tracking now records customer_id for logged-in shoppers, enabling history that persists across sessions and devices.
  • ImprAdded customer_id column (with index) to ayasoftware_search_events. Run bin/magento setup:upgrade after updating.

v1.2.1 June 11, 2026
  • FixSearch results page not showing any filters
  • FixPrice attribute not appearing in the filter sidebar
  • FixPrice slider max value permanently reduced after filtering
  • FixPrice slider not resetting when the price filter chip is removed
  • FixEnter key not applying the typed price range
  • FeatAuto-start Typesense on devcontainer boot via postStartCommand
  • FeatPrice handles show a live tooltip with the current value while dragging
  • FeatPrice range input is editable — type a range and press Enter to apply
  • ImprPrice slider fires search on handle release only, not on every drag pixel
  • ImprSearch results default to 12 items per page with a 12/24/36 selector
  • ImprFilters pre-configured out of the box: Category, Color, Size, Material, Gender, Price

v1.2.0 Previous release

New Features

  • Feat
    AI Search Intent — Transform natural language searches into intelligent filters, categories, price ranges, brands, and attributes automatically.
  • Feat
    Search Analytics Dashboard — New Magento Admin dashboard with store and 7 / 30 / 90-day filters. Tracks search impressions, product clicks, add-to-cart events, orders, conversion rates, and revenue attribution.
  • Feat
    Actionable Recommendations — Surfaces zero-result searches, low click-through queries, and frequently searched terms that generate no orders.
  • Feat
    Daily Analytics Aggregation — Efficient cron-based aggregation for fast reporting across large datasets.
  • Feat
    Multilingual AI Filter Parsing — AI-powered natural-language filter parsing supporting multilingual queries.
  • Feat
    AI Provider Selection — Choose between Claude, OpenAI, and Google Gemini. Provider-specific API key and model configuration shared by query rewriting and AI filters.

Improvements

  • ImprImproved search result product rendering and interaction handling
  • ImprExpanded product attribute configuration options
  • ImprUpdated module and Composer package version to 1.2.0

v1.1.0 Previous release

New Feature — AI-Powered Query Rewriting

  • Feat
    Claude AI query rewriting — Search queries on the result page are automatically cleaned and expanded before being sent to Typesense, improving result quality for conversational, abbreviated, or misspelled queries.
  • Feat
    Result page banner — When a query is rewritten, the page shows "Showing results for: [rewritten query]" with an option to search the original term instead.
  • Impr
    Redis caching — Rewritten queries are cached for 24 hours. Repeated queries cost nothing. Falls back to the original query silently if the API is unavailable or times out.

Examples

Original queryRewritten to
"cheap red running shoes"Removes filler, focuses on product terms
"tee shirt xl""t-shirt xl" — expands abbreviations
"do you have argus tank""argus tank" — strips conversational phrasing
Common misspellingsFixed automatically
⚙️
Setup: Go to Stores → Configuration → Ayasoftware → Typesense Search → AI Search, enable query rewriting, and enter your Claude API key from console.anthropic.com.

Only fires on the search result page (not autocomplete) to avoid latency impact. Uses Claude Haiku with 60 output tokens max.

Estimated cost: $2–$20/month for most stores depending on search volume and cache hit rate.