Skip to main content
WordPress made easy with the drag & drop Total WordPress Theme!Learn More

How to Make a WordPress Theme WooCommerce Compatible

Last updated on: November 29, 2023

So you want to add a shop to your theme – awesome! WooCommerce is a great choice. This guide will show you how to integrate the plugin so that your theme is WooCommerce ready.

Now, technically all themes are “WooCommerce compatible/ready” because it’s a plugin and in theory any plugin should work with any WordPress theme. However, as a theme developer you may want to tweak the way the plugin works to better integrate with your theme or provide additional settings to your users that are not available in the plugin by default (such as altering the number of columns on the shop).

Below you will find some helpful snippets that you can use to provide “better” support for WooCommerce in your theme and/or to alter things for your specific design.

Important: Many of the snippets below use functions available in WooCommerce only. So make sure these snippets aren’t just dumped at the bottom of your functions.php file in a theme created for distribution. If you are going to share your theme with others or sell it be sure to place the snippets in their own file loaded only when the WooCommerce plugin is active.

Check if WooCommerce is Enabled

In my themes I like to define a custom constant that can be used to check if WooCommerce is enabled this way I can include files or run functions only when WooCommerce is active (see important message above if you haven’t yet).

define( 'WPEXPLORER_WOOCOMMERCE_ACTIVE', class_exists( 'WooCommerce' ) );

Now with the constant in place I can use it in my conditional statement as follows:

    // Do something...
    // Such as including a new file with all your Woo edits.

Declare WooCommerce Support

This is the first and most important piece of code to add to your theme which “enables” WooCommerce support and prevents the warnings from the plugin telling the end user that the theme is not compatible.

add_action( 'after_setup_theme', function() {
    add_theme_support( 'woocommerce' );
} );

Notice how this code is added to the “after_setup_theme” hook? Most likely you are already hooking into this somewhere else in your theme to declare theme support for core functions. If this is the case, simply add the part that reads add_theme_support( 'woocommerce' ); along with your other declarations instead of adding a new action hook.

Remove WooCommerce CSS

In order to style WooCommerce to match your theme you can add custom CSS to your site that overrides the plugin styles. However, if you want complete control and to slim down your site I recommend removing all the plugin CSS and then adding your own to style things.

Use the following code to remove all WooCommerce CSS:

add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );

Use the following code to remove only certain WooCommerce CSS:

function wpexplorer_remove_woo_styles( $styles ) {
    unset( $styles['woocommerce-general'] );
    unset( $styles['woocommerce-layout'] );
    unset( $styles['woocommerce-smallscreen'] );
    return $styles;
add_filter( 'woocommerce_enqueue_styles', 'wpexplorer_remove_woo_styles' );

In WooCommerce 3.0 they introduced new product gallery, zoom and lightbox functionality. These must all be enabled via “add_theme_support” if you want to make use of them in your theme.

add_action( 'after_setup_theme', function() {
    add_theme_support( 'wc-product-gallery-slider' );
    add_theme_support( 'wc-product-gallery-zoom' );
    add_theme_support( 'wc-product-gallery-lightbox' );
} );

Remove The Shop Title

A lot of themes already have functions to display archive titles so this code removes the extra title from WooCommerce which is better than hiding it via CSS (which is what some themes do).

add_filter( 'woocommerce_show_page_title', '__return_false' );

Change the Shop Archive Title

If your theme is using the archive_title() or get_archive_title() functions to display the title for your archives you can easily tweak it via a filter to grab the name of your product page instead for the shop archive title.

function wpexplorer_woo_archive_title( $title ) {
    if ( is_shop() && $shop_id = wc_get_page_id( 'shop' ) ) {
        $title = get_the_title( $shop_id );
    return $title;
add_filter( 'get_the_archive_title', 'wpexplorer_woo_archive_title' );

Change How Many Products Display on the Shop Pages

You can use the following code to change how many products display per page on the shop and product archives (categories and tags).

function wpexplorer_woo_posts_per_page( $cols ) {
    return 12;
add_filter( 'loop_shop_per_page', 'wpexplorer_woo_posts_per_page' );

Change the Number of Product Columns on the Shop Pages

I don’t understand why WooCommerce works in this way but you can’t just alter the ‘loop_shop_columns’ filter, you must also add the unique classes to the body tag in order for the columns to work. While the Woo shortcodes have a div wrapper with the correct classes the shop pages do not, that’s why we need two functions.

// Alter shop columns.
function wpexplorer_woo_shop_columns( $columns ) {
	return 4;
add_filter( 'loop_shop_columns', 'wpexplorer_woo_shop_columns' );

// Add correct body class for shop columns (this fix may no longer be needed)
function wpexplorer_woo_shop_columns_body_class( $classes ) {
	if ( is_shop() || is_product_category() || is_product_tag() ) {
		$classes[] = 'columns-4';
	return $classes;
add_filter( 'body_class', 'wpexplorer_woo_shop_columns_body_class' );

Important: It’s possible WooCommerce has already fixed how the columns work so you may not need the second part of the snippet above. You may want to try using the first function only and if it doesn’t work as expected then added the second function.

Change the Next & Previous Pagination Arrows

This snippet will allow you to tweak the pagination arrows on the shop to match those in your theme.

function wpexplorer_woo_pagination_args( $args ) {
    $args['prev_text'] = '<i class="fa fa-angle-left"></i>';
    $args['next_text'] = '<i class="fa fa-angle-right"></i>';
    return $args;
add_filter( 'woocommerce_pagination_args', 'wpexplorer_woo_pagination_args' );

Change the OnSale Badge Text

Especially useful on sites using a different language or to remove the exclamation mark which I am not a huge fan of.

function wpexplorer_woo_sale_flash() {
	return '<span class="onsale">' . esc_html__( 'Sale', 'text_domain' ) . '</span>';
add_filter( 'woocommerce_sale_flash', 'wpexplorer_woo_sale_flash' );

You may want to change the number of columns for the single product gallery thumbnails depending on your layout and this function will do just that.

function wpexplorer_woo_product_thumbnails_columns() {
    return 4;
add_action( 'woocommerce_product_thumbnails_columns', 'wpexplorer_woo_product_thumbnails_columns' );

The following code can be used to alter the number of products displayed for related products on the single product page.

function wpexplorer_woo_related_posts_per_page( $args ) {
    $args['posts_per_page'] = 4;
    return $args;
add_filter( 'woocommerce_output_related_products_args', 'wpexplorer_woo_related_posts_per_page' );

Just like the shop if you want to properly alter the number of columns for related and up-sell products on the single product pages you must filter the columns and also alter the body classes accordingly.

// Filter up-sells columns
function wpexplorer_woo_single_loops_columns( $columns ) {
	return 4;
add_filter( 'woocommerce_up_sells_columns', 'wpexplorer_woo_single_loops_columns' );

// Filter related args
function wpexplorer_woo_related_columns( $args ) {
	$args['columns'] = 4;
	return $args;
add_filter( 'woocommerce_output_related_products_args', 'wpexplorer_woo_related_columns', 10 );

// Filter body classes to add column class
function wpexplorer_woo_single_loops_columns_body_class( $classes ) {
	if ( is_singular( 'product' ) ) {
		$classes[] = 'columns-4';
	return $classes;
add_filter( 'body_class', 'wpexplorer_woo_single_loops_columns_body_class' );

Something that’s really popular is to show how many products are currently in your cart via an icon in your header menu. The following snippet will add a WooCommerce cart item to your menu that will update automatically whenever products are added or removed from the cart.

  • Make sure to update where it says “main_menu” to be the name of the menu location you want to target.
  • Also this snippet will display a cart icon and the cost of the items in the cart, if you rather display the count (number of products) simply change where it says wp_kses_post( $cart_total ) to instead say wp_kses_post( $cart_count ).
// Add the cart link to menu
function wpexplorer_add_menu_cart_item_to_menus( $items, $args ) {

    // Make sure your change 'main_menu' to your Menu location !!!!
    if ( 'main_menu' === $args->theme_location ) {
        $css_class = 'menu-item menu-item-type-cart menu-item-type-woocommerce-cart';
        if ( function_exists( 'is_cart' ) && is_cart() ) {
            $css_class .= ' current-menu-item';
        $items .= '<li class="' . esc_attr( $css_class ) . '">';
            $items .= wpexplorer_menu_cart_item();
        $items .= '</li>';

    return $items;
add_filter( 'wp_nav_menu_items', 'wpexplorer_add_menu_cart_item_to_menus', 10, 2 );

// Function returns the main menu cart link
function wpexplorer_menu_cart_item() {
    $output = '';

    $cart_count = absint( WC()->cart->cart_contents_count );
    $cart_total = WC()->cart->get_cart_total();

    if ( $cart_count ) {
        $url = wc_get_cart_url();
    } else {
        $url = wc_get_page_permalink( 'shop' );

    $icon = '<svg xmlns="" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15.55 13c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.37-.66-.11-1.48-.87-1.48H5.21l-.94-2H1v2h2l3.6 7.59-1.35 2.44C4.52 15.37 5.48 17 7 17h12v-2H7l1.1-2h7.45zM6.16 6h12.15l-2.76 5H8.53L6.16 6zM7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/></svg>';

    $output .= '<a href="'. esc_url( $url ) .'" class="menu-cart-total">';

        $output .= $icon . wp_kses_post( $cart_total );

    $output .= '</a>';

    return $output;

// Update cart link with AJAX
function wpexplorer_main_menu_cart_link_fragments( $fragments ) {
    $fragments['.menu-cart-total'] = wpexplorer_menu_cart_item();
    return $fragments;
add_filter( 'add_to_cart_fragments', 'wpexplorer_main_menu_cart_link_fragments' );

Important: The code above must not be wrapped in an is_admin() conditional because they rely on AJAX. So if this code isn’t working make sure you haven’t conditionally loaded this code for the front-end only.

Making your Theme WooCommerce Ready is Easy!

WooCommerce will work with any theme by default but adding some extra support for the plugin so that it better fits your theme is very easy to do.

This is a very simple guide with general tweaks you may want to make, we will be creating dedicated guides for more complex integrations or WooCommerce customizations. If you have any suggestions for these future guides let us know!


  1. Ankur Gupta

    Thanks for sharing. this post is very helpful for my new startup website.

  2. sameeuor

    Thank you very much for your article. You saved my lot times.

  3. Appstrape Solution

    Hello Thanks for sharing .
    I did all steps but on product page It is not showing any product

    Fatal error: Call to a member function is_on_sale() on null in wp-content\plugins\woocommerce\templates\single-product\sale-flash.php on line 29

    • AJ Clarke

      None of the snippets above would cause the issue sounds like a core plugin bug you should report on the WooCommerce github page. Based on the error the global $product variable is returning null (which it never should). But it could also be a theme or plugin issue, so before reporting any bug I would first recommend you try switching themes and disabling active plugins to test.

  4. Josh

    So, I am decent enough at piecing together HTML/CSS and tweaking the PHP files in wordpress but there is a lot of code here to deal with.

    Could I just dump each section of code here into a new php document then simply include that file in my main theme? Or I read something about using on woocommerce pages only, so would I only do an include with some sort of IF statement over the URL or another variable to make sure its loaded only when woocommerce is loaded?

    • AJ Clarke


      Yes you could just dump each section into a new php document and use require_once to include it via the functions.php file. All the filters used in the code target WooCommerce exclusively so you don’t need to use any if/else statements.The thing is you don’t NEED all of this, technically every theme out there will work with WooCommerce these are added functions you can use to provider better support for the plugin so read through each description so you are only adding the snippets you want/need.

  5. Waqas

    Thanks for the article. Helped me a lot.

  6. Mark

    Thanks for the info, I found this very helpful.

    I appreciate this is several years old but just on the off chance you still monitor this ….

    I have a WordPress Landing page I use and like and now want to add a few products on the home page and a Woocommerce side to this landing page site.

    I have another theme that has woocommerce built in and that woocommerce side of the theme looks and works nicely, nice layout and display features etc etc.

    My question is – is it possible to take that woocommerce code / files out of the main theme, and add that in to the Landing page by simply copying those files over, and then adding much of what you have presented above ?

    (reposting because I didn’t subscribe to the previous one)

    • AJ Clarke

      Hi Mark,

      This is Aj the author of the post. I know it’s been forever so you will likely never see this, but I figured I would approve the comment and reply incase anyone else is reading the thread. Anyway, what you are asking might be possible but depending on how the theme is coded this may require a lot of time to move the code over and get it to work as it will probably need to be modified as well.

      My recommendation would of course be to use the same theme for both sites if you like the look. Now, if you don’t want to use the same theme for your landing page site you could consider changing your landing page site to work as a multisite installation. This way you can add the shop as it’s own sub-site and install the theme there so that your main landing page can use it’s own theme and the shop can then use the other theme.

      As an added plus, you can then have your shop located in it’s own sub-domain such as and keep things separate which is nice for security, SEO and general management.

  7. Balazs

    Hello, I am having some trouble with my theme not properly working together with Woocommerce, and not being able to get it done with their support I decided to take the matter in my hands.

    I read through the above code and many of these would be helpful additions – can I dump them at the end of the functions.php file of the child theme? I have the Woocommerce plugin installed already.

    Additionally, my biggest problem at the moment is that the checkout page looks like this. Any suggestions on how I could fix that?

    • AJ Clarke

      Yes you can add the snippets to your child theme functions.php file. Now, if the checkout page or any page isn’t rendering correctly most likely the theme has some incompatibility problems and none of these snippets would help fix that. If the theme developer is not willing to update or support their theme, I would probably not recommend using that theme as I wouldn’t trust it and switch to a well supported theme such as Total.

  8. David Praise


    Where exactly I’m I suppose to place these snippets of code you’ve provided above?

    I will really appreciate your feedback. Thank you.

    • AJ Clarke

      You can place these code snippets inside your theme’s functions.php file. Although I recommend creating a new file for your WooCommerce integration and then loading this file via the functions.php file using the require_once PHP function. This way all your WooCommerce related code is neatly organized in it’s own file.

  9. Michael


    first: thank you a lot for your article!

    I am currently debugging my shop site and i am stucking with a problem since days:
    I created a variable product.
    But if i choose the attributes for the variables in the shop the frontend did not recognise this and doesn’t refresh the price nor the picture for the selected article (variant).
    If i choose an other theme then the variable product works fine.

    Can you give me a hint where i can start my search to fix this problem?

    Thanks in advance!

    • AJ Clarke

      Did you already try de-activating plugins? My guess is that most likely a 3rd party plugin is causing the error if not then you will probably want to check your theme to make sure it’s not overriding any of the plugin template files (these would be inside a woocommerce folder in the theme) and last check any custom code in the functions.php file or loaded via the functions.php file.

      Now, if you are working with a theme created by someone else you should contact the theme developer for support.

  10. David

    Thank you, this is the article I was looking for. Btw may I know what you use for your great and fast website? I’m also planning to create a simple website for my business, but I need a domain and hosting recommendation. I hear [edit] has a good reputation for that. Can you recommend them or are there any alternatives?

    • Kyla

      We use dedicated WordPress hosting from WP Engine, though you can checkout out the linked post to see other hosting options we’d recommend.

  11. chris

    How do we know if these articles are still relevant in 2023, since there are no dates published?

    • AJ Clarke

      This is AJ the author. I actually recently updated this article so it’s definitely relevant. I’m working on a complete redesign of the site and the dates will be displayed. I’ll tweak the current design a bit to show the last updated date. Good idea! Thank you for bringing this to my attention.

Leave a Reply

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

Learn how your comment data is processed by viewing our privacy policy here.