Header - Admin Components

In this guide, you'll learn how to create a header component that matches the Medusa Admin's design conventions.

Each section in the Medusa Admin has a header with a title, and optionally a subtitle with buttons to perform an action.

Example of a header in a section

To create a component that uses the same header styling and structure, create the file src/admin/components/header.tsx with the following content:

src/admin/components/header.tsx
1import { Heading, Button, Text } from "@medusajs/ui"2import React from "react"3import { Link, LinkProps } from "react-router-dom"4import { ActionMenu, ActionMenuProps } from "./action-menu"5
6export type HeadingProps = {7  title: string8  subtitle?: string9  actions?: (10    {11      type: "button",12      props: React.ComponentProps<typeof Button>13      link?: LinkProps14    } |  15    {16      type: "action-menu"17      props: ActionMenuProps18    } |19    {20      type: "custom"21      children: React.ReactNode22    }23  )[]24}25
26export const Header = ({27  title,28  subtitle,29  actions = [],30}: HeadingProps) => {31  return (32    <div className="flex items-center justify-between px-6 py-4">33      <div>34        <Heading level="h2">{title}</Heading>35        {subtitle && (36          <Text className="text-ui-fg-subtle" size="small">37            {subtitle}38          </Text>39        )}40      </div>41      {actions.length > 0 && (42        <div className="flex items-center justify-center gap-x-2">43          {actions.map((action, index) => (44            <>45              {action.type === "button" && (46                <Button 47                  {...action.props} 48                  size={action.props.size || "small"}49                  key={index}50                >51                  <>52                    {action.props.children}53                    {action.link && <Link {...action.link} />}54                  </>55                </Button>56              )}57              {action.type === "action-menu" && (58                <ActionMenu {...action.props} />59              )}60              {action.type === "custom" && action.children}61            </>62          ))}63        </div>64      )}65    </div>66  )67}

The Header component shows a title, and optionally a subtitle and action buttons.

Note: The component also uses the Action Menu custom component.

It accepts the following props:

titlestring
The section's title.
subtitlestringOptional
The section's subtitle.
actionsobject[]Optional
An array of actions to show.

Example#

Use the Header component in any widget or UI route.

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

src/admin/widgets/product-widget.tsx
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Container } from "../components/container"3import { Header } from "../components/header"4
5const ProductWidget = () => {6  return (7    <Container>8      <Header 9        title="Product Widget"10        subtitle="This is my custom product widget"11        actions={[12          {13            type: "button",14            props: {15              children: "Click me",16              variant: "secondary",17              onClick: () => {18                alert("You clicked the button.")19              },20            },21          },22        ]}23      />24    </Container>25  )26}27
28export const config = defineWidgetConfig({29  zone: "product.details.before",30})31
32export default ProductWidget

This widget also uses a Container custom component.

Was this page helpful?
Ask Anything
Ask any questions about Medusa. Get help with your development.
You can also use the 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