Product Master Specification
Product Master Specification
Overview
The product system consists of two main components that work together to provide complete product information:
- Product Master Data (
src/data/product-master-data.mjs) - Central product database - Product Introduction Pages (
src/mdx/notes/) - Detailed MDX pages for each product
The product-master-data.mjs file serves as the single source of truth for product data, containing all product information used throughout the application.
File Location: /src/data/product-master-data.mjs
Format: ES Module (JavaScript)
Total Products: 209 items
This file drives:
- Product pages generation
- Search functionality
- Mercari shop integration
- Product listings and filters
- Price management
Data Structure
The file exports a single array named allProducts:
const allProducts = [
{ /* product object */ },
{ /* product object */ },
// ... 209 products total
];
export { allProducts };
Product Schema
Each product object contains the following fields:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| slug | string | ✅ Required | Unique identifier, URL-safe | "oxi-one-mk2-black" |
| name | string | ✅ Required | Product display name | "OXI ONE MKII Black Edition" |
| brand | string | ✅ Required | Brand identifier | "oxi" |
| imgSrc | string | ✅ Required | Image path (without extension) | "/images/p/oxi-one-mk2-02-angle" |
| description | string | ✅ Required | Product description in Japanese | "8パートシーケンサー搭載..." |
| price | number | ❌ Optional | Price in JPY | 158800 |
| spec | object | ✅ Required | Specifications object | { width: "6HP" } |
| spec.width | string|null | ✅ Required | Module width in HP units | "6HP", null |
| mercariProductId | string | ❌ Optional | Mercari shop product ID | "g6nXiybfcAJbDSjouV8fai" |
| subtitle | string | ❌ Optional | Product subtitle | "Hybrid Oscillator" |
| seriesId | string | ❌ Optional | Product series identifier for grouping | "zudo-stand" |
| detailHref | string | ❌ Optional | Link to detailed MDX article | "/products/oxi-one-mk2-intro/" |
| brandBasedCategory | string | ❌ Optional | Brand-specific category | "zudo-rail" |
Field Specifications
slug
Purpose: Unique product identifier used in URLs and internal references
Format: Lowercase, hyphen-separated words
Constraints: Must be unique across all products
Naming Conventions:
- Use lowercase letters and hyphens only
- Brand prefix when relevant:
{brand}-{product-name} - Version numbers: Use
mk2,v2etc. (notmkiiorvII) - Color/variant suffix: Append variant name (e.g.,
oxi-one-black) - Set indicators:
set1,set2,dual
Examples:
oxi-one(base product)oxi-one-mk2(version 2)oxi-one-mk2-black(version + color variant)oxi-pipe-mk2(accessory version 2)zudo-rail-40-silver-set1(brand + product + size + color + set)
name
Purpose: Product display name shown to users
Character Support: Full Unicode (Japanese, English, special characters)
Length: Typically 10-50 characters
Format Requirements:
- Use proper capitalization
- Version format: “MKII”, “V2” in uppercase
- Color format: Append after colon (e.g., “OXI ONE: Black”)
Examples:
"OXI ONE""OXI ONE MKII""OXI ONE MKII Black Edition""zudo-rail 40HP Silver 単体""AI031 入力ミキサー"
brand
Purpose: Brand identifier for filtering and categorization
Format: Lowercase, hyphen-separated if multi-word
Valid Values (14 brands):
addacai-synthesisdivergent-wavesLMNCmeng-qimordaxnoisy-fruits-laboamoxipatching-pandarecoveryryktakazudoweston
imgSrc
Purpose: Path to product image
Format: Path without file extension
Processing: Images are processed through the build pipeline
Path Structure:
/images/p/{product-identifier}
Examples:
/images/p/oxi-one-mk2-02-angle/images/p/zudo-rail-40-silver-01/images/p/ai031-mixer-front
description
Purpose: Product description in Japanese
Content Guidelines:
- Clear, concise technical description
- Focus on key features and capabilities
- Typically 50-200 characters
- Use Japanese technical terms appropriately
- Follow text rules in
/doc/text-rule.md
Template:
[製品名]、[主要機能]。[特徴1]、[特徴2]、[特徴3]。
Example:
"OXI ONE MKII Black Edition、8パートシーケンサー搭載の次世代モデル。拡張されたジェネレーティブ機能、大型OLEDディスプレイ、最大64トラック制御が可能。"
price
Purpose: Product price in Japanese Yen
Format: Integer, no decimal places
Range: 1,100 - 158,800 JPY
Price Ranges by Category:
- Accessories (cables, etc.): 1,100 - 5,000 JPY
- Small modules: 5,000 - 20,000 JPY
- Standard modules: 20,000 - 60,000 JPY
- Premium/Complex modules: 60,000 - 160,000 JPY
spec
Purpose: Product specifications object
Required Field: width (always present)
Width Values:
- Standard HP units:
"2HP","6HP","10HP","14HP","16HP","20HP", etc. - Ranges:
"1-4HP","10-16HP","1HP-12HP" - Special formats:
"32HP/13HP","12+20HP" - Non-module items:
null,"--","200×35mm"
mercariProductId
Purpose: Links to Mercari shop listing
Format: 22-character alphanumeric string
Integration: Used for price synchronization
Example: "g6nXiybfcAJbDSjouV8fai"
subtitle
Purpose: Product subtitle Usage: Displayed as secondary descriptive text
Examples:
"Hybrid Oscillator""Dual / Stereo Voltage Controlled Amplifier""VC Stochastic Voltage Generator""Stereo Discrete Mixer"
seriesId
Purpose: Groups related product variants together Usage: Enables series-based filtering and navigation Format: Lowercase, hyphen-separated identifier
Examples:
"zudo-stand"- All zudo-stand variants share this ID"oxi-one-mk2"- All OXI ONE MKII variants share this ID"zudo-rail"- All zudo-rail variants share this ID
detailHref
Purpose: Link to detailed MDX article
Format: Absolute path to products section
Pattern: /products/{slug}-intro/
Examples:
/products/oxi-one-mk2-intro//products/oxi-pipe-mk2-intro/
brandBasedCategory
Purpose: Brand-specific product categorization
Current Usage: Primarily for Takazudo brand products
Known Values:
"zudo-rail"- Takazudo rail products"zudo-block"- Takazudo block products
Product Introduction Pages (MDX)
File Naming Convention
src/mdx/products/{slug}-intro.mdx
- Use the same slug as in product master data
- Always end with
-introsuffix
Frontmatter Structure
---
title: '{Brand}: {Product Name}'
description: '{Brand} {Product}の紹介記事になります。{One-line description}'
imgThumb: null # Auto-uses imgSrc from product master data
avoidListing: false # Always false for product intros
product: 'product-slug' # Must match product master data slug
tags:
- brand-name
- product-category
- modular # if applicable
categories:
- products-intro # Always this for product pages
---
Content Structure Template
- Opening Statement - Introduction with product description and purchase link
- Table of Contents - TOC section marker
- Product Photos Section - Image gallery with ImgsGrid component
- Feature Sections - Technical details and capabilities
- Closing Section - Outro wrapper with final purchase link
Opening Statement Example
Takazudo Modularにて取り扱わせて頂いている、{Brand}の**{Product}**の紹介/解説記事です。
{Product description paragraph}
本商品は、以下よりご購入頂けます。
<MercariNav ids={['product-slug']} />
Table of Contents
## TOC
Product Photos Section
## 商品写真
<ImgsGrid
srcs={[
'image-url-1',
'image-url-2',
]}
alts={['商品写真', '商品写真']}
extraWide />
Feature Sections
Use descriptive headers and include:
- Technical specifications
- Usage examples
- Integration tips
- Unique features
Closing Section
<Outro>
{Product}の紹介は以上になります。
<MercariNav ids={['product-slug']} />
ご参考になれば幸いです。
</Outro>
MDX Components Used
<MercariNav>- Product purchase linksid="slug"for single productids={['slug1', 'slug2']}for multiple products
<ImgsGrid>- Product image galleries- Props:
srcs,alts,divide,extraWide,captions
- Props:
<ExImg>- Single images with captions- Props:
src,alt,className,floatRight,floatLeft,extraWide,overFlowed
- Props:
<Youtube>- Embedded videos- Props:
url
- Props:
<TOC>- Table of contents placeholder<Outro>- Closing section wrapper<InfoBox>- Information callout box
Multi-Version and Variant Products
In Product Master Data
When a product has multiple versions or variants:
- Create separate entries for each version/variant
- Use distinct slugs:
oxi-onevsoxi-one-mk2vsoxi-one-mk2-black - Link to appropriate intro pages (can share the same page)
In MDX Pages
Options for handling variants:
- Shared Page: Use same intro page for similar variants
- Separate Pages: Create individual pages for major differences
- Combined Display: Use
<MercariNav ids={['v1-slug', 'v2-slug']}to show all versions
Example for color variants:
<MercariNav ids={['oxi-one-black', 'oxi-one-silver', 'oxi-one-white']} />
Product Categories and Tags
Common product categories used in tags:
-
Module Types:
modular- Eurorack modulessequencer- Sequencer devicessynth-voice- Voice/oscillator moduleseffector- Effect modulesvco- Voltage controlled oscillatorsvca- Voltage controlled amplifiersvcf- Voltage controlled filtersenvelope- Envelope generatorslfo- Low frequency oscillatorsutility- Utility modules
-
Device Types:
standalone- Non-modular devicesmidi- MIDI-capable devicescontroller- Control interfaces
-
Brand Tags: Use brand identifier from master data
Data Validation Rules
Required Fields
Every product MUST have:
slug- Unique identifiername- Display namebrand- Valid brand identifierimgSrc- Image pathdescription- Product descriptionspec- Object withwidthproperty
Format Requirements
| Field | Validation Rule |
|---|---|
| slug | Lowercase, alphanumeric with hyphens only, unique |
| brand | Must match valid brand list |
| imgSrc | Must start with /images/p/ |
| price | Positive integer or undefined |
| mercariProductId | 22 characters alphanumeric or undefined |
| detailHref | Must start with /notes/ and end with / or undefined |
| spec.width | String HP value, range, null, or special format |
Uniqueness Constraints
- slug: Must be unique across all products (enforced)
- mercariProductId: Should be unique when present (recommended)
- name: Should be unique or clearly differentiated (recommended)
Character Encoding
- All text fields support UTF-8
- Japanese characters required in name and description
- ASCII-only in slug and brand fields
- No emoji in product data
Data Patterns and Statistics
Slug Naming Pattern Examples
{brand}-{product}-{version}-{variant}
{brand}-{product}-{variant}
{product}-{variant}
Real Examples:
oxi-one-mk2-black- Brand + Product + Version + Colorzudo-rail-40-silver-set1- Brand + Product + Size + Color + Setaddac503-quad-linked-envelope- Brand/Model + Descriptionrecovery-blank-panel-1hp- Brand + Product + Size
Price Distribution
| Price Range | Product Count | Category |
|---|---|---|
| 1,100 - 5,000 | ~20% | Accessories, small utilities |
| 5,000 - 20,000 | ~35% | Basic modules |
| 20,000 - 60,000 | ~35% | Standard modules |
| 60,000+ | ~10% | Premium/Complex modules |
Brand Product Distribution
| Brand | Product Count | Primary Categories |
|---|---|---|
| takazudo | ~70 | Rails, blocks, utilities |
| addac | ~35 | Modules, systems |
| oxi | ~5 | Sequencers, controllers |
| ai-synthesis | ~15 | DIY modules |
| Others | ~63 | Various modules |
Integration Points
1. Mercari CSV Synchronization
Process:
- Export CSV from Mercari shop
- Place in
/mercari-data/directory asproduct_data_YYYY-MM-DD.csv - Run
pnpm update:mercari-prices - Script updates prices using
mercariProductIdmapping - Verify changes and commit
2. MDX Content Linking
Integration:
- Product pages link via
detailHref - MDX files reference products by slug
- Build process resolves product data at compile time
- Use
<MercariNav>component for product links
3. MiniSearch Indexing
Indexed Fields:
- title, description, tags, slug
- Excerpt text for full-text search
- Search data generated at build time (
search-data.json) - Served via Netlify Function with locale-aware score boosting
4. Next.js Page Generation
Process:
gatsby-node.mjsreads product data- Creates product pages programmatically
- Generates category and brand pages
- Processes MDX content with product data
5. Products Viewer Tool
Location: /sub-packages/products-viewer/
Purpose: Visual editor for product data
Port: http://zproducts.localhost:9755
Features:
- Click-to-edit interface
- Real-time file updates
- Add/remove products
- Bulk operations
- Sort and filter capabilities
Example Products
Example 1: Premium Sequencer
{
slug: 'oxi-one-mk2-black',
name: 'OXI ONE MKII Black Edition',
brand: 'oxi',
imgSrc: '/images/p/oxi-one-mk2-02-angle',
description: 'OXI ONE MKII Black Edition、8パートシーケンサー搭載の次世代モデル。拡張されたジェネレーティブ機能、大型OLEDディスプレイ、最大64トラック制御が可能。',
detailHref: '/products/oxi-one-mk2-intro/',
price: 158800,
spec: {
width: null,
},
mercariProductId: 'g6nXiybfcAJbDSjouV8fai',
}
Example 2: Eurorack Module
{
slug: 'addac503-quad-linked-envelope',
name: 'ADDAC503 Quad Linked Envelope',
brand: 'addac',
imgSrc: '/images/p/addac503-front',
description: '4つのADエンベロープ、多彩なトリガーモード、リンク機能搭載。複雑なエンベロープパターンの生成が可能。',
price: 58800,
spec: {
width: '16HP',
},
subtitle: 'Quad Linked Envelope Generator',
mercariProductId: 'HpQCfRxyKGBPFKzzfRhPqk',
}
Example 3: Accessory/Rail
{
slug: 'zudo-rail-40-nuts-set1',
name: 'zudo-rail-40 Nuts-set1',
brand: 'takazudo',
brandBasedCategory: 'zudo-rail',
imgSrc: '/images/p/40hp-nuts-set1',
description: '拡張性の高いDIY向けレールセット、40HP、Nuts版(スライドナット)、1セット。',
detailHref: '/products/zudo-rail-intro/',
price: 4480,
spec: {
width: '40HP',
},
mercariProductId: 'RZH5DPPmwai7AsyRqooc75',
}
Example 4: Product with Series Grouping
{
slug: 'zudo-stand-40',
name: 'zudo-stand-40',
seriesId: 'zudo-stand',
brand: 'takazudo',
brandBasedCategory: 'stand',
imgSrc: '/images/p/zudo-stand-40-view1',
description: 'zudo-blockシリーズを60°の安定した角度で支えるスタンド。3Dプリンター製、ツールレス組み立て可能。40HP用。',
detailHref: '/products/zudo-stand-intro/',
price: 2480,
spec: {
width: '40HP用',
},
}
Note: This example shows a product with seriesId for grouping. The name field contains the full product name (“zudo-stand-40”), and seriesId: 'zudo-stand' groups all zudo-stand variants together for organizational purposes.
Maintenance Workflows
Using Products Viewer App
Starting the App:
cd sub-packages/products-viewer
pnpm dev
# Opens at http://zproducts.localhost:9755
Editing Products:
- Click any cell to edit
- Press Enter to save
- Press Escape to cancel
- Changes are written immediately to file
Price Updates from Mercari
Workflow:
- Download CSV from Mercari Shops admin
- Save as
product_data_YYYY-MM-DD.csvin/mercari-data/ - Run update script:
pnpm update:mercari-prices
- Verify changes in products-viewer
- Commit updated
product-master-data.mjs
Adding New Products
IMPORTANT: Product Placement Rule
New products should always be added at the first position (index 0) of the allProducts array in product-master-data.mjs. This ensures:
- New products appear first in product listings
- Consistent chronological ordering (newest first)
- Easy to find recently added products
Method 1: Products Viewer
- Click green ”+” button (automatically adds at first position)
- Fill in all required fields
- Save changes
Method 2: Direct Edit
- Edit
product-master-data.mjsdirectly - Add new object at the beginning of the array (after
const allProducts = [) - Ensure all required fields present
- Run validation:
pnpm typecheck
Method 3: Generate MDX Template After adding to master data:
pnpm generate-product-intro-mdx <slug>
Editing Existing Products
Quick Edits:
- Use products-viewer for visual editing
- Click field → edit → Enter to save
Bulk Updates:
- Edit file directly for multiple changes
- Use find/replace for systematic updates
- Run build to verify:
pnpm build
Best Practices
Naming Conventions
Slugs:
- Use consistent prefixes for product lines
- Include version numbers when relevant (mk2, v2, not mkii)
- Add variant suffixes (color, size, set)
- Keep under 50 characters
- Always lowercase with hyphens
Product Names:
- Use official product names
- Include version/edition info (MKII, V2 in uppercase)
- Maintain brand consistency
- Use proper Japanese formatting
- Color variants after colon
Image Management
File Naming:
{slug}-{view-number}-{angle}
Examples:
oxi-one-mk2-01-frontoxi-one-mk2-02-anglezudo-rail-40-silver-01
Workflow:
- Place original images in
/imgs/products/ - Run image processing:
pnpm convimgs - Processed images appear in
/static/images/p/ - Reference in product data without extension
Description Writing Guidelines
Template:
[製品名]、[主要機能]。[特徴1]、[特徴2]、[特徴3]。
Requirements:
- Lead with product name/model
- State primary function
- List key features (3-5)
- Keep under 200 characters
- Use technical terms accurately
- Follow Japanese text rules
Good Example:
"ADDAC503、4つのADエンベロープジェネレーター。リンク機能、多彩なトリガーモード、個別出力搭載。"
Price Management
Consistency Rules:
- Regular Mercari sync (weekly/monthly)
- Verify price changes before committing
- Document price changes in commit messages
- Keep historical price data in Mercari CSVs
Format Requirements:
- Always use integers (no decimals)
- Omit comma separators in data
- Use null for price-on-request items
- Update both master data and Mercari
Japanese Text Guidelines
- Use proper Japanese technical terminology
- Maintain consistent tone (丁寧語)
- Include both technical specs and usage context
- Follow established patterns for descriptions
- Reference
/doc/text-rule.mdfor detailed rules
Common Issues and Solutions
Issue: Duplicate Slugs
Solution: Ensure unique slugs by adding suffixes (-v2, -black, -set1)
Issue: Missing Product Images
Solution: Check /imgs/products/ for originals, run pnpm convimgs
Issue: Price Sync Failures
Solution: Verify mercariProductId matches CSV, check for typos
Issue: MDX Page Not Linking
Solution: Ensure detailHref path matches actual MDX file location
Issue: Search Not Finding Product
Solution: Rebuild search index with pnpm build
Related Documentation
- Products Data Processing - How products.mjs processes master data
- Mercari Integration - CSV import/export workflow
- Image Processing Pipeline - Image optimization system
- Products Viewer Guide - Visual editor documentation