Wiele sklepów internetowych korzystających z WooCommerce i Elementora napotkało problem z odświeżaniem koszyka, zwłaszcza po dodaniu produktów do koszyka przez AJAX. Ten problem może objawiać się tym, że po dodaniu produktu do koszyka, zawartość koszyka (np. liczba produktów, podsumowanie) nie jest odświeżana poprawnie, szczególnie wtedy, gdy użytkownicy są zalogowani. Problem ten może wynikać z mechanizmów cache’owania, które blokują dynamiczne odświeżenie koszyka w zależności od stanu sesji użytkownika.
Problem z Odświeżaniem Koszyka w Elementorze i WooCommerce – Nadal nierozwiązany od lat
Mimo że Elementor i WooCommerce są jednymi z najpopularniejszych narzędzi do tworzenia sklepów internetowych, problem z odświeżaniem koszyka po dodaniu produktów przez AJAX wciąż pozostaje nierozwiązany. Chociaż z biegiem lat pojawiły się nowe wersje zarówno Elementora, jak i WooCommerce, problem ten nie został w pełni załatany, a użytkownicy nadal napotykają trudności z prawidłowym działaniem koszyka, zwłaszcza gdy są zalogowani.
Problem pustego koszyka Elementora mini-cart:
Kiedy użytkownicy są zalogowani, fragmenty koszyka (np. liczba produktów w koszyku) mogą nie być odświeżane dynamicznie po dodaniu nowych produktów. Jednakże, w trybie incognito, wszystko działa poprawnie. Często jest to wynikiem:
- Cache’owania stron koszyka lub checkout, które mogą powodować, że WooCommerce nie odświeża koszyka po każdej akcji AJAX.
- Brak załadowania odpowiednich skryptów, które są wymagane do dynamicznego odświeżenia koszyka.
Rozwiązanie problemy z pustym koszykiem Elementora:
Aby rozwiązać ten problem, potrzebujemy załadować odpowiedni skrypt WooCommerce do odświeżania koszyka oraz upewnić się, że koszyk i checkout nie są cache’owane dla zalogowanych użytkowników. Poniżej przedstawiamy pełne rozwiązanie w postaci kodu PHP oraz JavaScript, które możesz dodać do swojego motywu lub za pomocą wtyczki Code Snippets.
// Załaduj skrypt do odświeżania fragmentów koszyka (wc-cart-fragments)
add_action( 'wp_enqueue_scripts', 'enqueue_wc_cart_fragments_script' );
function enqueue_wc_cart_fragments_script() {
// Załaduj skrypt wc-cart-fragments na każdej stronie, jeśli chcesz, aby koszyk działał wszędzie
if ( is_cart() || is_checkout() || is_product() || is_shop() ) {
wp_enqueue_script( 'wc-cart-fragments' );
}
}
// Funkcja AJAX do odświeżania fragmentów koszyka (w przypadku dodawania do koszyka przez AJAX)
add_action( 'wp_ajax_update_cart_fragments', 'update_cart_fragments' );
add_action( 'wp_ajax_nopriv_update_cart_fragments', 'update_cart_fragments' );
function update_cart_fragments() {
// Używamy metody WooCommerce do odświeżania fragmentów koszyka
WC_AJAX::get_refreshed_fragments();
wp_die(); // Koniec działania po wywołaniu AJAX
}
// Zapewniamy wsparcie dla odświeżania koszyka po dodaniu elementów do koszyka za pomocą AJAX w Elementorze
add_action( 'wp_footer', 'add_cart_fragments_script', 999 );
function add_cart_fragments_script() {
?>
<script type="text/javascript">
jQuery(function($){
// Skrypt do aktualizacji koszyka po dodaniu elementu
$('body').on('added_to_cart', function(){
// Wywołaj AJAX, aby odświeżyć fragmenty koszyka
$.ajax({
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
type: 'GET',
success: function( response ) {
var fragments = response.fragments;
if (fragments) {
// Iterujemy po fragmentach i aktualizujemy je na stronie
$.each(fragments, function(key, value) {
$(key).replaceWith(value);
});
}
}
});
});
});
</script>
<?php
}
// Dodanie do sesji, by WooCommerce nie cache'ował fragmentów koszyka dla użytkowników zalogowanych
add_filter( 'woocommerce_is_cart_fragments_supported', '__return_true' );
// Dodatkowe: wykluczenie koszyka z cache'owania (jeśli używasz wtyczki cache'ującej)
add_action( 'init', 'exclude_cart_from_cache', 1 );
function exclude_cart_from_cache() {
if ( is_cart() || is_checkout() ) {
// Ustawienie nagłówków, które wykluczą stronę koszyka z cache'owania
header( 'Cache-Control: no-cache, no-store, must-revalidate' );
header( 'Pragma: no-cache' );
header( 'Expires: 0' );
}
}
Wyjaśnienie kodu:
- Załadowanie skryptu
wc-cart-fragments
:- Ten skrypt WooCommerce jest odpowiedzialny za odświeżanie fragmentów koszyka, takich jak liczba produktów i podsumowanie koszyka. W tym przypadku ładowany jest on na stronach takich jak koszyk, checkout, produkty oraz strona sklepu.
- Funkcja AJAX
update_cart_fragments
:- Po dodaniu produktu do koszyka przez AJAX, ta funkcja uruchamia metodę WooCommerce
WC_AJAX::get_refreshed_fragments()
, która odświeża zawartość koszyka. Funkcja ta działa zarówno dla użytkowników zalogowanych, jak i niezalogowanych.
- Po dodaniu produktu do koszyka przez AJAX, ta funkcja uruchamia metodę WooCommerce
- Skrypt JavaScript do odświeżania koszyka:
- Skrypt ten nasłuchuje zdarzenie
added_to_cart
i po jego wywołaniu wykonuje żądanie AJAX do serwera, aby zaktualizować fragmenty koszyka bez przeładowywania strony.
- Skrypt ten nasłuchuje zdarzenie
- Wykluczenie cache’owania koszyka:
- Strona koszyka oraz checkout są wykluczone z cache’owania, aby zapewnić, że zawartość koszyka zawsze będzie aktualna, szczególnie dla użytkowników zalogowanych. Dzięki temu WooCommerce nie będzie próbował wyświetlać zcache’owanej wersji koszyka, a wszystkie zmiany będą natychmiastowo widoczne.
Dlaczego to działa?
WooCommerce używa fragmentów koszyka (cart fragments), które są odświeżane po każdej akcji AJAX, aby dynamicznie zaktualizować koszyk na stronie. Działa to szczególnie w przypadku Elementor, gdzie produkty są dodawane do koszyka bez przeładowania strony. Dzięki powyższemu kodowi, problem z odświeżaniem koszyka, zwłaszcza w przypadku użytkowników zalogowanych, zostaje rozwiązany.
Dodatkowo, cache’owanie może powodować, że WooCommerce wyświetla zaktualizowaną zawartość koszyka tylko dla użytkowników w trybie incognito, a nie dla tych, którzy są zalogowani. Wykluczenie koszyka z cache’owania rozwiązuje ten problem, zapewniając, że zawartość koszyka będzie zawsze aktualna.
Pamiętaj że ten kod może nie dotyczyć Twojego problemu, przyczyna w Twojej instalacji WordPress może wynikać z zupełnie innego powodu, może to być konflikt wtyczki lub kodu PHP lub JavaScript.
Dzięki u mnie działa 🙂