# Admin Widgets

In this chapter, you’ll learn about widgets and how to use them.

## What is an Admin Widget?

The Medusa Admin's pages are customizable for inserting widgets of custom content in pre-defined injection zones. For example, you can add a widget on the product details page that allows admin users to sync products to a third-party service.

You create these widgets as React components that render the content and functionality of the widget.

You can create an admin widget directly in your Medusa application, or in a [plugin](https://docs.medusajs.com/learn/fundamentals/plugins) if you want to share the widget across multiple Medusa applications.

***

## How to Create a Widget?

### Prerequisites

- [Medusa application installed](https://docs.medusajs.com/learn/installation)

You create a widget in a `.tsx` file under the `src/admin/widgets` directory. The file must export:

1. A React component that renders the widget. This will be the file's default export.
2. The widget’s configurations indicating where to insert the widget.

For example, create the file `src/admin/widgets/product-widget.tsx` with the following content:

![Example of widget file in the application's directory structure](https://res.cloudinary.com/dza7lstvk/image/upload/v1732867137/Medusa%20Book/widget-dir-overview_dqsbct.jpg)

```tsx title="src/admin/widgets/product-widget.tsx" highlights={widgetHighlights}
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { Container, Heading } from "@medusajs/ui"

// The widget
const ProductWidget = () => {
  return (
    <Container className="divide-y p-0">
      <div className="flex items-center justify-between px-6 py-4">
        <Heading level="h2">Product Widget</Heading>
      </div>
    </Container>
  )
}

// The widget's configurations
export const config = defineWidgetConfig({
  zone: "product.details.before",
})

export default ProductWidget
```

In the example above, the widget is injected at the top of a product’s details.

You export the `ProductWidget` component, which displays the heading `Product Widget`. In the widget, you use [Medusa UI](https://docs.medusajs.com/ui) to customize the dashboard with the same components used to build it.

To export the widget's configuration, you use `defineWidgetConfig` from the Admin Extension SDK. It accepts an object as a parameter with the `zone` property, whose value is a string or an array of strings, each being the name of the zone to inject the widget into.

The widget component must be created as an arrow function.

### Test the Widget

To test out the widget, start the Medusa application:

```bash npm2yarn
npm run dev
```

Then, open a product’s details page. You’ll find your custom widget at the top of the page.

***

## Props Passed to Widgets on Detail Pages

Widgets that are injected into a detail page receive a `data` prop, which is the main data of the details page.

For example, a widget injected into the `product.details.before` zone receives the product's details in the `data` prop:

```tsx title="src/admin/widgets/product-widget.tsx" highlights={detailHighlights}
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { Container, Heading } from "@medusajs/ui"
import { 
  DetailWidgetProps, 
  AdminProduct,
} from "@medusajs/framework/types"

// The widget
const ProductWidget = ({ 
  data,
}: DetailWidgetProps<AdminProduct>) => {
  return (
    <Container className="divide-y p-0">
      <div className="flex items-center justify-between px-6 py-4">
        <Heading level="h2">
          Product Widget {data.title}
        </Heading>
      </div>
    </Container>
  )
}

// The widget's configurations
export const config = defineWidgetConfig({
  zone: "product.details.before",
})

export default ProductWidget
```

The props type is `DetailWidgetProps`, and it accepts as a type argument the expected type of `data`. For the product details page, it's `AdminProduct`.

***

## Injection Zones List

Refer to the [Admin Widget Injection Zones](https://docs.medusajs.com/resources/admin-widget-injection-zones) reference for the full list of injection zones and their props.

***

## Admin Components List

While the Medusa Admin uses the [Medusa UI](https://docs.medusajs.com/ui) components, it also expands on them for styling and design purposes.

To build admin customizations that match the Medusa Admin's designs and layouts, refer to the [Admin Components](https://docs.medusajs.com/resources/admin-components) guide. You'll find components like `Header`, `JSON View`, and more that match the Medusa Admin's design.

***

## Show Widgets Conditionally

In some cases, you may want to show a widget only if certain conditions are met. For example, you may want to show a widget only if the product has a brand.

To prevent the widget from showing, return an empty fragment from the widget component:

```tsx title="src/admin/widgets/product-widget.tsx"
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { Container, Heading } from "@medusajs/ui"
import { 
  DetailWidgetProps, 
  AdminProduct,
} from "@medusajs/framework/types"

// The widget
const ProductWidget = ({ 
  data,
}: DetailWidgetProps<AdminProduct>) => {
  if (!data.metadata?.brand) {
    return <></> // Don't show the widget if the product has no brand
  }

  return (
    <Container className="divide-y p-0">
      <div className="flex items-center justify-between px-6 py-4">
        <Heading level="h2">
          Brand: {data.metadata.brand}
        </Heading>
      </div>
    </Container>
  )
}

// The widget's configurations
export const config = defineWidgetConfig({
  zone: "product.details.before",
})

export default ProductWidget
```

In the above example, you return an empty fragment if the product has no brand. Otherwise, you show the brand name in the widget.


---

The best way to deploy Medusa is through Medusa Cloud where you get autoscaling production infrastructure fine tuned for Medusa. Create an account by signing up at cloud.medusajs.com/signup.
