Add custom fields to WooCommerce products

Even if WooCommerce provides a lot of ways to add custom data to your products, sometimes is just not enough, or no the best way to do it. You may need to add some custom fields that will properly show on your product page.

In this tutorial, you will learn how to create custom fields for your products. I won’t cover how to add custom fields on variations for now, it will be a separate tutorial.

Your custom fields will be added to the General tab in the product data section. You can add various types of fields, from simple text fields to dropdowns and text areas.

To begin, you need to hook the function that will print the fields to woocommerce_product_options_general_product_data, like this:


add_action( 'woocommerce_product_options_general_product_data', 'wc_custom_add_custom_fields' );

view raw

functions.php

hosted with ❤ by GitHub

Then you have to add the code to print the fields. There are various functions in WooCommerce to print different fields.
Let’s start with something simple, adding a text field:


add_action( 'woocommerce_product_options_general_product_data', 'wc_custom_add_custom_fields' );
function wc_custom_add_custom_fields() {
// Print a custom text field
woocommerce_wp_text_input( array(
'id' => '_custom_text_field',
'label' => 'Custom Text Field',
'description' => 'This is a custom field, you can write here anything you want.',
'desc_tip' => 'true',
'placeholder' => 'Custom text'
) );
}

view raw

functions.php

hosted with ❤ by GitHub

This code will print a text input in your general data section while editing a product. As I already said above, you can have different fields, here is a list of functions you can use for each type of field:

There are also other types of fields you can add but that do not have a specific function. They are the fields tel, number, and email.
To create them just use the function woocommerce_wp_text_input and in the array that you pass as a parameter, where I specified the field ID, description, etc., above, add also the index 'type' => 'tel' or number or email based on the type of field you want to print.

Saving the values

Printing the fields is not enough. If you don’t add a function to save their value, as soon as you update the product the changes will be lost.
The hook to use in this case is woocommerce_process_product_meta. You will find the values of your custom fields in the global variable $_POST. To save the field in the example above use this code:


add_action( 'woocommerce_process_product_meta', 'wc_custom_save_custom_fields' );
function wc_custom_save_custom_fields( $post_id ) {
if ( ! empty( $_POST['_custom_text_field'] ) ) {
update_post_meta( $post_id, '_custom_text_field', esc_attr( $_POST['_custom_text_field'] ) );
}
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Add as many fields as you need after line 5 of this snippet.
Make sure to escape them for safety and, if needed, perform other actions on them.


More Posts That You Might Like…


57 responses to “Add custom fields to WooCommerce products”

  1. Thanks, super useful 🙂

    1. You’re welcome Alessandro! Glad you like it!

  2. Thank you for this helpful tutorial. Any pointers on how to access these custom fields on the front end? i.e. if I add a Checkbox field for indicating whether a Product is “Personalizable”, I would like to show “This product is Personalizable” signage on the Single Product Page.

    Can you please provide any direction?

    1. Hi Amit,
      to access the value of those fields you need to use get_post_meta().

      1. in which file this code has to be inserted?

        1. It has to be added in your theme’s functions.php file!

  3. thanks bro really simple and helpful…:)

    1. You’re welcome harish! 🙂

  4. hi Nicola and Thanks For Post , it is really helpful.
    here i am doing little extra , it will be really helpful if you can give me answer.
    i am adding new tab in product data ( For Example PRODUCT INFO ) , i want to add custom fields in to this tab , but i think i far away from answer . so can you… plzzzzzzzzzzz

  5. /*
    * Add Custom Tab In Product Data
    */
    add_action(‘woocommerce_product_write_panel_tabs’, ‘woo_add_custom_admin_product_tab’);

    function woo_add_custom_admin_product_tab() {
    ?>

    <?php
    }

    for adding tab , plz answer as soon as possiable.

  6. Hi there!

    Hope you doing well! Nice tutorial but i wondering if your workaround would work in my case.

    I am actually using woocommerce on my wordpress site. I am selling paintings. The products are paintings. I have a list of artists as pages. Each artist is one page. I would like to connect the pages and products so I can show the artist’s name on the painting page and the user can click on the name and it takes them to the artist page. How do I do this?

    Thanks a lot!

    Best,

    Dan

    1. Hello,
      That would be definitely possible. It’s not easy to do though.

      What I’d do is to create a dropdown on the product page which lists all the artists, pages in your case, and then you can choose which one to link to the product.

      I’d suggest you to contact a WooExpert if you need some help with the code.

  7. OMG!! after many hours trying to find this
    thank you so much from Colombia 😀

    1. You’re welcome Luis! I’m glad it’s useful for you 🙂

  8. I just copied the same code but I am receiving a syntax error. Parse error: syntax error, unexpected end of file in /home/xxxx/functions.php on line 46

    1. Hello way2web,
      Make sure that you pasted the code properly.

      If the functions.php file originally ends with a ?> make sure to add the code from the article before that sign.

  9. So awesome this! I’ve created the text field and saved an image url.
    However I would like to have the custom field value (img url) being used in this fuction:
    https://www.skyverge.com/blog/add-information-woocommerce-product-images/
    (2nd raw code block)
    How can I echo the custom product field value. Could you please advise?

    1. With thise code I’m able to show the url on the frontend:
      echo get_post_meta( $post->ID, ‘_custom_text_field’, true );
      But the printed URL should inside the to show the actual image. See what I mean. Hope to hear from you.

      1. Hello Frank,
        You are almost there, just need to print the URL inside a <img /> HTML tag.

        Something like:

        <img src="PRINT_YOUR_URL_HERE" title="YOUR IMAGE TITLE" alt="YOUR IMAGE ALT TEXT" />
        
      2. In what file did you insert this snippet? single-page.php, functions.php …or was it in a woocommerce file?

        1. The code to add fields from this article has to be added in functions.php, the code to get the value of the fields instead can go into the template files, or in functions.php depending on what you need to do.

  10. Hi there. I think I did this correctly, but nothing is showing on the front end. I added to my functions.php (child):

    add_action( ‘woocommerce_product_options_general_product_data’, ‘wc_custom_add_custom_fields’ );
    function wc_custom_add_custom_fields() {
    // Print a custom text field
    woocommerce_wp_text_input( array(
    ‘id’ => ‘_custom_text_field’,
    ‘label’ => ‘Custom Text Field’,
    ‘description’ => ‘This is a custom field, you can write here anything you want.’,
    ‘desc_tip’ => ‘true’,
    ‘placeholder’ => ‘Custom text’
    ) );
    }
    add_action( ‘woocommerce_process_product_meta’, ‘wc_custom_save_custom_fields’ );
    function wc_custom_save_custom_fields( $post_id ) {
    if ( ! empty( $_POST[‘_custom_text_field’] ) ) {
    update_post_meta( $post_id, ‘_custom_text_field’, esc_attr( $_POST[‘_custom_text_field’] ) );
    }
    }

    When I am in the product area in the backend, I see a “custom text field” I entered some information, and updated. However, when I look at the product in either the product > category or under all products, I see no custom text. I have applied this to an existing product. (http://www.floorsforless.net/product/stoneworks-terra-12×24/). ps…I know the image is too large – I already spoke to my client about this.

    Will this show up in the products page (where I see all products in the category) or will it show up in the product details page only?

    I am using the “Styled Store” child theme and WordPress 4.6.1

    Thanks for any help.
    Abe

    1. Hello Abe,
      It does not show anywhere by default, you need to retrieve those data with get_post_meta() and then print it wherever you want it to show.

  11. Very nice ! thing helped a lot!

    1. You’re welcome!

  12. Hi Nicola, first of all, I would like to thank you for a nice and useful tutorial. I have one question regarding this. Please how can I retrieve my data right after add to cart button with this code? Thank you very much for you reply and have a nice day.

    add_action( ‘woocommerce_after_add_to_cart_button’, ‘add_content_after_addtocart_button_func’ );
    function add_content_after_addtocart_button_func() {
    // Echo content.
    echo ‘

    Place your content here!

    ‘;
    }

    1. Hello Viktoria,
      You need to get the value of the options with this code:

      get_post_meta( $product_id, '_custom_field_name', true );
      

      You can print that directly or save it into a variable to use later. Make sure to replace $product_id with the variable containing your product ID.

  13. Hello Nicola,
    Thanks alot for the tutorial, it is very helpful, I have just realized that when i want to use a blank field or delete the value of the field after i press update it goes back to the old value, in another word it seems i cannot save a blank field. any idea how to save the issues ?
    here is my code
    require_once( get_template_directory() . ‘/theme/init.php’ );

    add_action( ‘woocommerce_product_options_general_product_data’, ‘wc_custom_add_custom_fields’ );

    function wc_custom_add_custom_fields() {
    // Print a custom text field
    woocommerce_wp_text_input( array(
    ‘id’ => ‘_custom_text_field’,
    ‘label’ => ‘Manufacturer Part #’,
    ‘description’ => ‘This is a custom field, you can write here anything you want.’,
    ‘desc_tip’ => ‘true’,
    ‘placeholder’ => ‘Custom text’
    ) );

    woocommerce_wp_text_input( array(
    ‘id’ => ‘_custom_text_field-1’,
    ‘label’ => ‘Manufacturer Name’,
    ‘description’ => ‘This is a custom field, you can write here anything you want.’,
    ‘desc_tip’ => ‘true’,
    ‘placeholder’ => ‘Custom text’
    ) );
    }

    //stat
    add_action( ‘woocommerce_process_product_meta’, ‘wc_custom_save_custom_fields’ );
    function wc_custom_save_custom_fields( $post_id ) {
    if ( ! empty( $_POST[‘_custom_text_field’] ) ) {
    update_post_meta( $post_id, ‘_custom_text_field’, esc_attr( $_POST[‘_custom_text_field’] ) );

    }
    if ( ! empty( $_POST[‘_custom_text_field-1’] ) ) {
    update_post_meta( $post_id, ‘_custom_text_field-1’, esc_attr( $_POST[‘_custom_text_field-1’] ) );
    }
    }

    1. Hey,
      It’s because of that if ( ! empty( parts in the code. If you remove those lines (and the } of the respective if statements you will save anything from the fields.

      1. Thanks a lot that worked.
        What is the disadvangate in this case ?
        Is it better to have an If (data) >> Save else if (no data) Save ?

        1. The disadvantage is that you don’t check the data at all. empty just checks if the value is empty or not, but you could check anything, like the format of the value if there’s need, or the validity of it.

          Depends on what you are using the fields for.

        2. Im adding Menufacturar part number and UPC code to woo commerce product, and displaying them on the store front. I will use this feeds to mass import the values into the products.

        3. I don’t really know what the format of that would be. I guess you could skip the formatting if you are the only admin on the store.

  14. Hi, I managed to add the code but I want to display the custom text field in the single product front end, where do I have to add this: get_post_meta( $product_id, ‘_custom_field_name’, true );

    in Woocommerce single-product.php??

    1. Hi Gabriel,
      Depending on where you want to show the text, you can add it in functions.php or single-product.php.

      I’d say just override the template single-product.php in your theme and add the code there. That will always work, even if functions.php could be better in terms of future updates.

  15. […] time ago I wrote an article about how to add fields to products in WooCommerce. Those fields are custom product fields, and their value are post […]

  16. Can you get me any samples to add this custom field on single product page. Best regards

    1. Hi Tihomir,
      For example you could print the value of a text field with ID _my_text_field right before the Add to Cart button:

      add_action( 'woocommerce_before_add_to_cart_button', 'print_my_cf_value' );
      function print_my_cf_value() {
          global $product;
      
          echo '<p>' . esc_html( get_post_meta( $product->ID, '_my_text_field', true ) ) . '</p>';
      }
      
  17. Did you write a tutorial on how to add custom fields on variations?
    This tutorial was a life saver and now I just need a similar for variations 🙂

    1. Hi Kim,
      I did not, but my co-worker Remi did! You can find his article here: http://www.remicorson.com/woocommerce-custom-fields-for-variations/

  18. I’ve used a WooCommerce Custom Fields plug in
    n its working fine as per client’s requirement.
    When i chose the size, custom it displays 22 custom fields which are inserted
    using custom field plugin.
    now customer needs a icon in front of each field, which pops up an respective
    image for that field.
    when i went throgh the
    \wp-content\plugins\woocommerce-custom-fields\woocommerce-custom-fields.php
    i could not find any specific code for each text box or lables.
    there are 22 fields n on hovering those i need to display respective 22 images

  19. Hi, Nicola.
    I’d like to add “Handling Time” field in shipping section of product on wordpress.
    I have customized functionally, but it’s not working.
    Could you teach me about this problem?
    Looking forward from to hear good result.
    Thank you.

    1. Hi,
      What is not working? Please share your code on https://pastebin.com/

  20. Nicola, thanks for the helpful article!
    How can I add multiple custom fields?

    1. Hi Andre,
      you’re welcome!

      To add multiple fields simply write different functions, one next to the other. By funcftions I mean those to create the fields, like woocommerce_wp_text_input.

  21. Hi Nicola,
    I was wondering on your site the whole evening and then I saw the topic is really young.
    I would like to show the input text on my product images (instead of the Sale! button) so my client is able to customize those shout-outs.
    I just can’t get the hang of it, in the back-end everything works, but in the front-end I just don’t see the text. I think I tried about everything but I think I’m missing just the cope + paste code (if it’s available)…

    Please see http://185.104.29.20/~dhzdump2/winkel/vloer-afwerking/laminaat/echt-hout-woodfloor-silence-eiken-grijs/
    I should see the text ‘ moet zien’ behind the ‘hallo’ text underneath the ‘Add to basket/Stel uw vraag’ button.
    I’m using the following code to echo the text now

    add_action( ‘woocommerce_after_add_to_cart_button’, ‘print_my_cf_value’ );
    function print_my_cf_value() {
    global $product;

    echo '<p>hallo' . esc_html( get_post_meta( $product->ID, '_my_text_field', true ) ) . '</p>';

    }

    Could you please help me?

  22. Thanks. Amazing code.

    Is there a way I can display the added custom field values in the additional information tab alding with other product attributes.

  23. Hello There,
    Help me out with below issue.
    I used the following code in functions.php but I am unable to see custom fields in my variation tab of a variable product. I am using version woocommerce 3.0.7.

    Please let me know if I missed something from my side.

    // Add Variation Settings
    add_action( ‘woocommerce_product_after_variable_attributes’, ‘variation_settings_fields’, 10, 3 );
    // Save Variation Settings
    add_action( ‘woocommerce_save_product_variation’, ‘save_variation_settings_fields’, 10, 2 );
    /**
    * Create new fields for variations
    *
    */
    function variation_settings_fields( $loop, $variation_data, $variation ) {
    // Text Field
    woocommerce_wp_text_input(
    array(
    ‘id’ => ‘_text_field[‘ . $variation->ID . ‘]’,
    ‘label’ => __( ‘My Text Field’, ‘woocommerce’ ),
    ‘placeholder’ => ‘http://’,
    ‘desc_tip’ => ‘true’,
    ‘description’ => __( ‘Enter the custom value here.’, ‘woocommerce’ ),
    ‘value’ => get_post_meta( $variation->ID, ‘_text_field’, true )
    )
    );
    // Number Field
    woocommerce_wp_text_input(
    array(
    ‘id’ => ‘_number_field[‘ . $variation->ID . ‘]’,
    ‘label’ => __( ‘My Number Field’, ‘woocommerce’ ),
    ‘desc_tip’ => ‘true’,
    ‘description’ => __( ‘Enter the custom number here.’, ‘woocommerce’ ),
    ‘value’ => get_post_meta( $variation->ID, ‘_number_field’, true ),
    ‘custom_attributes’ => array(
    ‘step’ => ‘any’,
    ‘min’ => ‘0’
    )
    )
    );
    // Textarea
    woocommerce_wp_textarea_input(
    array(
    ‘id’ => ‘_textarea[‘ . $variation->ID . ‘]’,
    ‘label’ => __( ‘My Textarea’, ‘woocommerce’ ),
    ‘placeholder’ => ”,
    ‘description’ => __( ‘Enter the custom value here.’, ‘woocommerce’ ),
    ‘value’ => get_post_meta( $variation->ID, ‘_textarea’, true ),
    )
    );
    // Select
    woocommerce_wp_select(
    array(
    ‘id’ => ‘_select[‘ . $variation->ID . ‘]’,
    ‘label’ => __( ‘My Select Field’, ‘woocommerce’ ),
    ‘description’ => __( ‘Choose a value.’, ‘woocommerce’ ),
    ‘value’ => get_post_meta( $variation->ID, ‘_select’, true ),
    ‘options’ => array(
    ‘one’ => __( ‘Option 1’, ‘woocommerce’ ),
    ‘two’ => __( ‘Option 2’, ‘woocommerce’ ),
    ‘three’ => __( ‘Option 3’, ‘woocommerce’ )
    )
    )
    );
    // Checkbox
    woocommerce_wp_checkbox(
    array(
    ‘id’ => ‘_checkbox[‘ . $variation->ID . ‘]’,
    ‘label’ => __(‘My Checkbox Field’, ‘woocommerce’ ),
    ‘description’ => __( ‘Check me!’, ‘woocommerce’ ),
    ‘value’ => get_post_meta( $variation->ID, ‘_checkbox’, true ),
    )
    );
    // Hidden field
    woocommerce_wp_hidden_input(
    array(
    ‘id’ => ‘_hidden_field[‘ . $variation->ID . ‘]’,
    ‘value’ => ‘hidden_value’
    )
    );
    }
    /**
    * Save new fields for variations
    *
    */
    function save_variation_settings_fields( $post_id ) {
    // Text Field
    $text_field = $_POST[‘_text_field’][ $post_id ];
    if( ! empty( $text_field ) ) {
    update_post_meta( $post_id, ‘_text_field’, esc_attr( $text_field ) );
    }

    // Number Field
    $number_field = $_POST[‘_number_field’][ $post_id ];
    if( ! empty( $number_field ) ) {
    update_post_meta( $post_id, ‘_number_field’, esc_attr( $number_field ) );
    }
    // Textarea
    $textarea = $_POST[‘_textarea’][ $post_id ];
    if( ! empty( $textarea ) ) {
    update_post_meta( $post_id, ‘_textarea’, esc_attr( $textarea ) );
    }

    // Select
    $select = $_POST[‘_select’][ $post_id ];
    if( ! empty( $select ) ) {
    update_post_meta( $post_id, ‘_select’, esc_attr( $select ) );
    }

    // Checkbox
    $checkbox = isset( $_POST[‘_checkbox’][ $post_id ] ) ? ‘yes’ : ‘no’;
    update_post_meta( $post_id, ‘_checkbox’, $checkbox );

    // Hidden field
    $hidden = $_POST[‘_hidden_field’][ $post_id ];
    if( ! empty( $hidden ) ) {
    update_post_meta( $post_id, ‘_hidden_field’, esc_attr( $hidden ) );
    }
    }

    // Add New Variation Settings
    add_filter( ‘woocommerce_available_variation’, ‘load_variation_settings_fields’ );
    /**
    * Add custom fields for variations
    *
    */
    function load_variation_settings_fields( $variations ) {

    // duplicate the line for each field
    $variations[‘text_field’] = get_post_meta( $variations[ ‘variation_id’ ], ‘_text_field’, true );
    $variations[‘checkbox’] = get_post_meta( $variations[ ‘variation_id’ ], ‘_checkbox’, true );
    $variations[‘text_field’] = get_post_meta( $variations[ ‘variation_id’ ], ‘_number_field’, true );
    $variations[‘select’] = get_post_meta( $variations[ ‘variation_id’ ], ‘_select’, true );

    return $variations;
    }

    ============================================================================

    Added this code to variation.php under wp-plugins/plugins/woocommerce/templates/single-product/add-to-cart/

    {{{ data.variation.text_field }}}

    {{{ data.variation.checkbox }}}

    {{{ data.variation.text_field }}}

    {{{ data.variation.select }}}

    ============================================================================

    Please help me out with this issue.
    Thanks in Advance.

  24. Hi,
    Great tutorial. I managed to add custom field to my product but somehow followong your tutorial value of this field does not show up on frontend. I would really appreciate if you could see may pastebin and let me know what seems to be the issue there.
    https://pastebin.com/HPCKzy0P

    Thanks,
    J.

    1. Janek,
      Far be it for me to hijack this post, but I have been able to solve my issue with my field displaying on the front end. If your custom field is a number or starts with a number, you will need to change $product->ID to get_the_ID()
      That solved my issue, hope it does for you too.
      Ian

  25. Nicola,

    Thank you for a wonderful article. I am having an issue getting my custom field to display on the front end. I have added the save section to the functions.php file and when I refresh the product in the back end, the custom field is still populated so I am assuming that the save aspect of the code works properly. The code I am using to display it on the front end is going into the meta.php file and I am working on the version that is saved in the theme files. The code looks like this:

    <?php echo 'Dates: ‘ . esc_html(get_post_meta( $post->ID, ‘_dates_of_holiday’, true ) ) . ”;?>

    It is meant to display “Dates: ” At present it just displays “Dates:” I have tried $product->ID and $post->ID and neither work. The custom field is dates_of_holiday and I have checked that I have spelt everything correctly everywhere.

    Can you please prod me in the right direction.

    Many thanks,

    Ian

  26. Thanks so much for this post. Please i noticed something, each i save… it get updated, now i tried removing the content added to the custom field and hit SAVE CHANGED, the field didn’t go blank (to disable the display on frontend) but instead it brought back the content.

    For example i added [myshortcode] into the the custom text field and saved. it works fine as i wanted it to. Now i dont want the content [myshortcode] to show on that product again, i went bac to the backend, deleted the shortcode and SAVED CHANGED and it shortcode keep reloading itself, it wont go away if the custom text is empty

    Please help!

    1. Nevermind Nicola. i found a way to fix the little bug.

      add_action( 'woocommerce_process_product_meta', 'wc_custom_save_custom_fields' );
      function wc_custom_save_custom_fields( $post_id ) {
          if ( ! empty( $_POST['_your_custom_field'] ) ) {
              update_post_meta( $post_id, '_your_custom_field', esc_attr( $_POST['_your_custom_field'] ) );
          }
          else {
              update_post_meta( $post_id, '_your_custom_field', esc_attr( $_POST['_your_custom_field'] ) );
          }
      }
      
      1. Hi Isabel,
        I’m happy you solved this!

  27. Hi Nicola,

    I added this code to code snippets for products and would like to add it via elementor to my product template, is this possible? For example with pods I can see this in elementor, but I do not see custom fields for products.

  28. Hi Nicola, great job with creating this tutorial, well done!

    Quick question, I have added a product custom field and it does export as metadata using the build in Woocommerce product exporter.
    However when I edit the spreadsheet to fill this custom for all products, it does not import the values into the products.
    I do select to export and import the metadata as metadata, but it’s not filling the product custom field with the data I manually entered in the spreadsheet.
    It does import other fields fine.

    What am I doing wrong?

    Thank you!

    Hans

Leave a Reply

Categories

Newsletter

Receive new articles from this blog directly in your inbox!

No spam guaranteed!

Blog at WordPress.com.

%d bloggers like this: