This plugin powers your product search via a pluggable search backend. It
ships with ready-made adapters for
Elasticsearch and
OpenSearch, and lets
you provide your own adapter by implementing
SearchClientAdapter. This is a drop-in replacement for the
DefaultSearchPlugin which exposes many powerful configuration options
enabling your storefront to support a wide range of use-cases such as
indexing of custom properties, fine control over search index
configuration, and advanced features like spatial search.
Vendure v3.6+ requires Elasticsearch v9.1 or newer. When using OpenSearch, the 3.x client / 3.x server line is supported.
The version of the search engine that is deployed, the version of the
JavaScript client installed in your Vendure project and the version of that
same client used internally by @vendure-community/elasticsearch-plugin must
all match to avoid any issues. Neither client allows @latest in its public
repository, so these versions must be updated regularly.
| Package | Minimum version |
|---|---|
@vendure/core | 3.6.0 |
@vendure-community/elasticsearch-plugin | 2.0.0 |
| Elasticsearch (server + client) | 9.1.0 |
| OpenSearch (server + client) | 3.0.0 |
With Elasticsearch v8+, basic authentication, SSL, and TLS are enabled by
default and may result in your client and plugin not being able to connect to
Elasticsearch successfully if your client is not configured appropriately. You
must also set xpack.license.self_generated.type=basic if you are using the
free Community Edition of Elasticsearch.
Review the Elasticsearch docker example here for development and testing without authentication and security enabled. Refer to the Elasticsearch documentation to enable authentication and security in production.
Install the plugin plus exactly one of the two search clients:
Both clients are declared as optional peer dependencies — only install the
one you use. Make sure to remove the DefaultSearchPlugin from your
VendureConfig plugins array.
Build the adapter for the backend you want to use and pass it to
ElasticsearchPlugin.init().
SearchClientAdapter is a public TypeScript interface. You can implement your
own adapter (e.g. to use a managed/hosted service with a custom SDK, or to
inject a test double) and pass it directly:
If you need direct access to the underlying client (for example to issue a
query that is not on the SearchClientAdapter surface), each built-in adapter
exposes its native client via adapter.getRawClient().
By default the plugin re-indexes a product on every relevant event and writes by deleting the product's documents and recreating them. Two opt-in options reduce that work. Both default to the historic behaviour, so existing installs are unaffected until you enable them.
When enabled, an update reads the product's currently indexed documents, compares
them against the freshly built ones, and writes only the difference: it replaces
the documents that changed, creates new ones, deletes the ones that no longer
exist, and writes nothing when nothing changed. Because it never deletes a
still-current document first, the product does not briefly drop out of search
during an update. It compares the whole document, so it is correct for any mapping
configuration. A full reindex still writes every document, and a product too
large to diff safely falls back to the delete-then-recreate path.
Controls whether a stock change enqueues a re-index job. This covers both an
order-driven StockMovementEvent and an admin variant update that touched only
stock-level fields. With 'onStockStatusChange' the plugin checks, before
creating a job, whether the change would flip a variant's inStock or its
product's productInStock, and skips the job when it would not, avoiding the
queue write, the poll wait and the worker cycle for a change that cannot affect
search results (for example a 50 to 49 change that leaves the item in stock).
The check is scoped to the variants whose stock moved: one query loads them, one
search reads their indexed inStock values, and the saleable stock level is
recomputed once per moved variant per channel. A product's productInStock can
only flip when one of its variants' inStock flips, so if no moved variant flips
the job is skipped. Sibling variants are not recomputed, so the check does not
notice a productInStock that is already stale in the index for an unrelated
reason; a reindex or the next non-stock update repairs that. When the check cannot
decide (for example the variant is not indexed yet) it enqueues.
The check inspects only the built-in stock booleans, so it applies only when
neither customProductMappings nor customProductVariantMappings is configured.
When either is set, a custom field could derive from stock and change without an
inStock flip, so the plugin automatically falls back to 'always'. If you map a
stock-derived field, keep 'always' and use incrementalIndexUpdates, which
compares the whole document and stays correct for any mapping.
Versions prior to 2.0.0 shipped as @vendure/elasticsearch-plugin and
accepted host / port directly in ElasticsearchPlugin.init(...). The
v2 release introduces the adapter pattern so the same plugin can power both
Elasticsearch and OpenSearch.
Before (v1.x):
After (v2.x):
Note the arrow: adapter accepts a factory that produces a
SearchClientAdapter, not an adapter instance directly. The plugin calls
the factory once per internal provider so each owns its own client.
The clientOptions property that previously lived at the top level of
ElasticsearchOptions now lives on the adapter factory options and is passed
through to the underlying client constructor verbatim.
This plugin extends the default search query of the Shop API, allowing richer querying of your product data.
The SearchResponse type is extended with information about price ranges in the result set:
This SearchResponsePriceData type allows you to query data about the range of prices in the result set.
(options: ElasticsearchOptions) => Type<ElasticsearchPlugin>Architecture reviews, custom plugin work, migrations, ongoing support. Get a hand from the team that builds Vendure.
Talk to the team