Medusa.js Admin Dashboard Setup
Medusa Admin — React Vite app, separate package @medusajs/dashboard. In Medusa 2.x, Admin completely separated from backend, connected as plugin or deployed standalone. Extension via Extensions — custom pages, widgets, routes.
Connection Options
# Option 1: Built-in backend (recommended start)
npm install @medusajs/dashboard
# auto-added to medusa-config.ts via create-medusa-app
# Option 2: Standalone deploy
npx create-medusa-app@latest --no-boilerplate
cd my-admin && npm install
VITE_MEDUSA_BACKEND_URL=https://api.example.com npm run build
# deploy dist/ to Vercel/Nginx
Custom Widget for Product Pages
import { defineWidgetConfig } from '@medusajs/admin-sdk';
import { Container, Heading, Text } from '@medusajs/ui';
import { useQuery } from '@tanstack/react-query';
const ProductLoyaltyWidget = ({ data }: { data: { id: string } }) => {
const { data: stats } = useQuery({
queryKey: ['loyalty-stats', data.id],
queryFn: () => sdk.client.fetch(`/admin/products/${data.id}/loyalty-stats`),
});
return (
<Container>
<Heading level="h2">Loyalty</Heading>
<Text>Points given: {stats?.total_points_given ?? '—'}</Text>
</Container>
);
};
export const config = defineWidgetConfig({
zone: 'product.details.after',
});
export default ProductLoyaltyWidget;
Custom Pages
import { defineRouteConfig } from '@medusajs/admin-sdk';
import { GiftSolid } from '@medusajs/icons';
const LoyaltyPage = () => {
return (
<Container>
{/* loyalty page content */}
</Container>
);
};
export const config = defineRouteConfig({
label: 'Loyalty Program',
icon: GiftSolid,
});
export default LoyaltyPage;
Run and Configure
VITE_MEDUSA_BACKEND_URL=http://localhost:9000 npm run dev
# Build for production
VITE_MEDUSA_BACKEND_URL=https://api.example.com npm run build
# Extensions auto-applied from src/admin/
Timeline: basic setup + backend connection — 2–4 hours; custom widgets and pages for business tasks — 2–5 days.







