Product Attributes
Add a flexible custom attribute system to products
Medusa Product Attributes
A flexible attribute system for Medusa v2 — text, number, file, boolean, with units and category inheritance
Features
Feature Description Text Attributes Arbitrary text values for products Numeric Attributes Numbers with units (kg, m, pcs, etc.) File Attributes File uploads: certificates, 3D models, manuals Boolean Attributes Yes/No values Category Inheritance Attributes cascade from parent to child categories Global Attributes Applied to every product automatically Templates Reusable blueprints — apply to any category in one click Auto Slug Labels are transliterated (Russian, Chinese, any script) Smart File Naming Uploaded images renamed to Copy to clipboard{product_handle}_{attr_key}.ext i18n English and Russian out of the box, extensible
Requirements
Dependency Version Medusa ^2.13 Node.js >=20 TypeScript ^5.0
Quick Start
Installation
12345678# Via pnpmpnpm add @empty-complete-org/medusa-product-attributes# Via npmnpm install @empty-complete-org/medusa-product-attributes# Via yarnyarn add @empty-complete-org/medusa-product-attributes
1. Add the plugin to configuration
1234567891011// medusa-config.tsimport { defineConfig } from '@medusajs/framework/utils'export default defineConfig({plugins: [{resolve: "@empty-complete-org/medusa-product-attributes",options: {},},],})
2. Run migrations
1npx medusa db:migrate
3. Done!
The plugin automatically creates tables and registers admin widgets.
Screenshots
Category widget with inheritance
Product attribute values
Settings — Global Attributes & Templates
Usage
Admin
- Category attributes — open any category, the "Attributes" widget appears below details. Add custom attributes (inherited by subcategories), or pick from a template.
- Global attributes — Settings → Product Attributes → Globals tab. Applied to every product automatically.
- Templates — Settings → Product Attributes → Templates tab. Reusable blueprints.
- Product values — open any product, the "Characteristics" widget shows all inherited + global attributes with inputs.
API
12345678910111213GET /admin/product/:productId/attribute-schemaGET /admin/category/:categoryId/custom-attributesPOST /admin/category/:categoryId/custom-attributesPATCH /admin/category/:categoryId/custom-attributesGET /admin/global-attributesPOST /admin/global-attributesPATCH /admin/global-attributesGET /admin/attribute-templatesPOST /admin/attribute-templatesPATCH /admin/attribute-templatesPOST /admin/attribute-templates/:id/apply { category_id }GET /admin/product/:productId/custom-attributesPOST /admin/product/:productId/custom-attributes
Programmatic usage
12345678910111213141516171819import { CUSTOM_ATTRIBUTE_MODULE } from '@empty-complete-org/medusa-product-attributes'const module = container.resolve(CUSTOM_ATTRIBUTE_MODULE)// Create a category attributeawait module.createCategoryAttribute({label: 'Screen Size',type: 'number',unit: 'inch',category_id: 'pcat_phones',})// Add a product valueawait module.createProductAttribute({product_id: 'prod_iphone15pro',category_custom_attribute_id: 'attr_screen_size',value: '6.1',value_numeric: 6.1,})
Attribute types
Type Admin input Stored in Copy to clipboardtext text input Copy to clipboardvalue Copy to clipboardnumber number input + unit badge Copy to clipboardvalue, Copy to clipboardvalue_numeric Copy to clipboardfile upload button Copy to clipboardvalue (URL), Copy to clipboardvalue_file Copy to clipboardboolean select Yes/No Copy to clipboardvalue
Project Structure
1234567891011121314151617181920medusa-product-attributes/├── src/│ ├── admin/│ │ ├── lib/│ │ │ ├── i18n.ts│ │ │ ├── locales/│ │ │ │ ├── en.json│ │ │ │ └── ru.json│ │ │ └── sdk.ts│ │ ├── routes/settings/product-attributes/│ │ │ └── page.tsx│ │ └── widgets/│ │ ├── category-attribute-templates.tsx│ │ └── product-attribute-values.tsx│ ├── api/admin/│ │ ├── attribute-templates/│ │ ├── category/[categoryId]/custom-attributes/│ │ ├── global-attributes/│ │ └── product/[productId]/│ │ ├── attribute-schema/
Development
1234pnpm installpnpm test # Jest unit testspnpm run build # medusa plugin:buildpnpm run dev # medusa plugin:develop
Contributing
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
Made with ❤️ for the Medusa community

