PHPwoocommerceintermediate
WooCommerce Custom Product Tabs
Add custom tabs to WooCommerce product pages with dynamic content
Faisal Yaqoob
December 23, 2025
#woocommerce#product-tabs#ui#product-display
Code
php
1 // Add a new custom tab 2 add_filter('woocommerce_product_tabs', 'add_custom_product_tab'); 3 function add_custom_product_tab($tabs) { 4 // Specifications tab 5 $tabs['specifications'] = array( 6 'title' => __('Specifications', 'woocommerce'), 7 'priority' => 50, 8 'callback' => 'specifications_tab_content' 9 ); 10
11 // Sizing guide tab 12 $tabs['sizing_guide'] = array( 13 'title' => __('Sizing Guide', 'woocommerce'), 14 'priority' => 60, 15 'callback' => 'sizing_guide_tab_content' 16 ); 17
18 // Shipping info tab 19 $tabs['shipping_info'] = array( 20 'title' => __('Shipping Info', 'woocommerce'), 21 'priority' => 70, 22 'callback' => 'shipping_info_tab_content' 23 ); 24
25 return $tabs; 26 }
WooCommerce Custom Product Tabs
Add custom tabs to WooCommerce product pages to display additional information like specifications, sizing guides, shipping info, and more.
// Add a new custom tab
add_filter('woocommerce_product_tabs', 'add_custom_product_tab');
function add_custom_product_tab($tabs) {
// Specifications tab
$tabs['specifications'] = array(
'title' => __('Specifications', 'woocommerce'),
'priority' => 50,
'callback' => 'specifications_tab_content'
);
// Sizing guide tab
$tabs['sizing_guide'] = array(
'title' => __('Sizing Guide', 'woocommerce'),
'priority' => 60,
'callback' => 'sizing_guide_tab_content'
);
// Shipping info tab
$tabs['shipping_info'] = array(
'title' => __('Shipping Info', 'woocommerce'),
'priority' => 70,
'callback' => 'shipping_info_tab_content'
);
return $tabs;
}
Tab Content Callbacks
// Specifications tab content
function specifications_tab_content() {
global $product;
$specifications = get_post_meta($product->get_id(), '_product_specifications', true);
echo '<h2>' . __('Specifications', 'woocommerce') . '</h2>';
if ($specifications) {
echo '<div class="specifications-content">' . wp_kses_post($specifications) . '</div>';
} else {
echo '<p>' . __('No specifications available.', 'woocommerce') . '</p>';
}
}
// Sizing guide tab content
function sizing_guide_tab_content() {
global $product;
// Check for product-specific sizing guide
$sizing_guide = get_post_meta($product->get_id(), '_sizing_guide', true);
// Fall back to category-specific guide
if (empty($sizing_guide)) {
$categories = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'ids'));
if (!empty($categories)) {
$sizing_guide = get_term_meta($categories[0], 'category_sizing_guide', true);
}
}
// Fall back to global sizing guide
if (empty($sizing_guide)) {
$sizing_guide = get_option('global_sizing_guide');
}
echo '<h2>' . __('Sizing Guide', 'woocommerce') . '</h2>';
if ($sizing_guide) {
echo '<div class="sizing-guide-content">' . wp_kses_post($sizing_guide) . '</div>';
} else {
echo '<p>' . __('Sizing information coming soon.', 'woocommerce') . '</p>';
}
}
// Shipping info tab content
function shipping_info_tab_content() {
echo '<h2>' . __('Shipping Information', 'woocommerce') . '</h2>';
echo '<div class="shipping-info-content">';
echo '<p>' . __('We offer the following shipping options:', 'woocommerce') . '</p>';
echo '<ul>';
echo '<li><strong>Standard Shipping:</strong> 5-7 business days</li>';
echo '<li><strong>Express Shipping:</strong> 2-3 business days</li>';
echo '<li><strong>Overnight Shipping:</strong> 1 business day</li>';
echo '</ul>';
echo '<p>' . __('All orders are processed within 24 hours.', 'woocommerce') . '</p>';
echo '</div>';
}
Add Custom Fields for Tab Content
// Add custom fields to product admin for tab content
add_action('woocommerce_product_options_general_product_data', 'add_product_tab_fields');
function add_product_tab_fields() {
global $post;
echo '<div class="options_group">';
// Specifications field
woocommerce_wp_textarea_input(array(
'id' => '_product_specifications',
'label' => __('Specifications', 'woocommerce'),
'placeholder' => __('Enter product specifications', 'woocommerce'),
'desc_tip' => true,
'description' => __('Content for the specifications tab. HTML allowed.', 'woocommerce'),
));
// Sizing guide field
woocommerce_wp_textarea_input(array(
'id' => '_sizing_guide',
'label' => __('Sizing Guide', 'woocommerce'),
'placeholder' => __('Enter sizing guide', 'woocommerce'),
'desc_tip' => true,
'description' => __('Product-specific sizing guide. Leave empty to use category or global guide.', 'woocommerce'),
));
// Custom tab title field
woocommerce_wp_text_input(array(
'id' => '_custom_tab_title',
'label' => __('Custom Tab Title', 'woocommerce'),
'placeholder' => __('e.g., Care Instructions', 'woocommerce'),
'desc_tip' => true,
'description' => __('Optional custom tab title.', 'woocommerce'),
));
// Custom tab content field
woocommerce_wp_textarea_input(array(
'id' => '_custom_tab_content',
'label' => __('Custom Tab Content', 'woocommerce'),
'placeholder' => __('Enter custom tab content', 'woocommerce'),
'desc_tip' => true,
'description' => __('Content for custom tab. HTML allowed.', 'woocommerce'),
));
echo '</div>';
}
// Save custom tab fields
add_action('woocommerce_process_product_meta', 'save_product_tab_fields');
function save_product_tab_fields($post_id) {
$specifications = isset($_POST['_product_specifications']) ?
wp_kses_post($_POST['_product_specifications']) : '';
update_post_meta($post_id, '_product_specifications', $specifications);
$sizing_guide = isset($_POST['_sizing_guide']) ?
wp_kses_post($_POST['_sizing_guide']) : '';
update_post_meta($post_id, '_sizing_guide', $sizing_guide);
$custom_tab_title = isset($_POST['_custom_tab_title']) ?
sanitize_text_field($_POST['_custom_tab_title']) : '';
update_post_meta($post_id, '_custom_tab_title', $custom_tab_title);
$custom_tab_content = isset($_POST['_custom_tab_content']) ?
wp_kses_post($_POST['_custom_tab_content']) : '';
update_post_meta($post_id, '_custom_tab_content', $custom_tab_content);
}
Dynamic Custom Tab Based on Product Meta
// Add dynamic custom tab if content exists
add_filter('woocommerce_product_tabs', 'add_dynamic_custom_tab', 98);
function add_dynamic_custom_tab($tabs) {
global $product;
$custom_tab_title = get_post_meta($product->get_id(), '_custom_tab_title', true);
$custom_tab_content = get_post_meta($product->get_id(), '_custom_tab_content', true);
// Only add tab if both title and content exist
if ($custom_tab_title && $custom_tab_content) {
$tabs['custom_dynamic'] = array(
'title' => $custom_tab_title,
'priority' => 80,
'callback' => 'dynamic_custom_tab_content'
);
}
return $tabs;
}
function dynamic_custom_tab_content() {
global $product;
$custom_tab_title = get_post_meta($product->get_id(), '_custom_tab_title', true);
$custom_tab_content = get_post_meta($product->get_id(), '_custom_tab_content', true);
echo '<h2>' . esc_html($custom_tab_title) . '</h2>';
echo '<div class="custom-tab-content">' . wp_kses_post($custom_tab_content) . '</div>';
}
Modify or Remove Existing Tabs
// Rename, reorder, or remove default tabs
add_filter('woocommerce_product_tabs', 'customize_default_tabs', 98);
function customize_default_tabs($tabs) {
// Rename the description tab
$tabs['description']['title'] = __('Product Details', 'woocommerce');
// Rename the reviews tab
if (isset($tabs['reviews'])) {
$tabs['reviews']['title'] = __('Customer Reviews', 'woocommerce');
}
// Rename additional information tab
if (isset($tabs['additional_information'])) {
$tabs['additional_information']['title'] = __('Attributes', 'woocommerce');
}
// Change priority (lower number = higher priority)
$tabs['description']['priority'] = 5;
if (isset($tabs['reviews'])) {
$tabs['reviews']['priority'] = 90;
}
// Remove additional information tab
// unset($tabs['additional_information']);
return $tabs;
}
Conditional Tabs
// Add tabs conditionally based on product attributes
add_filter('woocommerce_product_tabs', 'add_conditional_tabs', 98);
function add_conditional_tabs($tabs) {
global $product;
// Add warranty tab only for specific categories
$categories = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'slugs'));
if (in_array('electronics', $categories) || in_array('appliances', $categories)) {
$tabs['warranty'] = array(
'title' => __('Warranty', 'woocommerce'),
'priority' => 65,
'callback' => 'warranty_tab_content'
);
}
// Add video tab only if product has video
$video_url = get_post_meta($product->get_id(), '_product_video_url', true);
if ($video_url) {
$tabs['video'] = array(
'title' => __('Video', 'woocommerce'),
'priority' => 55,
'callback' => 'video_tab_content'
);
}
return $tabs;
}
function warranty_tab_content() {
echo '<h2>' . __('Warranty Information', 'woocommerce') . '</h2>';
echo '<div class="warranty-content">';
echo '<p>' . __('This product comes with a 1-year manufacturer warranty.', 'woocommerce') . '</p>';
echo '<p>' . __('For warranty claims, please contact our customer service.', 'woocommerce') . '</p>';
echo '</div>';
}
function video_tab_content() {
global $product;
$video_url = get_post_meta($product->get_id(), '_product_video_url', true);
echo '<h2>' . __('Product Video', 'woocommerce') . '</h2>';
echo '<div class="video-content">';
if ($video_url) {
// If it's a YouTube or Vimeo URL, embed it
if (preg_match('/youtube\.com|youtu\.be|vimeo\.com/', $video_url)) {
echo wp_oembed_get($video_url);
} else {
// Otherwise show video tag
echo '<video controls width="100%">';
echo '<source src="' . esc_url($video_url) . '" type="video/mp4">';
echo __('Your browser does not support the video tag.', 'woocommerce');
echo '</video>';
}
}
echo '</div>';
}
Tab with Accordion Content
// Add FAQ tab with accordion
add_filter('woocommerce_product_tabs', 'add_faq_tab');
function add_faq_tab($tabs) {
$tabs['faq'] = array(
'title' => __('FAQ', 'woocommerce'),
'priority' => 75,
'callback' => 'faq_tab_content'
);
return $tabs;
}
function faq_tab_content() {
global $product;
echo '<h2>' . __('Frequently Asked Questions', 'woocommerce') . '</h2>';
echo '<div class="faq-accordion">';
$faqs = array(
array(
'question' => __('What is the return policy?', 'woocommerce'),
'answer' => __('You can return products within 30 days of purchase.', 'woocommerce')
),
array(
'question' => __('Is this product in stock?', 'woocommerce'),
'answer' => $product->is_in_stock() ? __('Yes, in stock.', 'woocommerce') : __('Currently out of stock.', 'woocommerce')
),
array(
'question' => __('Do you offer international shipping?', 'woocommerce'),
'answer' => __('Yes, we ship to most countries worldwide.', 'woocommerce')
),
);
foreach ($faqs as $index => $faq) {
echo '<div class="faq-item">';
echo '<button class="faq-question" data-index="' . $index . '">';
echo esc_html($faq['question']);
echo '<span class="toggle">+</span>';
echo '</button>';
echo '<div class="faq-answer" id="faq-' . $index . '" style="display: none;">';
echo '<p>' . esc_html($faq['answer']) . '</p>';
echo '</div>';
echo '</div>';
}
echo '</div>';
}
JavaScript for FAQ Accordion
// Add to your theme's JavaScript file
jQuery(document).ready(function($) {
$('.faq-question').on('click', function(e) {
e.preventDefault();
var index = $(this).data('index');
var answer = $('#faq-' + index);
var toggle = $(this).find('.toggle');
answer.slideToggle(300);
if (toggle.text() === '+') {
toggle.text('-');
} else {
toggle.text('+');
}
});
});
Styling
/* Product tabs styling */
.woocommerce-tabs ul.tabs {
margin: 0;
padding: 0;
list-style: none;
border-bottom: 2px solid #e0e0e0;
}
.woocommerce-tabs ul.tabs li {
display: inline-block;
margin: 0 5px -2px 0;
}
.woocommerce-tabs ul.tabs li a {
padding: 12px 20px;
display: block;
text-decoration: none;
border: 1px solid transparent;
border-bottom: 0;
background: #f5f5f5;
color: #666;
transition: all 0.3s ease;
}
.woocommerce-tabs ul.tabs li a:hover {
background: #fff;
color: #333;
}
.woocommerce-tabs ul.tabs li.active a {
background: #fff;
border-color: #e0e0e0;
color: #0073aa;
font-weight: 600;
}
.woocommerce-tabs .panel {
padding: 30px 20px;
background: #fff;
border: 1px solid #e0e0e0;
border-top: 0;
}
/* FAQ accordion styling */
.faq-accordion {
margin: 20px 0;
}
.faq-item {
margin-bottom: 10px;
border: 1px solid #e0e0e0;
border-radius: 4px;
}
.faq-question {
width: 100%;
padding: 15px 20px;
text-align: left;
background: #f9f9f9;
border: none;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
transition: background 0.3s ease;
}
.faq-question:hover {
background: #f0f0f0;
}
.faq-question .toggle {
font-size: 20px;
font-weight: bold;
}
.faq-answer {
padding: 15px 20px;
background: #fff;
}
Features
- Multiple Tab Types: Specifications, sizing guides, shipping info, FAQs, videos
- Dynamic Content: Tabs from custom fields or global settings
- Conditional Display: Show tabs based on product attributes or categories
- Accordion Support: Interactive FAQ accordions within tabs
- Flexible Priority: Control tab order easily
- Custom Fields: Admin interface for tab content
- HTML Support: Rich content with HTML formatting
- Video Embedding: Support for YouTube, Vimeo, and direct video files
- Fallback System: Product-specific, category-specific, or global content
- Fully Styled: Professional CSS for tabs and accordions
Dependencies
- WooCommerce
Related Snippets
WooCommerce Product Badges and Labels
Add custom badges and labels to WooCommerce products (Sale, New, Featured, Custom)
PHPwoocommerceintermediate
phpPreview
// Display product badges on product listings and single product pages
add_action('woocommerce_before_shop_loop_item_title', 'display_product_badges', 10);
add_action('woocommerce_before_single_product_summary', 'display_product_badges', 10);
...#woocommerce#badges#labels+2
12/23/2025
View
WooCommerce Related Products Customization
Customize WooCommerce related products display, algorithm, and layout
PHPwoocommerceintermediate
phpPreview
// Change number of related products displayed
add_filter('woocommerce_output_related_products_args', 'custom_related_products_args');
function custom_related_products_args($args) {
$args['posts_per_page'] = 8; // Display 8 products
...#woocommerce#related-products#upsell+2
12/23/2025
View
WooCommerce Bulk Discounts and Quantity Pricing
Implement bulk discounts, quantity-based pricing, and tiered discounts in WooCommerce
PHPwoocommerceadvanced
phpPreview
// Apply bulk discount based on quantity
add_action('woocommerce_before_calculate_totals', 'apply_bulk_discount');
function apply_bulk_discount($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
...#woocommerce#pricing#discounts+2
12/23/2025
View