WooCommerce Currency Switcher Stuck Loading After JS Optimization
A WooCommerce currency switcher stuck loading, with three animated dots that never turn into a drop-down, is almost never a slow server. The switcher is built by JavaScript in the visitor's browser, and a speed optimization plugin that minifies, combines, defers or delays scripts has changed when or in what order that JavaScript runs. The same cause shows up as a drop-down that does nothing on click, prices hidden behind a spinner until the visitor moves the mouse, or a switcher that works for you and breaks for everyone else. Below is how FOX starts in the browser, how to confirm the optimizer is the cause, and what to exclude.
What the switcher needs to start
FOX prints three things into the page, and all of them have to run, in this order:
- A small inline script with the visitor's data:
woocs_current_currency,woocs_default_currency,woocs_array_of_get,woocs_ajaxurland a few other variables, all starting withwoocs_. WordPress prints it right before the main file. - The main file,
/wp-content/plugins/woocommerce-currency-switcher/js/front.js, which needs jQuery. It defineswoocs_redirect(), the function every drop-down calls when a currency is chosen. The drop-down skins (ddslick, Chosen, wSelect, Style #1–#3) add their own scripts from the plugin folder. - For switchers made in the Designer tab (
[woocs sd=1]and similar), a placeholder with the three dots. The scriptjs/sd/front.jsreplaces the dots with the real drop-down when the browser fires itsloadevent, once, for the placeholders present at that moment.
When I am using cache plugin on my site is set to Yes, front.js also sends an AJAX request (woocs_get_products_price_html) after the page has loaded and redraws the prices in the visitor's currency. With Prices preloader on, the prices are hidden until that answer arrives.
Each optimization feature breaks a different link of that chain:
| Feature | What it does to FOX | Typical symptom |
|---|---|---|
| Delay JavaScript until user interaction | The scripts run after the load event has already fired, so the code waiting for it never runs | Dots spin forever; prices appear only after a scroll or a click |
| Defer JavaScript | Changes the order: the inline block, jQuery and front.js no longer run in sequence | woocs_current_currency is not defined, jQuery is not defined |
| Combine or minify JavaScript | Moves the inline block away from front.js; one error anywhere in the combined file stops everything after it | The drop-down does nothing, woocs_redirect is not defined |
| Combine CSS, remove unused CSS | The drop-down markup is created by JavaScript after load, so its styles look unused to the optimizer and get dropped or reordered | Broken or unstyled switcher for logged-out visitors only |
Confirm the optimizer is the cause
Open the page in a private window, logged out. Most optimizers serve their processed files only to visitors and skip logged-in administrators, which is why the switcher can work perfectly for you. Then open the browser console (F12, tab Console), reload, and paste:
console.log(typeof woocs_current_currency, typeof woocs_redirect, typeof jQuery);
A working page prints object function function. Any undefined means that part of FOX has not run yet. Red errors that name woocs_ variables or a combined file (names like min/, cache/, autoptimize_) point the same way. For a final check, switch off only the JavaScript features of the optimizer (minify, combine, defer, delay), clear its cache and reload in the private window. If the switcher works now, re-enable the features with the exclusions below instead of leaving them off.
Exclude FOX from defer, delay and combine
Every optimizer has an exclusion field for each of these features, and almost all of them accept a part of a file path or a keyword found in an inline script. Add these four lines to each JavaScript feature you use:
woocommerce-currency-switcher
woocs
jquery.min.js
jquery-migrate
woocommerce-currency-switcheris the plugin folder: it covers front.js, the drop-down skins and the Designer scripts.woocsmatches the inline block, because every variable in it starts withwoocs_. Excluding only front.js does not help if the inline block is still delayed.- jQuery and jQuery Migrate, because FOX runs on jQuery. If jQuery is delayed and FOX is not, FOX starts first and stops at
jQuery is not defined.
Where the fields are in the common plugins:
| Plugin | Where to add the exclusions |
|---|---|
| WP Rocket | File Optimization: the exclusion fields of Load JavaScript deferred and Delay JavaScript execution. More in FOX and WP Rocket. |
| LiteSpeed Cache | Page Optimization → Tuning: JS Deferred / Delayed Excludes, and JS Excludes if JS combine is on. The Delayed mode of Load JS Deferred is the one that leaves Designer switchers on the dots. |
| Autoptimize | JS, CSS & HTML: Exclude scripts from Autoptimize, comma-separated. |
| SiteGround Speed Optimizer, NitroPack, WP-Optimize | The exclusion list next to each minify, combine, defer or delay option. |
After saving, clear the optimizer's cache and the page cache: pages built before the change still reference the old combined files. Then repeat the console check in a private window. If the theme or a hosting panel has its own "optimize JavaScript" switch, it needs the same exclusions.
Prices hidden behind a spinner until the visitor interacts
On a cached shop, the page arrives with the prices of whoever was cached first, and FOX fixes them in the browser with the AJAX redraw described above. If the optimizer delays scripts until the first user interaction, the redraw starts only then, and with Prices preloader on the prices stay hidden until the visitor scrolls or clicks. The exclusions above fix it. While you test, you can also turn Prices preloader off in the Options tab: the prices are then visible at once, in the cached currency until the redraw runs.
Check that the redraw is needed at all. I am using cache plugin on my site should be Yes only if the shop pages really come from a page cache; without one, FOX already prints the right prices on the server. Why the redraw exists is explained in why a currency switcher and a page cache fight each other.
Delayed scripts can also change the currency of the cart. With Currency storage set to Transient and the cache option on, front.js gives each browser its own key and adds it to cart, checkout and payment requests, including the fetch() calls of the Checkout block, the Store API and the PayPal buttons. Requests sent before front.js runs go without the key and are resolved by IP address instead, which can give them a different currency. One more reason not to delay front.js.
Broken switcher styles for logged-out visitors
If the drop-down looks right when you are logged in and broken for visitors (wrong size, no flags, the list open under other elements), the CSS was combined or partly removed. Features called "remove unused CSS" or "critical CSS" analyse the HTML the server sends, and the drop-down markup is not in it yet: the skins build it with JavaScript after load. Exclude the plugin folder woocommerce-currency-switcher from CSS combine and from unused-CSS removal, then clear the caches. A short flash of the text FOX v.2.5.5 where the switcher sits is the same problem in a milder form: the plugin's stylesheet, which hides that text, is loaded late.
If you prefer a switcher with no skin at all, choose Not styled drop-down in the Currencies tab. It is a plain select that takes the theme's styles, but it still needs front.js to switch the currency.
Hide the loading dots only after fixing the cause
The dots are the .woocs-lds-ellipsis element inside a Designer placeholder. They can be hidden with CSS in Appearance → Customize → Additional CSS:
/* FOX: hide the loading animation of Designer switchers */
.woocs-lds-ellipsis {
display: none !important;
}
This removes the animation, not the problem. If the script still does not run, the visitor now sees an empty space instead of dots. Use it to hide the short moment before the load event on a slow page, after the switcher has been confirmed to appear on its own.
If it still does not work
- Errors from other scripts. In a combined file, an error thrown by another plugin stops the code after it, including FOX. Fix the errors that name a combined file first; the console shows the file and line.
- Switchers in menus loaded later. Designer switchers are built once, on
load. A mobile menu or popup whose content the theme inserts after that keeps its dots. Use a switcher that is in the page from the start, or a [woocs] switcher with the Not styled drop-down skin: it is a plain select and switches the currency even when it is inserted later. - The browser cache. Test in a fresh private window, or reset the page cache in the browser, after every change.
If the console check still shows undefined with all exclusions in place and the caches cleared, open a topic on the FOX support forum with the page link, the name of the optimization plugin and the console errors, and we will look at it.