Overview
Icon for Brand Management

Brand Management

Brand management with product assignment and admin UI

@mgtalabs/medusa-brand

A commercial-grade Brand Management plugin for Medusa v2 — full CRUD with soft delete/restore, a one-brand-to-many-products relationship built on Medusa's official Module Link system, Admin and Store REST APIs, an Admin dashboard UI, and events other plugins can subscribe to.

Compatibility

Built and tested against Medusa 2.18.0. Requires Copy to clipboard@medusajs/medusa, Copy to clipboard@medusajs/framework, and the other packages listed under Copy to clipboardpeerDependencies to already be present in the consuming application (they are, for any standard Medusa v2 project).

Features

  • Brand CRUD: create, update, soft delete + restore, permanent delete
  • One brand → many products, via a Module Link (not a direct foreign key — see docs/architecture.md in the workspace for why)
  • Assign a brand at product-creation time through the normal Admin product form (Copy to clipboardadditional_data.brand_id), or manage assignment after the fact from either side — the product's Admin page (see below), the brand's own detail page, or via the Brand's product endpoints directly
  • Storage-provider-agnostic logo/banner fields (plain URL + file id — works with local, S3, MinIO, Cloudinary, or any configured Medusa File Module provider)
  • Bulk delete/restore
  • Search (Copy to clipboardq param), status/featured filtering, pagination and sorting on all list endpoints
  • Admin dashboard: a Brands list, a Brand detail page (edit brand fields, plus a searchable/paginated multi-select product picker to assign, add, or remove products in bulk), a "Products" section in the Create Brand form to assign products at creation time, and a Product-detail widget for assigning, changing, or removing that product's brand from the product's own page
  • Configurable via plugin options: Copy to clipboardenableSEO, Copy to clipboardenableFeaturedBrands, Copy to clipboardlogoRequired
  • Events (Copy to clipboardbrand.created, Copy to clipboard.updated, Copy to clipboard.deleted, Copy to clipboard.restored) and workflow hooks (Copy to clipboardbrandCreated, Copy to clipboardbrandUpdated) for other plugins to build on

Installation

npm install @mgtalabs/medusa-brand

Register it in your Medusa application's Copy to clipboardmedusa-config.ts:

module.exports = defineConfig({
// ...
plugins: [
{
resolve: "@mgtalabs/medusa-brand",
options: {
enableSEO: true,
enableFeaturedBrands: true,
logoRequired: false,
},
},
],
})

Then run migrations to create the Copy to clipboardbrand table and sync the product-brand link:

npx medusa db:migrate

Configuration

Option Type Default Effect Copy to clipboardenableSEO Copy to clipboardboolean Copy to clipboardtrue Governs whether Copy to clipboardmeta_title/Copy to clipboardmeta_description are exposed in the admin form/API surface. The columns always exist regardless, to avoid schema drift if you flip this later. Copy to clipboardenableFeaturedBrands Copy to clipboardboolean Copy to clipboardtrue Governs whether the Copy to clipboardis_featured filter and Copy to clipboard/store/brands/featured are meaningfully used in your storefront. Copy to clipboardlogoRequired Copy to clipboardboolean Copy to clipboardfalse When Copy to clipboardtrue, brand creation is rejected (Copy to clipboardINVALID_DATA) if Copy to clipboardlogo_url isn't provided.

Admin API

All routes are under Copy to clipboard/admin and require the standard Medusa admin authentication — nothing extra to configure.

Method Path Description Copy to clipboardGET Copy to clipboard/admin/brands List brands. Query: Copy to clipboardq, Copy to clipboardstatus, Copy to clipboardis_featured, Copy to clipboardlimit, Copy to clipboardoffset, Copy to clipboardorder Copy to clipboardPOST Copy to clipboard/admin/brands Create a brand Copy to clipboardGET Copy to clipboard/admin/brands/:id Get a brand Copy to clipboardPOST Copy to clipboard/admin/brands/:id Update a brand Copy to clipboardDELETE Copy to clipboard/admin/brands/:id Soft delete (default); pass Copy to clipboard?permanent=true for a hard delete Copy to clipboardPOST Copy to clipboard/admin/brands/:id/restore Restore a soft-deleted brand Copy to clipboardPOST Copy to clipboard/admin/brands/batch Bulk delete/restore: Copy to clipboard{ delete?: string[], restore?: string[] } Copy to clipboardGET Copy to clipboard/admin/brands/:id/products List a brand's products (paginated) Copy to clipboardPOST Copy to clipboard/admin/brands/:id/products Assign products: Copy to clipboard{ product_ids: string[] } Copy to clipboardDELETE Copy to clipboard/admin/brands/:id/products Remove products: Copy to clipboard{ product_ids: string[] }

Brand fields: Copy to clipboardname, Copy to clipboardslug (auto-derived from Copy to clipboardname if omitted), Copy to clipboarddescription, Copy to clipboardshort_description, Copy to clipboardlogo_url, Copy to clipboardlogo_file_id, Copy to clipboardbanner_url, Copy to clipboardbanner_file_id, Copy to clipboardmeta_title, Copy to clipboardmeta_description, Copy to clipboardis_featured, Copy to clipboardsort_order, Copy to clipboardstatus (Copy to clipboardactive/Copy to clipboardinactive), Copy to clipboardmetadata.

Assigning a brand at product-creation time

POST /admin/products
{
"title": "...",
...
"additional_data": { "brand_id": "brand_123" }
}

Store API

Public routes, gated by a publishable API key like any other store route.

Method Path Description Copy to clipboardGET Copy to clipboard/store/brands List active brands. Query: Copy to clipboardq, Copy to clipboardis_featured, Copy to clipboardlimit, Copy to clipboardoffset, Copy to clipboardorder Copy to clipboardGET Copy to clipboard/store/brands/featured Convenience alias for Copy to clipboard?is_featured=true Copy to clipboardGET Copy to clipboard/store/brands/:idOrSlug Get a brand by id or slug (same handler resolves either) Copy to clipboardGET Copy to clipboard/store/brands/:idOrSlug/products List a brand's products

Events

Event Payload Copy to clipboardbrand.created Copy to clipboard{ id } Copy to clipboardbrand.updated Copy to clipboard{ id } Copy to clipboardbrand.deleted Copy to clipboard{ id, permanent } Copy to clipboardbrand.restored Copy to clipboard{ id }

Subscribe from any plugin:

// src/subscribers/brand-created.ts
import type { SubscriberArgs, SubscriberConfig } from "@medusajs/framework"
export default async function brandCreatedHandler({
event: { data },
}: SubscriberArgs<{ id: string }>) {
// ...
}
export const config: SubscriberConfig = { event: "brand.created" }

Extension points

Beyond events, Copy to clipboardcreateBrandWorkflow and Copy to clipboardupdateBrandWorkflow expose hooks for synchronous, transactional extensibility:

import { createBrandWorkflow } from "@mgtalabs/medusa-brand/workflows/create-brand"
createBrandWorkflow.hooks.brandCreated(async ({ brand }, { container }) => {
// runs inside the same workflow transaction
})

The Copy to clipboardproduct-brand Module Link itself is also queryable by any other plugin.

Known limitations

  • Filtering core's Copy to clipboard/admin/products or Copy to clipboard/store/products by Copy to clipboardbrand_id directly is not supported — Medusa doesn't document a way to extend a core route's query validator from a plugin. Use this plugin's own Copy to clipboard/admin/brands/:id/products / Copy to clipboard/store/brands/:idOrSlug/products instead.
  • Copy to clipboard/store/.../products returns whatever products are linked regardless of their own publish status — Medusa's Query layer doesn't support filtering by a linked model's property (confirmed against current docs), only by the link table's own columns.
  • HTTP-level integration tests for this plugin live in the consuming application's own test suite, not this package's — Copy to clipboard@medusajs/test-utils's Copy to clipboardmedusaIntegrationTestRunner has an open upstream bug when configured at the plugin level (medusajs/medusa#11863). Module-level tests (Copy to clipboardmoduleIntegrationTestRunner) are unaffected and ship in Copy to clipboardsrc/modules/brand/__tests__/.

License

Proprietary — see the workspace root LICENSE. Free during the current evaluation period; see the workspace's Copy to clipboarddocs/architecture.md for the licensing/pricing model.

You may also like

Browse all integrations

Build your own

Develop your own custom integration

Build your own integration with our API to speed up your processes. Make your integration available via npm for it to be shared in our Library with the broader Medusa community.

gift card interface

Ready to build your custom commerce setup?