Practical WordPress guide

Change Sale Badge Text for WooCommerce: safe setup, failure cases, and rollback

A plain-language guide for nontechnical site owners. It separates what the parent plugin really knows from what a helper plugin should never guess.

Reviewed July 17, 2026Official-source links includedNo invented performance claims

Direct answer

To change the words in WooCommerce's native Sale badge safely, use the woocommerce_sale_flash filter, preserve the incoming badge when the setting is empty or the product context is uncertain, and replace only the escaped visible text. Do not calculate a discount, change regular or sale prices, edit sale dates, copy a template, or hide unknown markup with CSS.

StoreFixKit's Change Sale Badge Text for WooCommerce follows that narrow boundary. Free supplies one store-wide label. Pro adds category and individual product wording while the complete Free result remains independent of billing.

A sale badge is not the sale itself

A WooCommerce sale has several separate parts:

  • the product's regular price;
  • the product's sale price;
  • optional sale start and end dates;
  • WooCommerce's decision that the product is currently on sale;
  • the visible badge HTML and words;
  • the product, cart, checkout, and order behavior.

A wording plugin should own only the visible words.

WooCommerce's current native sale-flash.php template first checks whether the product is on sale and then applies woocommerce_sale_flash. That order matters. The plugin does not need to inspect a price or reproduce WooCommerce's sale calculation; it receives the result after WooCommerce has made the decision.

If WooCommerce supplies no native badge, a text-only plugin should render nothing. Creating a new badge would be a different product with different placement, design, accessibility, and compatibility responsibilities.

Why a one-field problem becomes difficult for beginners

A merchant asking how to change a two-word badge is often given one of four answers:

  1. edit PHP in a child theme;
  2. replace a translation string;
  3. hide the old text and add new text with CSS;
  4. install a complete badge-design suite.

The pain is visible in public support threads. One merchant was told the incumbent badge text was not editable and that another plugin was needed. Another said they spent two days trying four plugins and two code snippets. A third found that a classic-page change did not carry into a Handpicked Products block.

These reports do not prove that every store has the same defect. They show that output ownership is the real question: which component actually printed the badge?

Keep the input bounded

A sale label rarely needs more than a short phrase:

  • Special offer
  • Clearance
  • Limited deal
  • Member price
  • Seasonal sale

Plain text limited to 40 characters is enough for this job. HTML, icons, shortcodes, formulas, JavaScript, and dynamic tokens would turn one field into a content and pricing system.

The safe transformation is:

  1. receive WooCommerce's original badge HTML;
  2. confirm the setting is enabled and the label is valid;
  3. confirm the current product is valid, published, and on sale;
  4. rebuild the same native badge wrapper with escaped text;
  5. otherwise return the original HTML exactly.

That last step is the failure boundary. Uncertainty should preserve the store's previous result.

Do not calculate a percentage in a wording plugin

Percentage badges look related, but they are a different technical job. A percentage implementation must decide how to handle:

  • simple products;
  • variable products with several regular and sale prices;
  • tax display settings;
  • scheduled sales;
  • rounded prices;
  • extensions that alter price HTML;
  • cached product collections.

Once a plugin promises a calculated percentage, it owns price interpretation. A one-field text plugin should not quietly grow into that responsibility.

Test the sale state, not only the screenshot

Use a small matrix before launch:

Product case Expected result
Published simple product with an active sale Custom words appear inside the native badge
Variable product with discounted variation WooCommerce still decides whether a badge exists
Future sale No new StoreFixKit badge is invented
Expired sale No stale StoreFixKit badge remains
Regular-price product No badge is created
Empty label or disabled setting Original WooCommerce badge returns

Then confirm that regular price, sale price, sale dates, stock, quantity, Add to cart, cart totals, checkout totals, and a disposable order are unchanged.

Classic templates and product blocks are different owners

WooCommerce's classic template exposes the documented PHP filter. A product block, theme, builder, or quick-view panel may:

  • apply the same filter;
  • render a server-side block with different code;
  • fetch data through an API;
  • print its own badge component;
  • replace markup after page load.

Only a surface that applies the native sale-flash filter is automatically inside this plugin's contract.

Do not force compatibility by searching every .onsale element in the browser. That approach can change another plugin's badge, run after the customer sees the old text, miss accessible text, or break after a class-name change. Do not copy WooCommerce's template solely to change two words; the template header itself warns that overrides must be maintained when WooCommerce updates it.

Make Free and Pro precedence explainable

Free solves the ordinary problem with one store-wide value. Pro should add bounded placement rather than a condition builder:

  1. an individual product can explicitly use WooCommerce's native text;
  2. an individual product can supply its own label;
  3. one category label can apply to up to 50 selected categories;
  4. the Free store-wide label is the fallback.

The closest valid choice wins. Empty closer values fall through. An explicit native choice returns the incoming WooCommerce badge rather than another StoreFixKit fallback.

This gives support a deterministic answer to “why did these words appear?”

Localization needs a named owner

A saved merchant label is content, not automatically a WooCommerce translation. On a multilingual store, decide whether:

  • one phrase is acceptable in every language;
  • the translation plugin can translate the saved option;
  • each language site needs a separate setting;
  • selected products should keep native WooCommerce wording.

Do not claim universal multilingual support without testing the actual translation and cache stack. A translation workaround that changes the word Sale globally can also affect contexts the merchant did not intend to change.

Resource and failure boundary

The native render already has the badge HTML and product. The focused helper needs one small option read. Pro may read the current product's owned metadata and category IDs.

It needs no:

  • catalog scan;
  • price query loop;
  • product write on a public request;
  • cron or Action Scheduler job;
  • custom database table;
  • frontend CSS or JavaScript;
  • customer cookie;
  • telemetry;
  • StoreFixKit request from the storefront.

Missing WooCommerce, an unpublished or non-sale product, malformed settings, inactive Pro, an expired license, or an unavailable license service leaves the previous badge unchanged. Free remains local.

The Change Sale Badge Text documentation includes real screenshots, exact setup, compatibility limits, troubleshooting, rollback, uninstall ownership, and support evidence.

Beginner launch checklist

Record the baseline

Open one active sale, one future or expired sale, and one regular product. Record the badge, prices, and purchase behavior before installing anything.

Save one short label

Avoid formulas and long calls to action. The badge is a status label, not an advertisement panel.

Test every real surface

Open the shop, category, search, product page, quick view, and the exact product blocks used by the site. Record which surfaces use WooCommerce's native filter.

Test the off path

Disable the setting, clear the field, and deactivate the plugin. WooCommerce's exact original output should return each time.

Test rollback

Install the previous known-good package, then restore the current one. Confirm the label and Pro rules remain saved and no price or order changed.

Security and support evidence

Only a user allowed to manage WooCommerce should save global or category settings. Product fields require product-edit permission. Every write needs a nonce, capability check, bounded sanitization, and escaped output. WordPress's nonce documentation is clear that a nonce is not authorization; capability checks are still required.

Useful support evidence includes the product ID and URL, product type, sale state and dates, expected words, actual words, Free and Pro versions, WooCommerce version, theme or block owner, cache/CDN, and screenshots. Remove credentials, customer data, payment details, and full license keys.

FAQ

Does changing the badge text change the discount?

No. The plugin does not read or write the regular price, sale price, sale dates, or discount calculation.

Can it show 20% off automatically?

No. Percentage calculation is deliberately outside this text-only product.

Why does one product block still say Sale?

That block may own its badge output instead of applying WooCommerce's native sale-flash filter.

What happens when Pro expires?

The Free store-wide label continues locally. Category and individual-product rules require an active product-bound license.

Focused plugin

Use the one-job implementation.

Replace the words inside WooCommerce's native Sale badge without changing prices, sale dates, discounts, products, carts, checkout, or orders.