> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mercurjs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Replace panel components

> Swap the sidebar, topbar actions, or store setup screen for your own components through dashboard SDK configuration.

Some customizations aren't about one page — they change the panel's global chrome. For those, the dashboard SDK exposes a small set of **named component overrides**: you point the plugin config at your own file, and the panel renders your component in place of the built-in one everywhere it appears.

<Info>
  **Choose the right tool.** A component override replaces one of four global layout slots across the whole panel. If you want to change a single page, [re-compose it](/rc/resources/tutorials/recompose-a-page) instead — and if you want to add a new screen, just [drop in a route](/rc/resources/tutorials/custom-panel-page). The decision guide in [Extending Panels](/rc/resources/customization/extending-panels#choosing-your-extension-mechanism) compares all three.
</Info>

## What you'll build

A vendor portal with custom topbar actions (a help link and a status badge) and a custom main sidebar, configured entirely from `vite.config.ts`.

## The available slots

Exactly four layout components can be replaced:

| Component         | Where it renders                                            |
| ----------------- | ----------------------------------------------------------- |
| `MainSidebar`     | Primary navigation sidebar on every main page               |
| `SettingsSidebar` | Sidebar of the `/settings` section                          |
| `TopbarActions`   | Action cluster on the right side of the top bar             |
| `StoreSetup`      | The store setup screen shown to new sellers (vendor portal) |

Anything else — a page, a section, a table — is customized through routes and compound components, not through overrides.

## Set up the override

<Steps>
  <Step title="Write the replacement component">
    Create the component anywhere under `src/`. It must have a **default export**:

    ```tsx apps/vendor/src/components/topbar-actions.tsx theme={null}
    import { Badge, Button } from "@medusajs/ui"

    export default function TopbarActions() {
      return (
        <div className="flex items-center gap-x-2">
          <Badge size="2xsmall" color="green">
            All systems operational
          </Badge>
          <Button size="small" variant="transparent" asChild>
            <a href="https://help.example.com" target="_blank" rel="noreferrer">
              Help
            </a>
          </Button>
        </div>
      )
    }
    ```
  </Step>

  <Step title="Register it in the Vite config">
    Component overrides live in the `components` option of `mercurDashboardPlugin`, in your panel app's `vite.config.ts`. Paths are **relative to `src/`**:

    ```typescript apps/vendor/vite.config.ts theme={null}
    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import { mercurDashboardPlugin } from '@mercurjs/dashboard-sdk'

    export default defineConfig({
      plugins: [
        react(),
        mercurDashboardPlugin({
          medusaConfigPath: '../../packages/api/medusa-config.ts',
          components: {
            TopbarActions: 'components/topbar-actions',
            MainSidebar: 'components/main-sidebar',
          },
        }),
      ],
    })
    ```

    The plugin resolves each path at build time and swaps your component in through the `virtual:mercur/components` module — no runtime registration, no context providers to wire.
  </Step>

  <Step title="Restart the dev server">
    Vite config changes require a restart. After it, your components render everywhere their slots appear.
  </Step>
</Steps>

<Tip>
  Build overrides with `@medusajs/ui` components and Medusa UI color tokens so they match the rest of the panel. The panels ship no other UI library.
</Tip>

## Verify

1. Open the vendor portal — the top bar shows your badge and Help link on every page.
2. Navigate between main pages and `/settings` — the override applies everywhere its slot renders.
3. Remove the `components` entry and restart — the built-in components return. The originals were never modified.

## FAQ

<AccordionGroup>
  <Accordion title="If I replace MainSidebar, do my custom routes still show up in the menu?">
    Only if your sidebar renders them. A `MainSidebar` override replaces the **entire** navigation sidebar, including the auto-generated menu items from route `config` exports — read them from `virtual:mercur/menu-items` if you want to keep automatic navigation. If you only want to add or reorder items, you don't need an override at all: the `config` export on route files (with `rank` and `nested`) covers that.
  </Accordion>

  <Accordion title="Can I override other components, like the login page or a form?">
    No — these four slots are the complete list. The login flow, forms, and everything page-level are customized through drop-in routes and [compound re-composition](/rc/resources/tutorials/recompose-a-page).
  </Accordion>

  <Accordion title="Do overrides apply to both panels?">
    Each panel app has its own `vite.config.ts`, so overrides are configured per panel. `StoreSetup` only exists in the vendor portal; the other three slots exist in both.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Re-compose a built-in page" href="/rc/resources/tutorials/recompose-a-page">
    Change one page's composition instead of global chrome.
  </Card>

  <Card title="Extending Panels" href="/rc/resources/customization/extending-panels">
    The full reference for routes, navigation, branding, and overrides.
  </Card>
</CardGroup>
