Professionel hjemmeside

Fra kun 4.000 kr

Få en professionel hjemmeside der skaber resultater. Vi designer og udvikler skræddersyede løsninger der passer til din virksomhed.

  • Responsivt design
  • SEO optimeret
  • Hurtig levering
Start dit projekt i dag!
Webworq
Kontakt os
Send os en mail
København, Danmark
Ajax Load More i WooCommerce: Komplet guide med kodeeksempler
Custom CodeArtikel

Ajax Load More i WooCommerce: Komplet guide med kodeeksempler

Implementér Ajax Load More i din WooCommerce-shop med vores trin-for-trin guide. Konkrete kodeeksempler, SEO-overvejelser, filterkompatibilitet og fejlfinding.

Sebastian Thiemann
Sebastian Thiemann14. maj 2025Opdateret 23. juni 20268 min

Paginering er en af de mest oversete brugeroplevelsesdetaljer i en webshop. Traditionel paginering (side 1, 2, 3...) bryder browsingflowet og kræver fuld sidegenindlæsning. Ajax Load More løser det ved at indlæse nye produkter direkte i siden uden reload.

Det her er ikke teori. Vi har bygget og kørt den her løsning i produktion på danske WooCommerce-webshops, blandt andet med en "vis flere"-knap på en webshop vi driver, og guiden her er den opskrift vi selv bruger. Vi deler både koden, de SEO-faldgruber vi har lært at undgå, og de små fejl der oftest spænder ben. Vores mål er at du kan implementere en løsning der både føles hurtig for brugeren og er korrekt for søgemaskiner.

Hvad er Ajax Load More?

Ajax Load More er en teknik (og et populært WordPress-plugin) der bruger Ajax-kald til at hente og indsætte nyt indhold i siden uden fuld sidegenindlæsning. I en WooCommerce-kontekst betyder det at brugeren kan browse flere produkter med et klik på "Vis flere" eller med automatisk infinite scroll.

Fordele ved Ajax Load More i en webshop

  • Bedre brugeroplevelse: Ingen irriterende sidegenindlæsninger. Browsing føles hurtig og glidende.
  • Lavere bounce rate: Brugere der nemt kan se flere produkter, forlader sjældnere siden.
  • Højere engagement: Flere sete produkter giver flere potentielle tilføjelser til kurven.
  • Hurtigere opfattet hastighed: Kun nye produkter indlæses, ikke hele siden.

Metode 1: Ajax Load More-plugin (ingen kode)

Det nemmeste er at bruge Ajax Load More-pluginet (gratis med premium add-ons). Her er opsætningen:

  1. Installér og aktivér "Ajax Load More" fra WordPress plugin-repository.
  2. Køb og installér WooCommerce-add-on'en (påkrævet for WooCommerce-integration).
  3. Gå til Ajax Load More, Settings og konfigurér grundindstillinger.
  4. Tilføj shortcode til din shop-side eller brug pluginets template integration.

Grundlæggende shortcode

[ajax_load_more post_type="product" posts_per_page="12"
  orderby="date" order="DESC"
  button_label="Vis flere produkter"
  button_loading_label="Indlæser..."
  transition="fade" transition_speed="300"]

Med WooCommerce-specifik template

[ajax_load_more woocommerce="true"
  posts_per_page="12"
  button_label="Vis flere produkter"
  images_loaded="true"
  css_classes="woocommerce columns-3"]

Metode 2: Custom implementering (fuld kontrol)

Pluginet er fint til at komme hurtigt i gang, men når vi bygger til kunder, laver vi løsningen custom. Det giver fuld kontrol over markup, performance og hvordan knappen spiller sammen med tema og filtre, og vi undgår at trække et helt plugin ind for én funktion. Det er den løsning vi gennemgår herunder. Bemærk at koden bruger en nonce til at sikre Ajax-kaldet mod misbrug (CSRF). Her er den komplette opsætning:

Trin 1: PHP, registrér Ajax endpoint

// functions.php eller custom plugin
add_action('wp_ajax_load_more_products', 'load_more_products_handler');
add_action('wp_ajax_nopriv_load_more_products', 'load_more_products_handler');

function load_more_products_handler() {
    // Verificér nonce (sikkerhed)
    check_ajax_referer('load_more_nonce', 'nonce');

    $paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
    $per_page = isset($_POST['per_page']) ? intval($_POST['per_page']) : 12;
    $category = isset($_POST['category']) ? sanitize_text_field(wp_unslash($_POST['category'])) : '';

    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => $per_page,
        'paged'          => $paged,
        'post_status'    => 'publish',
        'orderby'        => 'date',
        'order'          => 'DESC',
        // Respektér WooCommerces synlighed, så load more matcher selve shoppen.
        // Tilføj 'outofstock' til terms hvis din shop skjuler udsolgte varer.
        'tax_query'      => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => array('exclude-from-catalog'),
                'operator' => 'NOT IN',
            ),
        ),
    );

    if ($category) {
        $args['tax_query'][] = array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $category,
        );
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        ob_start();
        while ($query->have_posts()) {
            $query->the_post();
            wc_get_template_part('content', 'product');
        }
        $html = ob_get_clean();
        wp_reset_postdata();

        wp_send_json_success(array(
            'html'     => $html,
            'has_more' => $paged < $query->max_num_pages,
        ));
    } else {
        wp_send_json_success(array(
            'html'     => '',
            'has_more' => false,
        ));
    }
}

Trin 2: Enqueue og localize scripts

Vigtigt: Du skal bruge wp_localize_script til at give JavaScript adgang til Ajax-URL'en og din nonce. Uden dette virker Ajax-kaldet ikke.

// functions.php
function enqueue_load_more_scripts() {
    if (is_shop() || is_product_category()) {
        wp_enqueue_script(
            'load-more-products',
            get_template_directory_uri() . '/assets/js/load-more.js',
            array('jquery'),
            '1.0.0',
            true
        );

        wp_localize_script('load-more-products', 'wc_ajax_params', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('load_more_nonce'),
        ));
    }
}
add_action('wp_enqueue_scripts', 'enqueue_load_more_scripts');

En vigtig note om nonce og caching: Nonces beskytter mod misbrug, men de udløber typisk efter 12 til 24 timer. Kører din side med fuld sidecaching, kan en cachet side ende med en udløbet nonce, så Ajax-kaldet fejler for nogle besøgende. Da dette endpoint kun returnerer offentlige produktdata, er der ingen reel CSRF-risiko, og du kan derfor vælge at droppe nonce-tjekket på stærkt cachede sider. Beholder du det, så sørg for at "vis flere"-knappen ikke ligger på en fuldt cachet side, eller hent en frisk nonce via et separat, ucachet kald.

Trin 3: JavaScript, Load More-funktionalitet

// assets/js/load-more.js
(function($) {
    let currentPage = 1;
    const perPage = 12;
    let isLoading = false;

    $('#load-more-btn').on('click', function(e) {
        e.preventDefault();
        if (isLoading) return;

        isLoading = true;
        const $btn = $(this);
        $btn.text('Indlæser...').prop('disabled', true);

        currentPage++;

        $.ajax({
            url: wc_ajax_params.ajax_url,
            type: 'POST',
            data: {
                action: 'load_more_products',
                nonce: wc_ajax_params.nonce,
                page: currentPage,
                per_page: perPage,
                category: $btn.data('category') || '',
            },
            success: function(response) {
                if (response.success && response.data.html) {
                    $('ul.products').append(response.data.html);

                    if (!response.data.has_more) {
                        $btn.fadeOut();
                    } else {
                        $btn.text('Vis flere produkter').prop('disabled', false);
                    }
                }
                isLoading = false;
            },
            error: function() {
                $btn.text('Fejl, prøv igen').prop('disabled', false);
                isLoading = false;
            }
        });
    });
})(jQuery);

SEO-overvejelser

Det er her vi ser flest fejl, også i løsninger der ellers virker fint for brugeren. Ajax Load More kan påvirke din SEO hvis det implementeres forkert. Googlebot scroller ikke og klikker ikke på "Vis flere"-knapper, så indhold der kun er tilgængeligt via Ajax, risikerer ikke at blive indekseret. Vi følger Googles officielle anbefalinger for paginering:

Behold altid standard WooCommerce-paginering med rigtige <a href>-links i din HTML-kildekode. Ajax Load More skal være en forbedring ovenpå, ikke en erstatning. Google indekserer primært URL'er det finder i <a href>-tags, så de crawlbare links sikrer at alle dine produkter kan findes.

Brug selv-refererende canonicals (ikke canonical til side 1)

Dette er den hyppigste SEO-fejl ved paginering. Hver pagineret side (side 2, 3, 4...) skal have en selv-refererende canonical, altså side 2 canonicaliserer til side 2. Peg IKKE alle paginerede sider mod side 1. Gør du det, fortæller du Google at det skal ignorere alt efter side 1, hvilket kan gøre produkterne på de dybere sider forældreløse og uindekserede.

Undgå noindex på paginerede sider

Lad være med at sætte noindex på dine paginerede sider. Over tid holder Google op med at crawle noindexede sider og følger dermed ikke deres links, så produkter der kun er linket fra dybe sider, kan forsvinde fra indekset.

rel="next" og rel="prev" er ikke længere nødvendige

Google annoncerede i 2019 at de ikke længere bruger rel="next" og rel="prev" som signal. Har du dem allerede, gør de ingen skade (Bing bruger dem stadig), men du behøver ikke tilføje dem på nye sider. Brug i stedet din tid på crawlbare links og korrekte canonicals.

Unikke produkt-URL'er

Hvert produkt skal have sin egen permanente URL, uanset om det blev indlæst via Ajax eller traditionel paginering. Link altid til den kanoniske produkt-URL.

Vil du dykke dybere ned i det tekniske, så se vores guide til teknisk SEO.

Kompatibilitet med produktfiltre

Ajax Load More skal geninitialiseres når brugeren ændrer filtre. Her er et eksempel med YITH WooCommerce Ajax Product Filter:

// Lyt efter filterændringer
$(document).on('yith-wcan-ajax-filtered', function() {
    // Reset page counter
    currentPage = 1;

    // Opdatér Load More-knap
    $('#load-more-btn').show().text('Vis flere produkter');

    // Hent aktive filtre til næste Ajax-kald
    activeFilters = getCurrentFilters();
});

De fleste populære filter-plugins som YITH, WooCommerce Product Filter by WooBeWoo og FacetWP har lignende JavaScript-events du kan lytte på.

Performance-optimering

  • Lazy load billeder: Brug loading="lazy" på produktbilleder i Ajax-responsen for at spare båndbredde. Se vores guide til billedoptimering.
  • Preload næste side: Hent næste side i baggrunden når brugeren nærmer sig bunden, så indlæsningen føles øjeblikkelig.
  • Caching: Cache Ajax-responses server-side med Transients API for at reducere databaseforespørgsler.
  • Minimér response-størrelse: Send kun den HTML der er nødvendig, ikke hele sidens markup.

Hastighed påvirker både brugeroplevelse og SEO. Se hvordan det hænger sammen med dine Core Web Vitals.

Fejlfinding: Almindelige problemer

Det er de samme håndfulde fejl der går igen, når vi sætter Ajax Load More op. Her er dem vi oftest støder på, og hvordan vi løser dem:

Ajax-kaldet returnerer 0 eller en fejl

Den hyppigste årsag er en manglende eller forkert nonce, eller at wp_localize_script ikke kører. Tjek at wc_ajax_params faktisk er defineret i frontenden (kig i browserens konsol), og at nonce-navnet matcher mellem PHP og JavaScript.

Produkter vises ikke korrekt

Tjek at du bruger wc_get_template_part('content', 'product') i dit Ajax-endpoint. Hvis dit tema bruger en custom product loop, skal du referere til den template i stedet.

Billeder mangler eller er forkert størrelse

Sørg for at WooCommerce-billedstørrelserne er konfigurerede. Kør evt. "Regenerate Thumbnails" efter ændringer.

Load More-knap forsvinder ikke

Tjek at din Ajax-handler returnerer has_more: false korrekt. Sammenlign $paged med $query->max_num_pages.

Konflikter med page builders

Elementor, Divi og WPBakery har egne product loop-elementer der kan konflikte med Ajax Load More. Brug plugin-specifikke hooks til integration, eller implementér Load More direkte i page builderens custom widget.

Anbefaling: Load More-knap vs. infinite scroll

Vi får ofte spørgsmålet om vi ikke bare skal lave infinite scroll i stedet. Vores erfaring er klar: vi vælger næsten altid Load More-knappen frem for infinite scroll i webshops. Infinite scroll lyder tiltalende, men giver i praksis flere problemer:

  • Brugeren kan ikke nå footeren (med kontaktinfo, links osv.).
  • Det er sværere for brugeren at vende tilbage til et specifikt produkt.
  • Det kan føles overvældende for brugere der leder efter noget bestemt.
  • Tilgængelighed er bedre med en eksplicit knap.

Uanset metode er det vigtigste at indholdet også findes via crawlbare URL'er, så hverken brugere eller søgemaskiner går glip af produkter.

Vil du have hjælp til at optimere din WooCommerce-shop? Se vores e-commerce services eller kontakt os for en uforpligtende snak om din webshops performance og brugeroplevelse.

Ofte stillede spørgsmål

Find svar på de mest almindelige spørgsmål

Ajax Load More er kompatibelt med de fleste WooCommerce-temaer, herunder populære temaer som Astra, Flatsome, OceanWP, Storefront og GeneratePress. Dog kan temaer med custom product loop-implementeringer kræve ekstra konfiguration. Test altid på en staging-side først, og tjek at produktkort, varianter og priser vises korrekt.
Ikke hvis du implementerer det korrekt. Googlebot udfører ikke klik på en "Vis flere"-knap, så det indhold der kun indlæses via Ajax, skal også være tilgængeligt via almindelige, crawlbare URL'er. Brug progressive enhancement: behold standard WooCommerce-paginering med rigtige <a href>-links i HTML'en for crawlere, og læg Ajax Load More ovenpå for brugere med JavaScript. Sørg for at hver produktside har sin egen unikke URL.
Ja, men det kræver ekstra konfiguration. Ajax Load More skal geninitialiseres når filtre ændres. De fleste filter-plugins (YITH, WooCommerce Product Filter) har JavaScript-events du kan bruge til at triggere en reload af Ajax Load More med nye filterparametre. Se kodeeksemplerne i guiden for konkret implementering.
Infinite scroll indlæser automatisk nye produkter når brugeren scroller ned. Load More-knap kræver et klik. Vi anbefaler Load More-knappen, fordi den giver brugeren kontrol, er bedre for tilgængelighed, og gør det muligt at nå footeren (vigtig for kontaktinfo og links). Infinite scroll kan frustrere brugere der leder efter noget specifikt.
Vi anbefaler 12-24 produkter per load, afhængigt af dit layout. 12 produkter i et 3-kolonne grid giver 4 rækker, nok til at brugeren kan vurdere udvalget uden at blive overvældet. For mobilvisning kan 8-12 produkter per load være passende. Test med din målgruppe for at finde det optimale antal.

Klar til at tage det næste skridt?

Lad os hjælpe dig med at implementere disse strategier