I have this function (woocommerce) and it changes the product descriptions tab titles from the defaukt....

add_filter( 'woocommerce_product_tabs', 'wc_change_product_description_tab_title', 10, 1 );
function wc_change_product_description_tab_title( $tabs ) {
  global $post;
    if ( isset( $tabs['description']['title'] ) )
    $tabs['description']['title'] = '★ Product Information'."\n".' ★ Ingredients'."\n".' ★ Sizes';
    return $tabs;
}

The problem is, that it does not separate new titlles like this:

★ Product Information
★ Ingredients
★ Sizes

I've tried \n and \r and <br> and char(13) to get them to stack......
But Im running into a dead-end. Is there a way to do this other than ( ."\n". ) ? and even that does not work :(

Dani AI

Generated

Short answer: the title text was being escaped (so <br> showed as literal text) while literal newline characters can still exist in the HTML source but are collapsed by default by the browser. That’s why was right that HTML was being stripped/escaped, and why ’s final fix (preserving whitespace in the tab heading) made the \n show as line breaks.

Why this happens (concise): WordPress/WooCommerce output for tab titles is sanitized to prevent HTML injection, so injected tags are printed as entities. A \n is just a character in the text node — browsers normally fold it into regular whitespace unless the element’s whitespace handling is changed, or the text is transformed into real HTML (<br>).

Practical options you can use (pick one):

  • Easiest — keep the newline approach and ensure the tab heading preserves whitespace. Apply a whitespace-preserving rule to the tab header element so the \n becomes visible as a break (this is what ended up doing). This is safest and requires no template edits.

  • DOM transformation — run a small script after the page loads that replaces newline characters with real line breaks. Example:

    document.addEventListener('DOMContentLoaded', function(){
      document.querySelectorAll('.woocommerce-tabs .tabs a').forEach(function(el){
        el.innerHTML = el.textContent.replace(/\n/g, '<br>');
      });
    });

    This is non-invasive and reversible, but be cautious: using innerHTML will render any HTML present in the title, so only do this if titles are trusted.

  • Template override (server-side) — for a permanent, “correct” solution you can override the WooCommerce tabs template in your theme and output the title using a safe sanitizer that allows <br> only. For example, replace the title echo with a sanitization call that permits br tags. This avoids client-side hacks but requires maintaining the override when WooCommerce updates. Always sanitize allowed tags (e.g., wp_kses) to avoid XSS.

Recommendation: for a quick, low-risk fix use the whitespace-preserving CSS approach. If you need semantically real markup or accessibility control, use the template override with careful sanitization.

Recommended Answers

All 3 Replies

It's likely that HTML is being stripped from the description as it is being rendered.
You may need to remove the filter as described here:
Woocommerce docs

Thanks for the input but that didn't work... it just displayed the html as a string (like) <br>

Well here's an update!

  • added a css white-space: pre; /* or pre-wrap */class to the tabs

and the "/n" worked....

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.