Global vs. Local Attributes: Solving the WooCommerce Filtering Problem
Stop wondering why your WooCommerce product filters are empty. Learn the critical difference between global and local attributes and how to implement them for better site performance.
23 May 2026, 21:10 UTC

The Filtering Gap: Why Your Attributes Aren't Showing Up
\nYou've spent hours adding detailed specifications to your WooCommerce products—material, size, or voltage—only to find that your \\\"Filter Products by Attribute\\\" widget remains empty. The problem usually isn't a plugin conflict or a CSS bug; it is a fundamental architectural choice between Global and Custom (Local) attributes.
\n\nThe takeaway is simple: if you want a customer to be able to filter a category page by a specific trait, that trait must be a Global Attribute. Local attributes are for display only and are invisible to the WooCommerce filtering engine.
\n\n\nThe Architecture of Product Traits
\n\nGlobal Attributes (Taxonomy-based)
\nDefined under Products > Attributes, these are treated as custom taxonomies in WordPress. When you create a global attribute like \\\"Color,\\\" WooCommerce creates a dedicated taxonomy. Each value (Red, Blue, Green) becomes a term within that taxonomy.
\nBecause taxonomies are indexed in the database, they are highly performant for queries. This is why the layered navigation widgets can instantly pull a list of all products that share the \\\"Blue\\\" term across your entire catalog.
\n\n\nCustom Attributes (Meta-based)
\nDefined directly within the Product Data panel of a single product, these are \\\"Local\\\" attributes. They are stored as serialized data within the wp_postmeta table (or the wc_product_meta tables in newer High-Performance Order Storage versions).
Since these are stored as a blob of text associated with one specific product, the database cannot efficiently query them across the whole site. They are excellent for unique specifications that don't apply to other products, but they are useless for faceted search.
\n\n\nProgrammatic Implementation
\nWhen automating product imports or building custom dashboards, you must use the WC_Product CRUD API to ensure attributes are assigned correctly. Below is an example of how to assign a global attribute versus a local one.
// Run this in a custom plugin or functions.php context\n// Required Permissions: Administrator or Product Editor\n\n$product = wc_get_product( 123 ); // Replace 123 with your product ID\n$attributes = $product->get_attributes();\n\n// 1. Adding a GLOBAL attribute\n// 'pa_color' is the taxonomy name (pa = product attribute)\n$attribute = new WC_Product_Attribute();\n$attribute->set_id( wc_attribute_taxonomy_id_by_name( 'pa_color' ) );\n$attribute->set_name( 'pa_color' );\n$attribute->set_options( array( 'blue', 'green' ) ); // Terms must exist in the taxonomy\n$attribute->set_visible( true );\n$attribute->set_variation( true );\n\n// 2. Adding a LOCAL (Custom) attribute\n$local_attribute = new WC_Product_Attribute();\n$local_attribute->set_name( 'Unique Batch ID' );\n$local_attribute->set_options( array( 'BATCH-001' ) );\n$local_attribute->set_visible( true );\n$local_attribute->set_variation( false );\n\n$attributes['pa_color'] = $attribute;\n$attributes['unique-batch-id'] = $local_attribute;\n\n$product->set_attributes( $attributes );\n$product->save();\n\n\nRisk: Overwriting the attributes array without calling get_attributes() first will delete all existing attributes on the product. Always fetch the current set before updating.
Trade-offs and Performance
\nWhile Global attributes enable filtering, they come with a management cost. Every global attribute adds to the number of terms in your database. In catalogs with tens of thousands of products and hundreds of global attributes, the admin interface can become sluggish.
\n\n\n| Feature | \nGlobal Attributes | \nCustom (Local) Attributes | \n
|---|---|---|
| Filterable via Widgets | \nYes | \nNo | \n
| Database Storage | \nTaxonomy Terms | \nSerialized Meta | \n
| Management | \nCentralized | \nPer-Product | \n
| Query Speed | \nFast (Indexed) | \nSlow (Non-indexed) | \n
Verification and Limitations
\nTo verify your setup, add a \\\"Filter Products by Attribute\\\" widget to your shop sidebar. If your attribute does not appear in the dropdown list of available filters, it is likely a local attribute.
\nLimitation: WooCommerce does not provide a native \\\"Convert to Global\\\" button. If you have hundreds of products with local attributes that you now want to make filterable, you will need to write a migration script that reads the local meta, creates the corresponding global taxonomy terms, and re-assigns them using the WC_Product API.
Actionable Summary
\n- \n
- Use Global Attributes for any trait that defines a category of products (e.g., Size, Material, Brand). \n
- Use Custom Attributes for one-off data that is informative but not used for searching (e.g., \\\"Manufacturer Part Number\\\"). \n
- Verify filterability by checking the Appearance > Widgets area. \n
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.