WooCommerce Custom Fields & Attributes
Before writing code
Fetch live docs:
- Web-search
site:developer.woocommerce.com product data custom fieldsfor product custom fields guide - Web-search
site:developer.wordpress.org plugins metadatafor WordPress metadata API - Web-search
woocommerce custom product attributes programmaticallyfor attribute creation
Product Attributes
Global Attributes
Defined in WooCommerce > Attributes — shared across all products:
- Stored as custom taxonomies:
pa_{attribute_slug}(e.g.,pa_color,pa_size) - Terms are the possible values (Red, Blue, Small, Large)
- Can be used for filtering, variations, and layered navigation
- Managed via
wc_create_attribute(),wc_update_attribute(),wc_delete_attribute()
Custom (Local) Product Attributes
Per-product attributes — not global taxonomies:
- Stored in product meta as part of
_product_attributesarray - Visible on the product page under "Additional Information" tab
- Set via
$product->set_attributes()withWC_Product_Attributeobjects
Setting Attributes Programmatically
Create WC_Product_Attribute objects:
set_id()— 0 for custom attributes, taxonomy ID for globalset_name()— taxonomy name (pa_color) or custom labelset_options()— array of term IDs (global) or string values (custom)set_visible()— show on product pageset_variation()— used for variations
Product Meta
Core Meta Keys
| Key | Description |
|---|---|
_price | Current active price |
_regular_price | Regular price |
_sale_price | Sale price |
_sku | Stock Keeping Unit |
_stock | Stock quantity |
_stock_status | instock / outofstock / onbackorder |
_weight, _length, _width, _height | Dimensions |
_virtual, _downloadable | Product type flags |
Custom Meta
$product->update_meta_data( '_my_custom_field', $value )then$product->save()$product->get_meta( '_my_custom_field' )— retrieve value- Prefix custom keys with
_to hide from the Custom Fields meta box
Adding Product Edit Fields
Use hooks to add fields to the product edit screen:
woocommerce_product_options_general_product_data— General tabwoocommerce_product_options_inventory_product_data— Inventory tabwoocommerce_product_options_shipping_product_data— Shipping tabwoocommerce_product_options_advanced— Advanced tab- Save with:
woocommerce_process_product_metaaction
Field Rendering Functions
woocommerce_wp_text_input( $args )— text inputwoocommerce_wp_textarea_input( $args )— textareawoocommerce_wp_select( $args )— dropdown selectwoocommerce_wp_checkbox( $args )— checkboxwoocommerce_wp_hidden_input( $args )— hidden field
Custom Product Tabs
Adding to Product Page
Filter woocommerce_product_tabs to add, remove, or reorder tabs:
- Return array with
title,priority,callbackkeys - Remove default tabs by unsetting keys:
description,additional_information,reviews
Adding to Product Edit (Admin)
Filter woocommerce_product_data_tabs to add tabs in the product editor:
- Return array with
label,target,class,priority - Render panel content via
woocommerce_product_data_panelsaction
Order Meta
$order->update_meta_data( '_my_field', $value )then$order->save()$order->get_meta( '_my_field' )— retrieve value- HPOS-compatible: always use CRUD methods, never
update_post_meta()
Customer Meta
$customer->update_meta_data()/$customer->get_meta()viaWC_Customer- Or
update_user_meta()/get_user_meta()for WordPress user meta
Custom Taxonomies
Registering Custom Taxonomies
Use register_taxonomy() on init hook:
- Associate with
productpost type for product classification - Set
show_in_restfor REST API / block editor support - Hierarchical (like categories) or flat (like tags)
Best Practices
- Use global attributes for values shared across products (color, size, brand)
- Use custom meta for product-specific data not used in filtering
- Prefix custom meta keys with underscore to hide from the generic meta box
- Always use CRUD methods (
update_meta_data/get_meta) for HPOS compatibility - Sanitize all input before saving:
sanitize_text_field(),wc_clean(),absint() - Escape all output:
esc_html(),esc_attr(),wp_kses_post()
Fetch the WooCommerce product data and metadata documentation for exact hook names, field function signatures, and attribute API before implementing.