@empty-complete-org/medusa-product-attributes
v1.2.0
Published
Custom attributes module for Medusa v2 with support for text, number, file types and units of measurement
Maintainers
Readme
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 {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
# Via pnpm
pnpm add @empty-complete-org/medusa-product-attributes
# Via npm
npm install @empty-complete-org/medusa-product-attributes
# Via yarn
yarn add @empty-complete-org/medusa-product-attributes1. Add the plugin to configuration
// medusa-config.ts
import { defineConfig } from '@medusajs/framework/utils'
export default defineConfig({
plugins: [
{
resolve: "@empty-complete-org/medusa-product-attributes",
options: {},
},
],
})2. Run migrations
npx medusa db:migrate3. 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
GET /admin/product/:productId/attribute-schema
GET /admin/category/:categoryId/custom-attributes
POST /admin/category/:categoryId/custom-attributes
PATCH /admin/category/:categoryId/custom-attributes
GET /admin/global-attributes
POST /admin/global-attributes
PATCH /admin/global-attributes
GET /admin/attribute-templates
POST /admin/attribute-templates
PATCH /admin/attribute-templates
POST /admin/attribute-templates/:id/apply { category_id }
GET /admin/product/:productId/custom-attributes
POST /admin/product/:productId/custom-attributesProgrammatic usage
import { CUSTOM_ATTRIBUTE_MODULE } from '@empty-complete-org/medusa-product-attributes'
const module = container.resolve(CUSTOM_ATTRIBUTE_MODULE)
// Create a category attribute
await module.createCategoryAttribute({
label: 'Screen Size',
type: 'number',
unit: 'inch',
category_id: 'pcat_phones',
})
// Add a product value
await 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 |
|------|-------------|-----------|
| text | text input | value |
| number | number input + unit badge | value, value_numeric |
| file | upload button | value (URL), value_file |
| boolean | select Yes/No | value |
Project Structure
medusa-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/
│ │ └── custom-attributes/
│ └── modules/product-attributes/
│ ├── models/
│ ├── migrations/
│ ├── service.ts
│ └── index.ts
├── assets/
├── package.json
├── tsconfig.json
└── LICENSEDevelopment
pnpm install
pnpm test # Jest unit tests
pnpm run build # medusa plugin:build
pnpm run dev # medusa plugin:develop