Migrate from Algolia to Medusa Search

In this guide, you'll migrate a Medusa project that indexes and searches products in Algolia to use Medusa Search.

Not a Cloud user yet? Sign up for Cloud to use Medusa Search and other Cloud features.

Migrate with an AI Agent#

If you use an AI agent, such as Claude Code or Codex, ask it to fetch this page:

Terminal
Fetch https://docs.medusajs.com/cloud/search/migrate-from-algolia and follow the instructions.

It will receive the following prompt with instructions on performing the full migration:

Migration Prompt
<role>You are a senior Medusa developer migrating an existingMedusa project from a custom Algolia integration to MedusaSearch, the managed search service of Cloud.</role>
<task>Replace this project's custom Algolia search integrationwith the Search Module and Medusa Search, keeping thestorefront's search behavior intact.</task>
<context>- Medusa Search is a provider of the Search Module, which  ships with Medusa v2.21.1 and later. Cloud registers and  configures it for every environment, so it needs no  credentials or configuration in the project.- Medusa declares no index by default, so a project  declares its own `product` index definition under  `src/search`. A project installed after v2.21.1 ships with  one at `src/search/product.ts`, and any other project may  or may not have it.- An index definition lives in a file under `src/search`,  declares the fields the engine holds, fills the index with  a `seed` async generator, and keeps it current with its  `events` and `consume` properties.- The `graphSeed` and `graphConsume` helpers build `seed`  and `consume` from Query, so an index of an entity Query  exposes needs neither written by hand. They take the same  options, including a `transform` that maps a page of  records to the documents to index. Every document must  carry the record's primary key as `id`, and a record you  leave out of the returned array stays out of the index.- Medusa's Store API has a `POST /store/search` route that  searches any index of the application, so a project  doesn't need its own product search route. The body is a  search query naming the index in `entity`, or a batch of  them under `queries`.- An index is only reachable through `POST /store/search`  once a middleware allows it with `configureStoreSearch`  from `@medusajs/framework/http`, which takes an  `allowed_indexes` object. The route narrows a product  index to published products in the publishable API key's  sales channels, and any further constraint is that  middleware's `filters` option.- Queries run through `query.search` in an API route. There  is no browser-side querying and no search-only key.- The `@medusajs/instantsearch-adapter` package is a search  client for InstantSearch widgets, so a storefront built on  `react-instantsearch` keeps its widgets and swaps the  client.- Medusa Search does not support synonyms, merchandising  rules, geo search, or search analytics. An index or a query  that relies on them fails.- Medusa Search supports typo tolerance and highlighting, but  both are opt-in per query through `search_options` and both  require a text query.</context>
<steps>1. Inspect the project and report what it has before you   change anything: the Algolia module, the sync workflows   and their steps, the subscribers, the admin sync route   and UI route, the search API route, the storefront search   client, and the Medusa version in `package.json`.2. If the Medusa version is below v2.21.1, stop and tell the   user to upgrade first.3. List the fields the project indexes in Algolia, taken   from the sync workflow's `fields` array, and ask the user   for the index settings from their Algolia dashboard.4. Check whether the project already declares a `product`   index, which ships at `src/search/product.ts`. If it   does and every indexed field and setting is covered by   it, skip to step 6 and say why. Otherwise, the project   needs an index definition of its own.5. Create the index definition under `src/search`. Map   Algolia's searchable attributes to `searchable()` fields   with a weight, faceting attributes to `facetable()` or   `filterable()`, sorting replicas to `sortable()`, and   unretrievable attributes to `retrievable(false)`. Build   `seed` and `consume` with `graphSeed` and `graphConsume`,   sharing one options object between them, and reproduce   the project's indexing rules in its `transform`, such as   leaving a product that isn't published out of the   documents it returns. List   the entity's create, update, and delete events in   `events`.6. Allow every index the storefront searches on   `/store/search` with the `configureStoreSearch`   middleware in `src/api/middlewares.ts`. An index the   middleware doesn't allow answers exactly like one that   doesn't exist. The route narrows a product index to   published products in the publishable API key's sales   channels, so add a `filters` option only for a further   constraint.7. Delete the project's product search API route and its   validation middleware, since `POST /store/search`   replaces it. Only write a route with `query.search` for a   result the built-in route can't answer with, such as one   reshaped for the storefront. In such a route, respond   with the hydrated records from `data` and the metadata   from `search_result`, and don't also return   `search_result.hits`, since each hit's `document` repeats   a record already returned.8. Replace any manual sync trigger with a workflow step that   calls the Search Module's `reindex` method.9. Delete the Algolia module, the sync workflows and steps,   the product subscribers, the module's entry in   `medusa-config.ts`, and the `algoliasearch` dependency.   Do this here and not earlier, since the application fails   to boot while the module is still registered and the   package is gone. Leave the Algolia environment variables   in place and tell the user to remove them after the   cutover.10. Update the storefront to search through Medusa. If it    uses InstantSearch widgets, install    `@medusajs/instantsearch-adapter`, create its search    client with the storefront's JS SDK instance and the    path `/store/search`, pass the client and the index    name to the existing `InstantSearch` provider, and    change every component that reads a hit's `objectID` to    read `id`. Otherwise, post to `/store/search` with the    JS SDK and read the `hits` and `metadata` it returns. Remove the Algolia packages, the Algolia search    client, and the Algolia environment variables from the    storefront.11. Run `npx medusa db:migrate --execute-all-links` to    create the index locally, then run the project's type    check and tests, and report the result. Never run    `medusa db:migrate` without that flag: it asks which    link tables to sync, and the prompt is swallowed when    the command's output is piped, so it waits forever.</steps>
<constraints>- Do not add a feature that Medusa Search does not support.  When the project relies on one, report it and propose the  closest alternative instead of implementing it silently.- Do not delete the user's Algolia account, indexes, or  credentials, and do not call the Algolia API.- Do not modify `POST /store/search` or recreate it in the  project.- Do not refine a widget or a filter on a field the index  definition doesn't mark `searchable()`, `filterable()`,  `facetable()`, or `sortable()`.- Do not run a deployment or push to any branch.- Never run a Medusa CLI command that can prompt without the  flag that skips its prompts. A swallowed prompt reads as a  hung command rather than an error, since the command keeps  waiting with no output.- Keep every package the current integration imports  installed until step 9, so the application boots at every  point before it.- Consult the Medusa documentation at  https://docs.medusajs.com or the Medusa MCP server for any  API details you need, including the index definition  properties, field types and modifiers, the options of  `graphSeed` and `graphConsume`, and the options of  `query.search`.</constraints>
<error_handling>- If the project has no Algolia integration, report that and  stop.- If the integration differs from the files listed in step  1, map each responsibility you find to its Search Module  equivalent and report the mapping before you change code.- If you cannot tell whether a field is searched, filtered,  faceted, or only displayed, ask the user rather than  guessing its modifiers.- If a storefront feature has no Medusa Search equivalent,  list it under manual follow-ups instead of removing the  feature. The adapter doesn't support `geoSearch`, Insights  and Analytics widgets, Query Rules, related-items widgets,  autocomplete, or Algolia `filters` strings.- If the storefront's search can't be expressed with the  built-in route's parameters, ask the user before adding a  custom search route for products.</error_handling>
<output_format>Respond with the following markdown sections:
## ChangesA table of every file you created, modified, or deleted,with one sentence on what changed in it.
## Behavior differencesEach Algolia behavior the project relied on that MedusaSearch does not support, and what you did about it.
## Manual follow-upsThe steps the user has to take themselves, such as removingenvironment variables, validating relevance, and deploying.</output_format>
<success_criteria>- The project builds and type checks with no reference to  `algoliasearch` left in the backend or the storefront.- Every field the project indexed in Algolia is either held  by the new index definition, covered by the default  product index, or listed as an intentional removal.- Every index the storefront searches is allowed in a  `configureStoreSearch` middleware on `/store/search`.- The storefront searches products through  `POST /store/search` and renders the hits it returns.- Every remaining search route uses `query.search` and  returns each record once.- Every unsupported Algolia behavior appears under  "Behavior differences".</success_criteria>


Who This Guide Is For#

This guide assumes your project follows the Integrate Algolia with Medusa guide, which is the most common Algolia setup in Medusa projects. That setup has the following pieces:

  • An Algolia Module in src/modules/algolia that wraps Algolia's client.
  • A syncProductsWorkflow and its steps that index and delete products in Algolia.
  • Subscribers on product events and a custom algolia.sync event.
  • An admin UI route and API route that trigger a full sync.
  • A /store/search API route that the storefront calls.
  • A storefront search client that sends every query to that route.

If your integration differs, the mapping in the Map Your Integration to Medusa Search section still applies, since every Algolia integration owns the same responsibilities.

Not sure whether to migrate? Refer to Medusa Search vs Algolia for a feature-by-feature comparison, including the Algolia features that Medusa Search doesn't offer.

What Changes in Your Project#

Medusa Search isn't a drop-in replacement for the Algolia client. It's a provider of the Search Module, which owns the parts of the integration you wrote by hand. So the migration deletes more code than it adds.

Responsibility

Your Algolia integration

Medusa Search

Connecting to the engine

The Algolia Module's service, its options, and three environment variables.

Cloud provisions the service and passes the credentials, so nothing to write.

Index schema

Algolia's dashboard settings, outside your repository.

An index definition in src/search.

Initial and full sync

syncProductsWorkflow, the algolia.sync subscriber, the admin API route, and the admin UI route.

The index definition's seed generator, which Medusa runs on deployment, plus the reindex method for a manual rebuild.

Incremental sync

The product-sync and product-delete subscribers, and the delete workflow.

The events and consume properties of the index definition.

Rollback on a failed write

Compensation functions that reindex the previous documents.

Not needed. A failed consume leaves the index behind, and a reindex repairs it.

Querying

The module service's search method, called from your /store/products/search route.

Medusa provides the /store/search route out-of-the-box, and you can search as well with query.search.

Per-environment isolation

An index name per environment, provisioned and configured by you.

One set of indexes per environment, created for you.

Behavior Differences to Settle First#

Some Algolia behaviors have no equivalent in Medusa Search, and an index or a query that relies on them fails rather than degrading. Decide what to do about each one before you write any code:

Behavior

What to do

Synonyms

Medusa Search doesn't support synonyms, and an index that declares them fails at startup. Expand a query's terms in your API route, or index the alternative terms as a searchable field.

Ranking rules and merchandising

Medusa Search ranks by the weight you set on each searchable field. Reproduce pinned or boosted results with your own logic in the API route.

Sorting by an attribute

Medusa Search sorts by any number of sortable fields, but not alongside a text query. A sorted product listing therefore runs as a separate query from a search, without a q filter.

Search analytics and A/B testing

Medusa Search doesn't provide them. Track queries in your own analytics from the API route.


Step 1: Upgrade Your Medusa Application#

Medusa Search requires Medusa v2.21.1 or later. Upgrade your application, then confirm it starts locally before you change any search code.

Refer to the Update Medusa guide for the upgrade steps.

Once you upgrade, the Search Module is registered by default with the PostgreSQL Search Module Provider locally, and with Medusa Search on Cloud. So you don't have to register anything in medusa-config.ts.


Step 2: Declare Your Index#

Medusa declares no index by default, so your application declares its own product index in a file under src/search. If you installed your Medusa application after v2.21.1, it already has that definition at src/search/product.ts. Otherwise, check whether the file is there, and declare the index if it isn't.

If you already have the product index definition, you can customize it, or declare a new one in the following cases:

  • Your Algolia records hold custom fields that your product index doesn't. You can then add those fields to the definition.
  • You need index settings or field options that your definition doesn't apply, such as a different weight, a facetable field, or a Medusa Search setting.
  • You indexed data models other than products in Algolia, such as product categories. You then declare an index for each of them.

Otherwise, skip to Step 3 and query the product index you already have.

An index definition replaces your Algolia index's configuration, holding the schema, the initial fill, and the event handling in one file that deploys with your code. The definition alone decides what the index holds, so customize src/search/product.ts rather than adding a second definition named product.

Tip: The example index below is simplified to show one feature at a time. For examples of indexing prices in multiple currencies, option values, categories, and other product data, refer to the Product Index Examples guide.

For example, the integration guide indexes each product's id, title, description, handle, thumbnail, categories, and tags, and it indexes published products only. To reproduce that, create the file src/search/product.ts with the following content:

src/search/product.ts
1import {2  defineSearchIndex,3  graphConsume,4  graphSeed,5  search,6} from "@medusajs/framework/utils"7
8const source = {9  fields: [10    "id",11    "title",12    "description",13    "handle",14    "thumbnail",15    "status",16    "categories.id",17    "categories.name",18    "categories.handle",19    "tags.id",20    "tags.value",21  ],22  transform: (products) => {23    return products24      .filter((p) => p.status === "published")25      .map(({ status, ...product }) => product)26  },27}28
29export const productIndex = defineSearchIndex({30  name: "product",31  entity: "product",32  fields: search.define({33    id: search.keyword().filterable(),34    title: search.text().searchable({ weight: 3 }),35    description: search.text().searchable(),36    handle: search.keyword().filterable(),37    thumbnail: search.keyword(),38    categories: search39      .object({40        id: search.keyword().filterable(),41        name: search42          .keyword()43          .searchable()44          .facetable(),45        handle: search.keyword().filterable(),46      })47      .array(),48    tags: search49      .object({50        id: search.keyword().filterable(),51        value: search52          .keyword()53          .searchable()54          .facetable(),55      })56      .array(),57  }),58  events: [59    "product.created",60    "product.updated",61    "product.deleted",62  ],63  consume: graphConsume(source),64  seed: graphSeed(source),65})

The definition declares the fields the engine holds, then lets the graphSeed and graphConsume helpers read those fields from Query. Note the following about it:

  • graphSeed fills the index for the first time, reading the catalog in batches and resuming an interrupted run, so you don't paginate the read yourself.
  • graphConsume replaces your product-sync and product-delete subscribers. Medusa routes each event in events to it, and it upserts or deletes the affected product's document.
  • Both helpers share the same source, so an event writes the same document the seed does. Its transform indexes published products only, which is the check the syncProductsWorkflow performs in its transform function, and leaving any other product out of the documents it returns deletes that product's document, the way deleteProductsFromAlgoliaStep did.

If you're creating a custom index for Medusa Search, you'll need to map each Algolia setting to its equivalent in Medusa Search:

Algolia

Medusa Search

searchableAttributes

A search.text() field with the searchable() modifier. The attribute's position in Algolia's ordered list becomes a weight.

attributesForFaceting

The facetable() modifier for an attribute the storefront shows counts for, and filterable() for one you only filter on. An attribute declared as filterOnly in Algolia maps to filterable() alone.

customRanking and ranking

A weight per searchable field. Medusa Search has no equivalent for the rest of Algolia's ranking criteria.

Replica indexes for sorting

The sortable() modifier on the same index. One index serves every sort order, so the replicas go away.

unretrievableAttributes

The retrievable() modifier set to false.

distinct and attributeForDistinct

The distinct_attribute index setting.

objectID

The index's primary_key, which defaults to id. Since the integration guide sets objectID to the product's ID, you can drop the field.

One index per environment

One index definition. Cloud scopes the physical indexes per environment, so the ALGOLIA_PRODUCT_INDEX_NAME variable goes away.

Test the Index Locally#

Locally, the PostgreSQL provider holds the index in your database, so run the migrations that create it:

Then start your application. The Search Module fills the index when the application starts in worker or shared mode.


Step 3: Replace the Search API Route#

Medusa's Store API has a POST /store/search API route that searches any index of your application, including the product index you declared in Step 2.

An index isn't searchable through the route until a middleware allows it, so add the configureStoreSearch middleware in src/api/middlewares.ts:

src/api/middlewares.ts
1import {2  configureStoreSearch,3  defineMiddlewares,4} from "@medusajs/framework/http"5
6export default defineMiddlewares({7  routes: [8    {9      matcher: "/store/search",10      middlewares: [11        configureStoreSearch({12          allowed_indexes: {13            product: true,14          },15        }),16      ],17    },18  ],19})

The route narrows a product index to published products in the publishable API key's sales channels. Learn more in the Store Search API Route guide.

Then, you can delete the route you previously created for searching products, and use the built-in route instead:

Terminal
MEDUSA_URL=https://your-project.medusajs.app
curl -X POST "$MEDUSA_URL/store/search" \  -H "x-publishable-api-key: {your_publishable_api_key}" \  -H "Content-Type: application/json" \  --data '{    "entity": "product",    "filters": { "q": "sweatshirt" },    "pagination": { "take": 20 }  }'

The route returns a JSON response like the following:

Code
1{2  "results": [3    {4      "hits": [5        {6          "id": "prod_01KXR3J9J610DT161E2E4ZS6P1",7          "score": 1.42,8          "document": {9            "id": "prod_01KXR3J9J610DT161E2E4ZS6P1",10            "title": "Medusa Sweatshirt",11            "description": "A classic sweatshirt, reimagined.",12            "handle": "sweatshirt",13            "thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png"14          }15        }16      ],17      "metadata": {18        "skip": 0,19        "take": 20,20        "count": 12,21        "query": "sweatshirt",22        "processing_time_ms": 723      }24    }25  ]26}

The route answers with one result per posted query, each holding the matching hits ranked by relevance and the query's metadata. It's close to the shape Algolia returned, with a hit's fields under document and its identifier in id rather than objectID. Step 4 provides guidance on updating your storefront to read the new response shape.

Search a Custom Index#

If you indexed data models other than products in Algolia, such as brands, create an API route that searches their index with query.search.

For example, to search a brand index, create the file src/api/store/brands/search/route.ts with the following content:

src/api/store/brands/search/route.ts
1import {2  MedusaRequest,3  MedusaResponse,4} from "@medusajs/framework/http"5import {6  ContainerRegistrationKeys,7} from "@medusajs/framework/utils"8import { z } from "@medusajs/framework/zod"9
10export const SearchSchema = z.object({11  query: z.string(),12  limit: z.number().optional().default(20),13  offset: z.number().optional().default(0),14})15
16type SearchRequest = z.infer<typeof SearchSchema>17
18export async function POST(19  req: MedusaRequest<SearchRequest>,20  res: MedusaResponse21) {22  const query = req.scope.resolve(23    ContainerRegistrationKeys.QUERY24  )25
26  const { query: q, limit, offset } = req.validatedBody27
28  const { data, search_result } = await query.search({29    entity: "brand",30    fields: ["id", "name", "country"],31    filters: { q },32    pagination: { skip: offset, take: limit },33  })34
35  res.json({36    brands: data,37    metadata: search_result.metadata,38  })39}

The route resolves Query from the Medusa container and searches the brand index, which is the name of its definition. query.search returns the hydrated entities in data and the engine's own result in search_result.

Add Filters, Facets, and Sorting#

You can apply filters, facets, and sorting directly in the API route using the filters and search_options parameters of query.search.

For example, to filter the brands by country and return the country counts:

src/api/store/brands/search/route.ts
1const { data, search_result } = await query.search({2  entity: "brand",3  fields: ["id", "name", "country"],4  filters: {5    q,6    country: req.validatedBody.country,7  },8  search_options: {9    facets: ["country"],10    disjunctive_facets: true,11  },12  pagination: { skip: offset, take: limit },13})

disjunctive_facets keeps the sibling country counts visible while a country filter is active, which is what a filter sidebar needs. Refer to Search Queries for every filter operator, facet type, and sorting option.

Note: Medusa Search can't sort by a field alongside a text query. If your storefront offers "sort by price" on a search results page, run the sorted listing as a separate query without a q filter.

Step 4: Update the Storefront#

Medusa provides an InstantSearch adapter for connecting your storefront to the Medusa backend and searching products. You can use the same widgets for displaying search results as you did with Algolia.

In your storefront, install the adapter:

You should also install InstantSearch packages specific for your frontend framework if you haven't already, such as react-instantsearch or vue-instantsearch.

Then, replace the Algolia searchClient with the adapter's client. For example, create the file src/lib/search-client.ts with the following content:

src/lib/search-client.ts
1import {2  createInstantSearchAdapter,3} from "@medusajs/instantsearch-adapter"4// JS SDK instance5import { sdk } from "./config"6
7export const PRODUCT_INDEX_NAME = "product"8
9export const { searchClient } = createInstantSearchAdapter({10  sdk,11  path: "/store/search",12})

The adapter sends the requests with the Medusa JS SDK instance your storefront already exports, so the publishable API key and the other headers are set for you.

Next, pass the client to your existing InstantSearch provider and set indexName to the name of your index definition:

src/components/search/index.tsx
1import {2  Configure,3  InstantSearch,4  SearchBox,5} from "react-instantsearch"6import {7  PRODUCT_INDEX_NAME,8  searchClient,9} from "../../lib/search-client"10
11const Search = () => (12  <InstantSearch13    indexName={PRODUCT_INDEX_NAME}14    searchClient={searchClient}15  >16    <Configure hitsPerPage={12} />17    <SearchBox />18    {/* your existing hit list, filters, and pagination widgets */}19  </InstantSearch>20)21
22export default Search

Finally, clean up what's left behind from the Algolia integration:

  1. Remove the Algolia searchClient from src/lib/config.ts, along with the algoliasearch dependency and environment variables like NEXT_PUBLIC_ALGOLIA_*.
  2. Change every component that reads a hit's objectID to read id instead, since the adapter builds a hit from the document your index holds.
  3. Confirm each field your widgets filter, facet, or sort on is marked filterable(), facetable(), or sortable() in the index definition you wrote in Step 2. A widget can't refine on a field the index doesn't hold that way.

Refer to the InstantSearch Adapter guide for the full setup, the adapter's configuration options, and the widgets it supports. For filters, facets, sorting, and pagination, refer to the Filtering, Sorting, and Pagination example.


Step 5: Replace the Manual Sync#

The integration guide's admin page triggers a full sync through the algolia.sync event. You no longer need that sync for everyday changes:

  1. Medusa fills the index on deployment.
  2. Medusa keeps the index current from the events and consume properties of the index definition, applying every product change as it happens. This applies for both the product index Medusa creates by default or the custom definition you wrote in Step 2.

A manual rebuild is only for repairing a diverged index, such as after a consume call failed or a change reached the database without emitting an event.

For a manual rebuild, you can drop the custom admin page entirely: admin users can rebuild any index from Settings -> Search in the Medusa Admin dashboard. Refer to the Manage Search Indexes user guide.

Triggering a Manual Rebuild in Code#

If you'd rather trigger the rebuild from your own code, replace the syncProductsWorkflow with a step that calls the Search Module's reindex method.

For example, create the file src/workflows/steps/reindex-products.ts with the following content:

src/workflows/steps/reindex-products.ts
1import { Modules } from "@medusajs/framework/utils"2import {3  createStep,4  StepResponse,5} from "@medusajs/framework/workflows-sdk"6
7export const reindexProductsStep = createStep(8  "reindex-products",9  async (_, { container }) => {10    const searchModuleService = container.resolve(11      Modules.SEARCH12    )13
14    const result = await searchModuleService.reindex({15      index: "product",16    })17
18    return new StepResponse(result)19  }20)

In this example, you use the reindex method from the Search Module to trigger a manual rebuild of the product index. You can then use this step in a workflow to programmatically rebuild the index whenever needed.

Note: reindex waits for the rebuild to finish before it resolves, so run it in a workflow rather than in the request handler of your admin API route. Refer to Long-Running Workflows if the rebuild outlasts your request timeout.

Step 6: Remove the Algolia Integration#

Once your searches run against the new index, delete the code that Medusa Search replaces. From a project that followed the integration guide, remove the following:

What to remove

Why

src/modules/algolia

The Search Module and its provider replace the client wrapper.

The module's entry in the modules array of medusa-config.ts

Removing the directory without this leaves your application failing to boot.

src/workflows/sync-products.ts, src/workflows/delete-products-from-algolia.ts, and their steps

The index definition's seed and consume functions replace them.

src/subscribers/algolia-sync.ts, src/subscribers/product-sync.ts, and src/subscribers/product-delete.ts

Medusa subscribes to the events in the definition's events array.

The algoliasearch dependency

Nothing in the backend calls Algolia anymore.

The ALGOLIA_APP_ID, ALGOLIA_API_KEY, and ALGOLIA_PRODUCT_INDEX_NAME variables

Remove them from every environment, including the Cloud environment variables. Delete them last, after the cutover.


Step 7: Deploy and Fill the Index to Preview#

With the backend and the storefront changes in place, push your changes to the branch of a Cloud environment. Use a preview or staging rather than production for the first deployment, so you can make sure everything works as expected.

During the deployment, Cloud runs the search migrations, which create the physical index for your definition. The Search Module then fills it with the documents that seed yields when the application starts.

Once your application is deployed, you can check the Medusa Admin dashboard for the status of the search index by going to Settings -> Search. Learn more in the User Guide.

If the index status is successful, it means the seeding has finished. You can test it out either by sending a request to the Store Search API route, or by using the storefront search interface to confirm that products appear as expected.


Step 8: Deploy Your Index#

Once the preview environment's search holds up, merge your changes into your production environment. Cloud builds and deploys your project, creates the production index, and fills it with the documents that seed yields.


Next Steps#

Was this guide helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Medusa MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break