AAA Interactive Category Tree & Mind Map for Medusa v2 Admin with drag-and-drop reparenting, tier indicators, superscript ranks, multi-storefront filtering, and NotebookLM-style subtree collapse.
An enterprise-grade, AAA interactive Category Tree, Mind Map & Category Detail Hub plugin for Medusa v2 Admin.
Inspired by modern visual and canvas tools like Figma, Miro, Linear, and NotebookLM, this plugin transforms Medusa's standard nested category list into a fluid, 60fps pan/zoom node canvas with branch-specific harmonic color coding, left-edge tier level indicators, sibling superscript rankings, and an all-in-one Category Detail Hub with product ranking and commercial top seller management.
In high-volume e-commerce stores with hundreds or thousands of categories across multiple sales channels and brands:
With this plugin:
Clicking the edit pencil icon on any node opens a wide slide-over hub featuring 4 dedicated workspaces:
Install the package in your Medusa backend project:
Register the plugin in your backend's (or ):
When you start your Medusa backend ( or ), the plugin automatically injects:
The plugin persists category-scoped ranking and top seller configuration into :
In your storefront API or data layer (e.g. Next.js App Router):
The plugin's Category Detail Hub features a unified media uploader and gallery manager. To ensure zero vendor lock-in, file handling is 100% storage-provider agnostic:
In core Medusa v2, products have native media tables (), but does not have a native images relationship out of the box.
To solve this universally without imposing mandatory database migrations on standard Medusa stores, this plugin employs an adaptive hybrid architecture:
Universal Metadata Mode (Zero Config / Out of the Box):
Custom Backend Module Mode (Optional Extended Architecture):
Because Medusa abstracts storage through , you can seamlessly route category media to AWS S3, Cloudflare R2, MinIO, or DigitalOcean Spaces by adjusting :
To build the plugin for distribution:
This compiles TypeScript definitions and JavaScript bundles into .
Contributions, issues, and feature requests are welcome! Feel free to open an issue or pull request on our repository.
Apache License 2.0 © HectaSquare Team
1npm install @hectasquare/medusa-plugin-category-tree2# or3pnpm add @hectasquare/medusa-plugin-category-tree4# or5yarn add @hectasquare/medusa-plugin-category-tree1module.exports = defineConfig({2 plugins: [3 {4 resolve: "@hectasquare/medusa-plugin-category-tree",5 options: {},6 },7 ],8})1// Inspect category metadata for top commercial sellers2const topSellerIds = category.metadata?.top_sellers || []3
4if (topSellerIds.length > 0) {5 // Fetch top seller products and place them first in designated order6 const { products: topProducts } = await getProductsList({7 queryParams: { id: topSellerIds },8 })9 topProducts.sort((a, b) => topSellerIds.indexOf(a.id) - topSellerIds.indexOf(b.id))10 11 // Fill remaining slots from the general category pool without duplicates12 return [...topProducts, ...otherCategoryProducts]13}1{2 "metadata": {3 "image_url": "https://cdn.store.com/category-thumb.webp",4 "images": [5 { "id": "img_01", "url": "https://cdn.store.com/hero.webp", "type": "thumbnail" },6 { "id": "img_02", "url": "https://cdn.store.com/banner.webp", "type": "image" }7 ]8 }9}1// medusa-config.js2module.exports = defineConfig({3 modules: [4 {5 resolve: "@medusajs/medusa/file",6 options: {7 providers: [8 {9 resolve: "@medusajs/medusa/file-s3",10 id: "s3",11 options: {12 file_url: process.env.MEDUSA_FILE_URL, // CDN or bucket public URL13 access_key_id: process.env.S3_ACCESS_KEY_ID,14 secret_access_key: process.env.S3_SECRET_ACCESS_KEY,15 region: process.env.S3_REGION,16 bucket: process.env.S3_BUCKET,17 },18 },19 ],20 },21 },22 ],23})1// medusa-config.js2options: {3 file_url: process.env.R2_PUBLIC_URL, // e.g. https://pub-xxxx.r2.dev or custom domain4 access_key_id: process.env.R2_ACCESS_KEY_ID,5 secret_access_key: process.env.R2_SECRET_ACCESS_KEY,6 bucket: process.env.R2_BUCKET_NAME,7 endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,8 region: "auto",9}1// medusa-config.js2options: {3 file_url: process.env.MINIO_PUBLIC_URL, // e.g. http://localhost:9000/my-bucket4 access_key_id: process.env.MINIO_ROOT_USER,5 secret_access_key: process.env.MINIO_ROOT_PASSWORD,6 bucket: process.env.MINIO_BUCKET,7 endpoint: process.env.MINIO_ENDPOINT, // e.g. http://127.0.0.1:90008 additional_client_config: {9 forcePathStyle: true, // Required for MinIO10 },11}1// medusa-config.js2options: {3 file_url: `https://${process.env.DO_SPACES_BUCKET}.${process.env.DO_SPACES_REGION}.digitaloceanspaces.com`,4 access_key_id: process.env.DO_SPACES_KEY,5 secret_access_key: process.env.DO_SPACES_SECRET,6 bucket: process.env.DO_SPACES_BUCKET,7 endpoint: `https://${process.env.DO_SPACES_REGION}.digitaloceanspaces.com`,8 region: process.env.DO_SPACES_REGION,9}1medusa-plugin-category-tree/2├── src/3│ ├── admin/4│ │ ├── index.tsx # Medusa Admin SDK registration5│ │ ├── routes/category-tree/ # Route /app/category-tree6│ │ └── components/category-tree/7│ │ ├── category-tree-canvas.tsx # Interactive canvas & marquee selection8│ │ ├── category-node.tsx # Node card with tier bars & ranks9│ │ ├── custom-edge.tsx # Orthogonal edge matching branch color10│ │ ├── canvas-dock.tsx # Floating glassmorphic dock11│ │ ├── tier-bars.tsx # Branch-colored tier bars12│ │ ├── edit-category-drawer.tsx # 4-tab Category Detail Hub13│ │ ├── category-products-manager.tsx # Products table, ranking & FocusModal14│ │ ├── create-category-drawer.tsx # Slide-over subcategory creator15│ │ └── lib/16│ │ ├── layout-engine.ts # Buchheim/Walker centered tree engine17│ │ └── tree-state.ts # Palette, tiers, ranks, & cycle checks18│ ├── api/admin/category-tree/ # Server route handlers19│ └── workflows/ # Atomic reorder workflows20├── package.json21├── tsconfig.json22└── README.md1# In the plugin directory2pnpm build3# or4npm run build