megachangelog
Feature2.21.1

v2.21.1: Search Module

Introduces a new Search Module that lets you manage and search through indexes for any data model, with built-in PostgreSQL and Medusa Cloud providers. Also includes improvements to the loyalty plugin's store credit features, new admin translations for Finnish and Swedish, and numerous bug fixes across authentication, payments, inventory, and shipping.

Highlights

Search Module

The Search Module allows you to manage and search through indexes defined in your Medusa application. You can search products or any data model defined just by defining an index for it.

The Search Module supports providers that integrate a search engine to perform the search operations. Out of the box, Medusa provides a PostgreSQL Search Module Provider and Medusa Search for Medusa Cloud users.

Read the announcement to learn about the new search features.

Example of a product index:

import {
  defineSearchIndex,
  graphConsume,
  graphSeed,
  search,
} from "@medusajs/framework/utils"

const source = {
  fields: [
    "id",
    "title",
    "description",
    "handle",
    "thumbnail",
    "status",
    "categories.id",
    "categories.name",
    "categories.handle",
    "tags.id",
    "tags.value",
  ],
}

export const productIndex = defineSearchIndex({
  name: "product",
  entity: "product",
  fields: search.define({
    id: search.keyword().filterable(),
    title: search.text().searchable({ weight: 3 }),
    description: search.text().searchable(),
    handle: search.keyword().filterable(),
    thumbnail: search.keyword(),
    categories: search
      .object({
        id: search.keyword().filterable(),
        name: search
          .keyword()
          .searchable()
          .facetable(),
        handle: search.keyword().filterable(),
      })
      .array(),
    tags: search
      .object({
        id: search.keyword().filterable(),
        value: search
          .keyword()
          .searchable()
          .facetable(),
      })
      .array(),
  }),
  events: [
    "product.created",
    "product.updated",
    "product.deleted",
  ],
  consume: graphConsume(source),
  seed: graphSeed(source),
})

You can the enable storefront searching for it, and search it with the new /store/search API route.

Learn more about the Search Module and how to set it up in the documentation.

Using Algolia or MeiliSearch?

Learn how to migrate to the Search Module in the following guides:

  1. Algolia
  2. MeiliSearch

Loyalty Plugin: Store Credit Improvements

We've made improvements to the loyalty plugin:

  1. You can debit a store credit account from the admin dashboard. Learn more in the documentation.
  2. You can create a store-credit account directly from the customer's details page in the admin.

New Admin Translations

  • Finnish (fi) translations have been added to the admin dashboard (#16746) — thanks @SanteriMoilanen.
  • Swedish (sv) translations have been added to the admin dashboard (#16808) — thanks @StudioKW.

Bug Fixes

  • Auth emailpass: an actor-less identity that was previously registered must now use the same password when re-registering (#16890).
  • Auth config: default http.authMethodsPerActor values are now applied correctly and the /auth/:auth_provider/user route is gated by config (#16816).
  • Disabled the store-credit payment option when there is no outstanding amount or the customer is a guest (#16852).
  • Included shipping_address in the order list query so the country column renders correctly (#16677) — thanks @MarcelRoblek.
  • Completed the Turkish translation (306 previously missing keys) (#16820) — thanks @Markheris.
  • Updated Croatian translations (#16743) — thanks @luxapan.
  • Mutations performed inside step compensation functions are now correctly awaited (#16573) — thanks @ebrahim2355.
  • An inventory item is now created when manage_inventory is enabled on a product variant (#16269) — thanks @KallinikosMil.
  • Vector fields are now filtered out on the Postgres search provider (#16891).
  • The environment handle is now correctly retrieved from the endpoint basic-auth config (#16834).
  • Graph helpers now accept a load property (#16905).
  • Context can now be passed through to graph helpers for search (#16903).
  • Stripe: webhook signature verification errors are now handled gracefully instead of crashing the handler (#16228) — thanks @calebcgates.
  • requested_at is now set when a return is created from the storefront (#16436) — thanks @thomassarazin.
  • Wildcard cache clears now correctly reset the internal size counter (#16607) — thanks @ebrahim2355.
  • deepEqualObj now compares Date values by their time value rather than by reference (#16749) — thanks @yfwmaniish.
  • The --skip-migrations flag now actually skips migrations (#16467) — thanks @tushardev-365.
  • react and react-dom are now deduped in the admin Vite config to prevent duplicate-React issues in custom extensions (#16620) — thanks @bohetangQAQ.
  • failOnError: false is now passed to the lint step during build so a lint warning no longer fails the build (#16648) — thanks @itzzdev09.
  • The link-create-keys-modules-enum rule now only triggers on actual link methods and steps, reducing false positives (#16851).
  • The full error object is now logged instead of undefined when a test runner hook fails (#16842).

Community Contributors

Thank you to everyone who contributed to this release:

searchmoduleapiloyaltytranslation

Source: original entry ↗

More from Medusa

Follow Medusa to get its new changes in your feed and email digest.

Improvement2.21.2

Performance Improvement for Search Route

The /store/search route now restricts field retrieval to only those defined on the index being searched, preventing data hydration outside the index for better performance. This release includes multiple bug fixes for search indexing, caching, promotions, payments, and dashboard internationalization.

searchperformanceapisearch-indexbug-fixes
Breaking2.21.0

Strict allowed fields in Store API and Exported Admin Components

Store API routes now enforce a strict allowed-fields list, returning only explicitly declared fields and relations to prevent unintended data exposure. Disallowed fields are silently stripped; use the allowFields middleware to re-expose specific fields if needed.

store-apisecuritybreaking-changefieldsrelations
Security2.20.1

Field Filter Stripping Fix, Search Stability, Schema Index Validation

Fixed a security issue where field filter restrictions (allowed query config and http.restrictedFields) were only applied when RBAC was enabled; now they are always enforced. Also fixed search correlated flag and schema index JSON validation.

securityfield-filteringrbacsearchschema
See all Medusa changes →