Kundexempel: E-handelsintegration

Se hur en nordisk e-handels/affiliate-sajt integrerade Besökskollen och fick datadrivna "Populära produkter" på 30 minuter.

Resultat

  • Integrationen tog ~30 minuter
  • Inga externa beroenden - enbart Next.js + Besökskollen
  • Fallback-logik baserad på confidence-nivåer
  • ISR-caching för bästa prestanda

Bakgrund

En nordisk e-handelssajt inom elektroniktillbehör ville visa "Populära produkter" baserat på faktiska klick, inte manuellt utvalda produkter.

Tidigare använde de en statisk lista som uppdaterades manuellt varannan vecka. Med Besökskollen får de nu realtidsdata på vilka produkter besökare faktiskt klickar på.

Steg-för-steg

StegTidVad
12 minRegistrerade event properties i dashboarden
21 minSkapade API-nyckel
31 minSparade credentials i .env.local
410 minImplementerade va() tracking på affiliate-länkar
515 minByggde API-klient med fallback
65 minIntegrerade med produktlistor

1. Registrera event properties

Först registrerade de vilka properties de ville spara. I Inställningar → Event Propertiesklickade de "Lägg till alla" för att få de vanligaste:

  • product_id - Unikt produkt-ID
  • category_slug - Produktkategori
  • partner_slug - Affiliate-partner
  • price - Pris vid klick

2-3. Skapa API-nyckel och spara credentials

I Inställningar → API-nycklar skapade de en nyckel och sparade den i .env.local:

# .env.local
BESOKSKOLLEN_API_KEY=bk_xxxxxxxxxxxx
BESOKSKOLLEN_SITE_ID=din-sajt-id

4. Implementera va() tracking

De la till tracking på sin affiliate-länkkomponent. När en användare klickar, skickas ett event med relevanta properties:

// components/AffiliateLinkButton.tsx
'use client';

interface Props {
  productId: string;
  categorySlug: string;
  partnerSlug: string;
  price: number;
  href: string;
  children: React.ReactNode;
}

export function AffiliateLinkButton({
  productId, categorySlug, partnerSlug, price, href, children
}: Props) {
  const handleClick = () => {
    // Skicka event till Besökskollen
    if (typeof window !== 'undefined' && window.va) {
      window.va('event', 'affiliate_click', {
        product_id: productId,
        category_slug: categorySlug,
        partner_slug: partnerSlug,
        price: price
      });
    }
  };

  return (
    <a
      href={href}
      onClick={handleClick}
      target="_blank"
      rel="noopener noreferrer"
      className="btn-primary"
    >
      {children}
    </a>
  );
}

Tips: Lägg till TypeScript-typer för window.va i en types/besokskollen.d.ts-fil.

5. Bygg API-klient med fallback

Nyckeln till en robust integration är att hantera fallet när det finns för lite data. De byggde en klient som automatiskt faller tillbaka på en alternativ datakälla:

// lib/besokskollen.ts
const API_KEY = process.env.BESOKSKOLLEN_API_KEY;
const SITE_ID = process.env.BESOKSKOLLEN_SITE_ID;
const BASE_URL = 'https://besokskollen.se/api/v1';

interface PopularProductsResponse {
  data: Array<{
    product_id: string;
    product_slug?: string;
    clicks: number;
  }>;
  meta: {
    confidence: 'high' | 'medium' | 'low';
    total_clicks: number;
  };
}

export async function getPopularProductIds(limit = 10) {
  try {
    const res = await fetch(
      `${BASE_URL}/popular/products?site_id=${SITE_ID}&days=30&limit=${limit}`,
      {
        headers: { 'Authorization': `Bearer ${API_KEY}` },
        next: { revalidate: 1800 } // 30 min ISR
      }
    );

    if (!res.ok) throw new Error('API error');

    const data: PopularProductsResponse = await res.json();

    return {
      ids: data.data.map(p => p.product_id),
      confidence: data.meta.confidence
    };
  } catch (error) {
    console.error('Besökskollen error:', error);
    return { ids: [], confidence: 'low' as const };
  }
}

6. Integrera med produktlistor

Slutligen använde de API-klienten i sin produktlista med smart fallback:

// lib/queries.ts
import { getPopularProductIds } from './besokskollen';

export async function getPopularProducts(limit = 12) {
  // Försök hämta från Besökskollen
  const { ids, confidence } = await getPopularProductIds(limit);

  if (confidence !== 'low' && ids.length > 0) {
    // Hämta produkter från din databas baserat på IDs
    const products = await db.query.products.findMany({
      where: inArray(products.id, ids),
      limit
    });

    // Sortera i samma ordning som Besökskollen returnerade
    return products.sort((a, b) =>
      ids.indexOf(a.id) - ids.indexOf(b.id)
    );
  }

  // Fallback: Senast uppdaterade produkter
  return db.query.products.findMany({
    orderBy: desc(products.updatedAt),
    limit
  });
}

Confidence-nivåer

  • high - 100+ events, 10+ produkter → Visa "Populära produkter"
  • medium - 20+ events → Visa med varning eller blanda
  • low - Lite data → Använd fallback

Slutresultat

Efter integrationen har sajten nu:

  • Datadrivna produktlistor - "Populära produkter" baserat på faktiska klick
  • Robust fallback - Fungerar även med lite data
  • Minimal overhead - ISR-caching ger snabb sidladdning
  • Insights i dashboarden - Kan se vilka produkter som trendar i Properties-fliken

"Integrationen var överraskande enkel. RFC-dokumentationen var tydlig, API:et är standard REST med Bearer token, och confidence-nivån gör fallback-logik trivial."

— Utvecklare, nordisk e-handelssajt

Vill du göra samma sak?