Medusa Admin Dashboard Search

In this guide, you'll learn how the Medusa Admin dashboard's global search works, and how to make the records of a custom entity searchable in it.

How Admin Search Works#

The Medusa Admin dashboard has a global search that admin users open with + K. It searches records, such as orders or products, and it also lists the dashboard's keyboard shortcuts and navigation entries.

The route searches one entity at a time and returns a group of results per entity:

  • For an entity that has a search index definition, the route searches the index through the Search Module. The index's search provider ranks the results, so the entity benefits from typo tolerance, weights, and the rest of the engine's features.
  • For an entity that has no index, the route queries the entity with Query using the same free-text q filter that the entity's list API route accepts.

The route never merges the groups, since relevance scores are only comparable within one index. Each group has its own count, offset, and limit.


Make a Custom Entity Searchable in Medusa Admin#

To show the records of a custom entity within the Medusa Admin search, such as a brand data model of a custom module, in the dashboard's search, you:

  1. Declare a search index for the entity, which is what the route searches.
  2. Register the entity in the dashboard, which renders its search results in the search panel.

1. Declare a Search Index#

Create a search index definition for the entity in a file under the src/search directory.

For example, to make brands searchable, create the file src/search/brand.ts with the following content:

src/search/brand.ts
1import {2  defineSearchIndex,3  graphConsume,4  graphSeed,5  search,6} from "@medusajs/framework/utils"7
8const fields = ["id", "name", "website"]9
10export default defineSearchIndex({11  name: "brand",12  entity: "brand",13  fields: search.define({14    id: search.keyword().filterable(),15    name: search.text().searchable({ weight: 3 }),16    website: search.keyword().searchable(),17  }),18  events: [19    "brand.created",20    "brand.updated",21    "brand.deleted",22  ],23  consume: graphConsume({ fields }),24  seed: graphSeed({ fields }),25})

Make sure every field that you show in a search result, such as the title and the subtitle, is searchable or stored in the index.

Learn more about index definitions and their fields in the Search Index Definitions guide.

Then, run the migrations to create the physical index:

2. Register the Entity in the Dashboard#

To register a custom entity in the Medusa Admin search, create the file src/admin/search-entities.tsx in your Medusa application or plugin. Medusa loads this file into the dashboard, so any entity you register in it becomes part of the search.

In the file, use defineSearchEntity from the dashboard SDK to register the entity:

src/admin/search-entities.tsx
1import { defineSearchEntity } from "@medusajs/dashboard/lib"2
3defineSearchEntity("brand", {4  groupLabel: "Brands",5  shortcut: {6    keys: { Mac: ["G", "B"] },7    label: "Go to Brands",8    to: "/brands",9  },10  transform: (brand: any) => ({11    id: brand.id,12    title: brand.name,13    subtitle: brand.website,14    to: `/brands/${brand.id}`,15    value: `brand:${brand.id}`,16  }),17})

defineSearchEntity accepts the entity's name as a first parameter, which must match the search index's name, and the entity's definition as a second parameter.

The definition accepts the following properties:

Loading...

Finally, start the Medusa application:

Open the dashboard, press + K, and type a brand's name. The results show under a "Brands" heading, and selecting one opens the brand's page.

Override or Remove Built-In Entities#

The dashboard registers the built-in commerce entities before it loads your file, so you can change or remove them in the same file.

To change how a built-in entity's results show, register it again with the same name. For example, to show a product's handle as its subtitle:

src/admin/search-entities.tsx
1import { defineSearchEntity } from "@medusajs/dashboard/lib"2
3defineSearchEntity("product", {4  groupLabel: "Products",5  transform: (product: any) => ({6    id: product.id,7    title: product.title,8    subtitle: product.handle,9    thumbnail: product.thumbnail,10    to: `/products/${product.id}`,11    value: `product:${product.id}`,12  }),13})
Was this page 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