Posted on

WooCommerce: Add Custom Field to Each Product Variation

Adding and displaying custom fields on WooCommerce products is quite simple. For example, you can add a “RRP/MSRP” field to a product, or maybe use ACF and display its value on the single product page.

Easy, yes. Unfortunately, the above only applies to products without variations (or the parent product only if it’s a variable product). So the question is: how do we add, save and display a custom field for each single variation?

WooCommerce: how to add a custom field to product variations

Part 1 – PHP Snippet: Add & Save Custom Field @ Product Variations


/**
 * @snippet       Add Custom Field to Product Variations - WooCommerce
 * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @sourcecode    https://businessbloomer.com/?p=73545
 * @author        Rodolfo Melogli
 * @compatible    Woo 3.3.4
 */

// -----------------------------------------
// 1. Add custom field input @ Product Data > Variations > Single Variation
 
add_action( 'woocommerce_variation_options_pricing', 'bbloomer_add_custom_field_to_variations', 10, 3 ); 

function bbloomer_add_custom_field_to_variations( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input( array( 
'id' => 'custom_field[' . $loop . ']', 
'class' => 'short', 
'label' => __( 'Custom Field', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'custom_field', true )
) 
);      
}
 
// -----------------------------------------
// 2. Save custom field on product variation save

add_action( 'woocommerce_save_product_variation', 'bbloomer_save_custom_field_variations', 10, 2 );
 
function bbloomer_save_custom_field_variations( $variation_id, $i ) {
    $custom_field = $_POST['custom_field'][$i];
	if ( ! empty( $custom_field ) ) {
		update_post_meta( $variation_id, 'custom_field', esc_attr( $custom_field ) );
	} else delete_post_meta( $variation_id, 'custom_field' );
}
 
// -----------------------------------------
// 3. Store custom field value into variation data
 
add_filter( 'woocommerce_available_variation', 'bbloomer_add_custom_field_variation_data' );

function bbloomer_add_custom_field_variation_data( $variations ) {
	$variations['custom_field'] = '<div class="woocommerce_custom_field">Custom Field: <span>' . get_post_meta( $variations[ 'variation_id' ], 'custom_field', true ) . '</span></div>';
	return $variations;
}

Part 2 – WooCommerce Template Override: Display Custom Field Upon Product Variation Selection

As the variation selection process uses Javascript in order to retrieve the correct variation data, the only choice we have is to override a WooCommerce template file called variation.php, which can be found under woocommerce/templates/single-product/add-to-cart

In order to override this template, create a file called “variation.php” and place it in your child theme’s woocommerce/single-product/add-to-cart folder.

Then, add a section with the variation data previously stored (see snippet, step #3):


// Add this <div> with variation custom field data

<div class="woocommerce-variation-custom_field">
	{{{ data.variation.custom_field}}}
</div>

The final child theme’s woocommerce/single-product/add-to-cart/variation.php file script should look like this:


// This is the <script> part in full

<script type="text/template" id="tmpl-variation-template">
	<div class="woocommerce-variation-description">
		{{{ data.variation.variation_description }}}
	</div>

	<div class="woocommerce-variation-price">
		{{{ data.variation.price_html }}}
	</div>
	
	<div class="woocommerce-variation-custom_field">
		{{{ data.variation.custom_field}}}
	</div>

	<div class="woocommerce-variation-availability">
		{{{ data.variation.availability_html }}}
	</div>
</script>

Where to add this code?

You can place PHP snippets at the bottom of your child theme functions.php file (before "?>" if you have it). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such delicate files - if you need more guidance, please take a look at my free WooCommerce Customization video tutorial.

Does this snippet still work?

Please let me know in the comments if everything worked as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting on PHP 7.

If you think this code saved you time & money, please join other Business Bloomer supporters and avail of 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP
  • woocommerce-customize-shop-page-PHP
  • woocommerce-advanced-customization
  • how-to-edit-woocommerce-cart
  • woocommerce-customize-checkout-page-PHP
  • woocommerce-email-customization
  • woocommerce-conditional-logic

Rodolfo Melogli

Author, WooCommerce expert, WordCamp speaker and Internet marketer, Rodolfo Melogli has worked as a WooCommerce freelancer since 2011. He helps entrepreneurs and developers overcome their WooCommerce nightmares :) Rodolfo is the organiser of WordCamp Dublin, the Dublin WooCommerce Meetup, the Dublin Ecommerce Meetup and the Dublin WordPress Meetup. He enjoys interacting with people, travelling and chasing tennis & soccer balls. Of course, he loves pizza too.

38 thoughts on “WooCommerce: Add Custom Field to Each Product Variation

  1. I have a query about this for Rodolfo or someone who may know.

    Is it possible to move the (custom field input ) to show *under the standard description input field – I think it would make it easier for a client/or anyone to find and understand.

    Anyone…..?

    1. Hey Roberta, thanks for your comment! You need to find an alternative to “woocommerce_variation_options_pricing” hook, maybe there is another one available for you that is positioned where you need it ๐Ÿ™‚

  2. Hello Rodolfo, this code did work a couple weeks ago, but now it does not display the values in the meta description on the single product page for variations. I can add and update the quantity and date fields and see the results of the changes in the meta data. The web page no longer shows the values of the fields.

    1. Hey Bruce, thanks for your comment! I don’t think Woo 3.5.1 changed the way this works, so try with some standard troubleshooting. Disable all plugins but Woo and switch theme, and see if it works.

  3. More edits – Forgive me if this may appear to be an overlong post – but it is beneficial. Also; I may repeat myself on occasion, but I want o be clear about all this.

    Using this code in previous versions of Woo resulted in nice variation descriptions. However, Woo has now implemented a “Description” field that does the same thing. ( Styling for this later )

    It supports html and is useful, but I wanted to use Bloomer code as well as the Woo, to add a second set of details pertaining to a particular variation. Seeing Woo has a global description, its easy to add it as a description – I wanted to have a separate set for particular items.

    The original Bloomer code has the div active at all times, so if there is no data entered it will still display – especially if there are colors, backgrounds, borders, etc applied. An additional “empty” style needs to be applied. This effectively “hides” the entire div and content if there is no content in the description two field.

    This required some changes to the Bloomer functionย code.
    Changes to the orig code:
    For the admin page, the “Custom Field” name was not working for the client, so a small re-edit was applied to make it more readable.

    Change 1 to:
    // 1. Add custom field input @ Product Data > Variations > Single Variation

     
    add_action( 'woocommerce_variation_options_pricing', 'bbloomer_add_custom_field_to_variations', 10, 3 ); 
     
    function bbloomer_add_custom_field_to_variations( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input( array(
    'id' => 'custom_field[' . $loop . ']',
    'class' => 'short',
    'label' => __( 'Description <sup>2</sup> - Displays after primary description below &darr;', 'woocommerce' ),
    'value' => get_post_meta( $variation->ID, 'custom_field', true )
    )
    );
    }
    
    

    Then for the product page itself – some more changes to the function code ( uses the added styles primarily ) to display on the page. As mentioned before, if there is no data in the field, it simply does not show, nifty!
    Change 3 to:
    // 3. Store custom field value into variation data

     
    add_filter( 'woocommerce_available_variation', 'bbloomer_add_custom_field_variation_data' );
     
    function bbloomer_add_custom_field_variation_data( $variations ) {
        $variations['custom_field'] = '<div class="woocommerce_custom_field no-data"><div class="var-desc2">' . get_post_meta( $variations[ 'variation_id' ], 'custom_field', true ) . '</div></div>';
        return $variations;
    }
    
    


    Styling CSS
    – add to the child theme or wherever the styling for the site resides – possibly the customizer.

    This styles the woocommerce variation display area
    Please note: There is a font awesome badge icon preceding the text – remove if not needed

    /* variation description - woo default */
    .woocommerce-variation-description{
        display:block;
        background:#f2f2f2;
        padding:0px 14px;
        color:#006868;
        border: 1px dashed #666; 
    }
    /* variation two description - bloomer add */
    .var-desc2 {
        display:block;
        background:#f2f2f2;
        padding:18px 14px;
        color:#006868;
        border-color:#666; 
        border-left: 1px dashed;
        border-right: 1px dashed;
        border-bottom: 1px dashed;
    }
    /* variation description before icon - woo default */
    .woocommerce-variation-description p:before {
        display:inline;
        content: "\f02e \A ";
        font-family: FontAwesome;
        color:red;
        font-weight:300;
    }
    /* variation description before icon - bloomer */
    .var-desc2::before {
        content: "\f02e \A ";
        font-family: FontAwesome;
        color:red;
        font-weight:300;
    }
    /* hide div if empty - no content in field */
    .var-desc2:empty,
    .no-data:empty {
        display: none;
    }
    
    1. Nice ๐Ÿ™‚ Remember to wrap your code between shortcodes “php” and “/php”

    2. Thanks so much for this update Wolfgen! I was just struggling with how to hide this when I have no content in the custom field. However, since I’m using this to display a link to a PDF, the css hide function is not working, because there is content within the wrapping div.

      add_filter( 'woocommerce_available_variation', 'bbloomer_add_custom_field_variation_data' );
       
      function bbloomer_add_custom_field_variation_data( $variations ) {
          $variations['custom_field'] = '<div class="woocommerce_custom_field no-data"><div class="technical-drawings-link"><a href="' . get_post_meta( $variations[ 'variation_id' ], 'custom_field', true ) . '" target="_blank">Click here to view/download Technical Drawing</a></div></div>';
          return $variations;
      }
      

      I need to be able to hide everything within the technical-drawings-link div if there is no content within the interior custom_field.
      Do you know of some way to make the hiding function work for this situation?

    3. Sorry about the late reply – lets see if I have this right?
      I showed how to hide the area if there is no content – however you do have content – a link to a pdf – right?

      Simply add a href link in the description field ( it supports html ) with a tip about it in the desc2 field

      …and you could change the function to show a link icon instead of the badge – f0c1

      it should work that way – you can alter the color of the link etc by adding a class to it, then referring to it in the css

  4. hello how did you find this hook woocommerce_variation_options_pricing I would like to put my field below variations SKU but can not understand which hook to use for it or how to identify hooks in admin, thank you

    1. Hello Mag – thanks so much for your comment! Just download Woo on your computer and do a file search for “woocommerce_variation_options_pricing”. You will find the right file and also other hooks if present ๐Ÿ™‚

  5. hey,

    How would you go changing variation price?

    as I done in single product ?

    function return_custom_price( $price, $product ) {
    	$shortcost_first = get_post_meta( $product->id, 'shortcost_first', true );
    	$shortcost_mid = get_post_meta( $product->id, 'vshortcost_mid', true );
    	$shortcost_minimum = get_post_meta( $product->id, 'shortcost_minimum', true );
    
    
       $unit_price = $shortcost_first +($shortcost_mid * ($shortcost_minimum - 1));
    	return $price + $unit_price;
        
    }
    add_filter('woocommerce_get_price', 'return_custom_price', 10, 3);
    add_filter('woocommerce_get_regular_price','return_custom_price', 10, 3);
    add_filter('woocommerce_get_sale_price','return_custom_price', 10, 3);
    
    1. Hey there, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

    2. thank you

  6. Awesome work! When trying to export product data via CSV or XML these fields do not appear. Are you able to suggest how to get them to appear?

    1. Hi there, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  7. Hi, can this also be used to add custom field which saves an image instead of text?

    1. Hi Jose, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  8. Hi…
    Amazing!!
    I have a question, how i can show the cutom field in the order item field??

    1. Hey Esteban, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  9. Hi Rodolfo Melogli

    If I want to change the customer filed to URL, how to do that?
    As I want to set a Variation to goURL function.

    thanks

    1. Hey Eddie, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  10. Hi

    In my theme this displays on the front end under the variation (size in this case) – I’d like it to display ABOVE the Price. I’ve toyed around and can’t get it to move at all! LOL.

    Is there a simple way to do this?

    Many thanks – works an absolute treat otherwise!

    1. Hey Ben, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

    2. I’d like to request/add another edit ing compound to this feature.

      Ive used this one with success to dispaly some extra info regarding the selected option, for example if the item has a Satin finish – that finish is UV treated. et, etc. – works well

      Is there a way to get this supporting html? Where a url or img link/popup be added to display an image to show just what that option is?

      EG Vertical, an image with a vertical dimanson – Horizontal an image with Horizontal dimensions – that way it could be used to display folding features or additional option popup links. Make sense?

    3. Hey Roberta, thanks for your comment! In part 3 of the snippet, whenever you echo the custom field content, you can definitely echo any HTML you like, including an image tag ๐Ÿ™‚

  11. This works with some caveats though
    1) if you change the label in the code from
    ‘label’ => __( ‘Custom Field’, ‘woocommerce’ ), to a lnger string, EG:
    ‘label’ => __( ‘Extra Information’, ‘woocommerce’ ), (this was done so the client understood what it was

    In the edit view the label is no long enough and truncates itself to a narrower area

    2) If you decide to not use a string in that custom field (I assume the data is being saved to the options.php) could not find it though (my guess is that it is serialzed data). Anyway it retians the previous input unless its overwritten by something else. So if you need to have it blank after you had something there, you need to add a space. Would be good if cleared itself, if no data was present.

    I found all this when I styled the resulting custom field info by adding a class to “class=”woocommerce_custom_field” – like: class=”woocommerce_custom_field xtra-info”

    A note of interest: How difficult woult it be to have the field display under the product description area above the add to cart button? I’m using this as a descriptor for each variations particular differences.

    1. Hey Roberta, thanks so much for your comment! I fixed issue 2) by adding “delete_post_meta” in the IF/ELSE – see revised snippet. In regard to your other request “display under the product description”… yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

    2. I figured it out through the themes setup – its using Visual Composer.

      In Visual Composer you can setup a “template” to use if you are using the same procedure over and over again – like the loop.

      So I made one and using the plugin addons; I simply “arranged” the page to the clients liking, and then used it via the Wocommerce settings as the singl product page display. I just moved the desc, price and other components int different positions.

      Worked for me.

  12. Any chance to get this as a plug-in? Thanks

    1. Hello Sebastian, thank you so much for your comment! Feel free to contact me privately and I’ll give you a quote for the work. Thanks ๐Ÿ™‚

  13. Is there a chance to display the value of this within the cart.php?

    1. Hey there, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  14. Hello Rodolfo,
    Thank you for the fantastic work your doing here. I just discovered your site and… goldmine!

    I want to use this snippet you wrote but inside a plugin. I will put this plugin on wordpress.org and so, I will not be able to manually create a template in the child theme.

    Do you know if I can have the template inside my plugin and then override the normal plugin. Or maybe unhook the call to the normal plugin and hook this one?

    Thanks in advance,
    Lucas

    1. Hey Lucas, thanks for your comment! I don’t specialize in plugins, so not sure here. Good luck ๐Ÿ™‚

  15. Thanks for this useful snippet! I’m sure this will come in handy for my upcoming projects.

    One question:

    I have seen this kind of variable – {{{ data.variation.custom_field}}} – quite often in different template files but don’t quite understand what it means. Do you have any resources that touch on this topic?

    Thanks once again for this post!

  16. Hi,

    Whatยดs the end goal with this? Can you show an example?

    Ricardo

    1. Hey Ricardo, thanks for your comment! For example, you might want to add a RRP/MSRP for each variation – or maybe a custom field such as an expiry date ๐Ÿ™‚

Questions? Feedback? Support? Leave your Comment Now!
If you're writing code, please wrap it between: [php] code_here [/php]

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.