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.

57 replies
  1. Amit Ramani
    Amit Ramani says:

    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?

    Reply
  2. Goldy rajurkar
    Goldy rajurkar says:

    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

    Reply
  3. Goldy rajurkar
    Goldy rajurkar says:

    /*
    * 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.

    Reply
  4. Dan
    Dan says:

    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

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
  5. way2web
    way2web says:

    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

    Reply
    • Frank
      Frank says:

      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.

      Reply
      • Nicola Mustone
        Nicola Mustone says:

        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" />
        
        Reply
        • Nicola Mustone
          Nicola Mustone says:

          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.

  6. Abe
    Abe says:

    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

    Reply
  7. Viktoria
    Viktoria says:

    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!

    ‘;
    }

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
  8. ohannis
    ohannis says:

    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’] ) );
    }
    }

    Reply
      • ohannis
        ohannis says:

        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 ?

        Reply
        • Nicola Mustone
          Nicola Mustone says:

          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.

        • ohannis
          ohannis says:

          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.

  9. Gabriel
    Gabriel says:

    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??

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
    • Nicola Mustone
      Nicola Mustone says:

      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>';
      }
      
      Reply
  10. Kim
    Kim says:

    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 🙂

    Reply
  11. AGasthya
    AGasthya says:

    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

    Reply
  12. Donghai
    Donghai says:

    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.

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
  13. Floor
    Floor says:

    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?

    Reply
  14. DJ
    DJ says:

    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.

    Reply
  15. Jack Dowson
    Jack Dowson says:

    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.

    Reply
  16. Janek
    Janek says:

    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.

    Reply
    • Ian
      Ian says:

      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

      Reply
  17. Ian
    Ian says:

    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

    Reply
  18. Isabel
    Isabel says:

    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!

    Reply
    • Isabel
      Isabel says:

      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'] ) );
          }
      }
      
      Reply
  19. Amelia
    Amelia says:

    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.

    Reply
  20. upperfieldent
    upperfieldent says:

    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

    Reply

Trackbacks & Pingbacks

  1. […] 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 […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply