Widget Integration Guide
Beta

Integrer booking på dit eget website

Med Holdstyring widgets kan du tilføje professionel booking-funktionalitet direkte på din hjemmeside - uden at skifte platform. Komplet guide fra opsætning til go-live.

Hvad er widgets?

Widgets er små, selvstændige komponenter som du kan integrere direkte på din eksisterende hjemmeside. De giver dine kunder mulighed for at se holdoversigten, logge ind, booke og betale for hold, købe klippekort og gavekort og se deres medlemskab - alt sammen uden at forlade din side.

💡

Perfekt til dig der...

  • ✓Allerede har en hjemmeside du er glad for
  • ✓Vil have fuld kontrol over design og branding
  • ✓Ønsker en sømløs brugeroplevelse for dine kunder

Fordele ved widgets

⚡

Nem integration

Tilføj blot ét script-tag og brug vores HTML-komponenter. Ingen kodning påkrævet.

🎨

Dit design

Widgets tilpasser sig automatisk dit studies farver og designskabelon fra Holdstyring.

🔒

Sikker & pålidelig

Domænebundne API-nøgler, signerede og kortlivede login-tokens og rate limiting på login og formularer beskytter dine data.

📱

Responsivt

Fungerer perfekt på alle enheder - desktop, tablet og mobil.

🔄

Live data

Hentes direkte fra Holdstyring når siden indlæses — ledige pladser, bookinger og medlemskabsinfo er altid de aktuelle.

🌐

Isoleret

Shadow DOM sikrer at widgets ikke påvirker eller påvirkes af din sides styling.

Kom i gang

Følg disse tre simple trin for at få widgets op at køre på din hjemmeside.

1

Opret en API-nøgle

Log ind på din Holdstyring-administration, slå widgets til (se boksen herunder), og gå til Indstillinger → Widgets. Klik på "Opret API-nøgle", giv nøglen et navn, og skriv dit websites adresse i feltet "Tilladte domæner (påkrævet)" (én pr. linje).

ℹ️
Slå først widgets til

Widgets skal være aktiveret på din konto under Indstillinger → Udvidede funktioner → Hjemmeside & indhold med kontakten "Widgets til egen hjemmeside". Er de ikke det, afvises alle kald — også selvom du har en gyldig API-nøgle. Kortet "Widgets" i Indstillinger og linket "Gå til Widget-opsætning for API-nøgler og integrationskode →" dukker først op, når kontakten er slået til. Åbner du Widgets-siden direkte (/admin/widgets) før da, kan du slå dem til med ét klik på "Slå widgets til".

dit-studio.holdstyring.dk/admin/widgets

API-nøgler

Min hjemmeside
wk_live_abc12345...
Domæner: https://www.mit-studie.dk, https://mit-studie.dk
Aktiv
⚠️
Vigtigt om API-nøgler
  • Den fulde nøgle vises kun én gang, lige efter oprettelsen (i den grønne boks "Din API-nøgle er klar!" sammen med "Klar til din hjemmeside" og knappen "Kopiér opsætning"). Bagefter viser listen kun starten af nøglen efterfulgt af ... — det er ikke en gyldig nøgle.
  • Nøglen står synligt i din sides kildekode, men den virker kun fra de domæner du har skrevet på den. Mindst ét domæne er påkrævet, for en tom liste afviser alle kald; * tillader alle domæner.
  • Sti, afsluttende / og manglende https:// rettes automatisk (https://mit-studie.dk/booking gemmes som https://mit-studie.dk). Men www.mit-studie.dk og mit-studie.dk er to forskellige domæner — skriv begge, eller brug *.mit-studie.dk, der dækker domænet og alle underdomæner.
  • Domænerne kan rettes bagefter. Mangler et domæne, så klik "Ret domæner" på nøglen under API-nøgler og gem. Nøglen og dine widgets er uændrede, så der skal ikke sættes ny kode ind. Opret kun en ny nøgle, hvis du vil skifte selve nøglen (en deaktiveret nøgle kan ikke genaktiveres).
2

Installer widget-scriptet

Tilføj følgende script-tag til din hjemmeside, helst lige før </body>:

Tilføj til din HTMLhtml
<script src="https://widgets.holdstyring.dk/v1/holdstyring-widgets.min.js" async></script>

💡 Tip: async attributten sikrer at scriptet ikke blokerer din sides indlæsning. Scriptet skal kun være på siden én gang, uanset hvor mange widgets du bruger. Når det er indlæst, står der Yoga Widgets v… loaded i browserens konsol (F12 → Console).

3

Tilføj widgets til din side

Nu kan du tilføje widgets hvor som helst på din side ved at bruge vores custom HTML-elementer:

Eksempel: Holdoversigthtml
<!-- Holdoversigt med booking -->
<holdstyring-schedule api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-schedule>

<!-- Login formular -->
<holdstyring-login api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-login>

<!-- Brugerens bookinger -->
<holdstyring-bookings api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-bookings>

<!-- Medlemskabsoversigt -->
<holdstyring-membership api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-membership>
💡
Både api-key og base-url skal med

base-url er dit studies adresse, så widgeten ved hvor den skal hente data: dit verificerede egne domæne, ellers dit-studio.holdstyring.dk — Class Booking-studier bruger deres class-booking.com-adresse. Widgets-siden i admin (Indstillinger → Widgets) sætter altid den rigtige base-url ind i al kode ("Hurtig integration", "Kopiér tag" og Widget-byggeren). Din fulde nøgle står kun i koden, så længe du bliver på siden efter at have oprettet nøglen; ellers står pladsholderen DIN_FULDE_API_NØGLE, som du selv skifter ud. tenant-slug="dit-studio" kan bruges i stedet for base-url, men peger altid på dit-studio.holdstyring.dk — forkert for Class Booking og eget domæne. Kun når siden selv ligger på en *.holdstyring.dk-adresse, findes adressen automatisk.

🎉

Det var det!

Dine widgets er nu klar til brug. De henter data direkte fra dit Holdstyring-studie, hver gang siden indlæses, og viser dine aktuelle hold, priser og ledige pladser.

Tilgængelige widgets

holdstyring-schedule

Viser dine kommende hold grupperet pr. dag med booking direkte i widgeten. Med view-toggle får den besøgende en Hold/Kalender-skifter, hvor kalenderen er en ugekalender med 7 kolonner (mandag-søndag).

Morgen Flow Yoga
Mandag 08:00 - 09:00
4 pladser
med Louise
Yin Yoga
Mandag 18:00 - 19:30
2 pladser

Attributter

AttributTypeStandardBeskrivelse
api-keystring-Din fulde API-nøgle (påkrævet)
base-urlstring-Dit studies adresse (påkrævet uden for *.holdstyring.dk)
hold-type-slugsstringalleKun hold med disse holdmærkater, kommasepareret (fx "yoga,pilates")
template-idstring-Kun hold fra én holdskabelon (ét bestemt hold eller program)
weeksnumber-Kun hold de næste 1-52 uger. Holdskabelonens egen bookinghorisont gælder også; den strammeste vinder
titlestringingenOverskrift over widgeten
view-togglebooleanfalse"true" viser skifteren Hold/Kalender
default-viewstring"list""list" eller "calendar" — den visning der vises først (uden view-toggle den eneste)
Eksempel med alle attributterhtml
<holdstyring-schedule
  api-key="DIN_FULDE_API_NØGLE"
  base-url="https://dit-studio.holdstyring.dk"
  hold-type-slugs="yoga,pilates"
  weeks="4"
  title="Vores hold"
  view-toggle="true"
  default-view="calendar"
  theme-primary="#8B5CF6"
></holdstyring-schedule>

Kalendervisningen filtrerer kun på hold-type-slugs; template-id og weeks gælder listen. Giver weeks ingen hold, fortæller widgeten hvornår de næste hold starter. Booking sker i en boks direkte i widgeten — se Booking og betaling.

Alle widgets

De fire ovenfor er de mest brugte. Her er hele kataloget — alle de widget-tags du kan sætte ind, med hver widgets egne attributter. De fleste finder du også i admin under Indstillinger → Widgets("Tilgængelige widgets" med "Kopiér tag", og Widget-byggeren), hvor nøgle og base-url er sat ind.

<holdstyring-schedule>Holdoversigt med bookinghold-type-slugs, template-id, weeks, title, view-toggle, default-view
<holdstyring-login>Log ind, opret konto og glemt passwordIngen egne attributter
<holdstyring-bookings>Kundens kommende bookinger med afmeldingIngen egne attributter
<holdstyring-membership>Klippekort, abonnement og tidligere købIngen egne attributter
<holdstyring-pricing>Prisplaner med køb i widgetenplan-ids, layout="cards|table|compact", title, show-features, category-filter="true", classes-href
<holdstyring-class-types>Holdtyper med «Book hold»hold-type-slugs, max-items, title, show-benefits, show-meta
<holdstyring-instructors>Instruktøroversigtmax-items, title, show-bio, show-specialties
<holdstyring-upcoming-classes>Kommende hold med bookinglimit (1-30, standard 6), title
<holdstyring-weekly-schedule>Ugeplan som liste pr. daghold-type-slugs, title, week-nav="false", layout="grid"
<holdstyring-week-grid>Ugekalender med 7 kolonner (mandag-søndag)hold-type-slugs, title, week-nav="false"
<holdstyring-seasons>Forløb og kurserlayout="cards|detailed"
<holdstyring-treatments>Behandlinger og prisertitle, show-price, show-duration, show-benefits
<holdstyring-rooms>Lokaler og facilitetertitle, show-features
<holdstyring-blog>Seneste blogindlæglimit (1-50, standard 6), show-images
<holdstyring-testimonials>Kundeanmeldelsertitle, max-items
<holdstyring-contact-info>Kontaktoplysninger, åbningstider og korttitle, show-opening-hours
<holdstyring-contact-form>Kontaktformulartitle, subtitle, show-phone
<holdstyring-newsletter>Nyhedsbrev-tilmeldingtitle, subtitle, button-text
<holdstyring-gift-cards>Gavekort med køb i widgetencta-text, cta-link
<holdstyring-waitlists>Ventelister for forløb (tilmelding i widgeten)Ingen egne attributter
<holdstyring-campaign-banner>Kampagnebanneroverride-title
<holdstyring-temperature>Vand- og lufttemperaturtitle, variant="ocean|dark|light", show-last-updated, latitude, longitude
<holdstyring-retreats>Oversigt over retreatsIngen egne attributter
<holdstyring-retreat>Enkelt retreat med bookingretreat-id (påkrævet), hide-image
<holdstyring-klinik-schedule>Klinikhusets ledige behandlingstidertitle
  • Alle widgets tager desuden de samme api-key- og base-url-attributter som eksemplerne ovenfor, plus theme-attributterne (se Tilpasning).
  • Alle show-*-attributter er slået til som standard; skriv ="false" for at skjule. category-filter er omvendt slået fra, indtil du skriver ="true".
  • hold-type-slugs er dine holdmærkater, kommasepareret. classes-href (fx #skema) lader "Se hold" i pris-widgeten blive på din egen side.
  • holdstyring-temperature viser offentlig hav- og lufttemperatur (Open-Meteo) for latitude/longitude; uden koordinater bruges studiets Thermit-sensor, og uden nogen af delene skjuler widgeten sig.
  • holdstyring-klinik-schedule virker kun med nøglen fra klinikhusets ejer-studie. Et klik på en tid åbner klinikkens egen bookingside i en ny fane.

Booking og betaling direkte i widgeten

Dine kunder kan booke, betale og afmelde uden at forlade din hjemmeside. Kun de mere komplekse tilfælde sendes videre til studiets egen side.

Login undervejs

Booking-, holdtype-, kalender- og venteliste-widgets åbner selv en login-boks (log ind eller opret konto), og handlingen fortsætter bagefter. Du behøver ikke holdstyring-login på siden for at kunne booke.

Medlemmer

Har kunden et abonnement eller et klippekort der dækker holdet, bookes det direkte i widgeten. Er holdet fuldt, sendes en klippekortholder dog videre til studiets side for at komme på ventelisten, så klippet bliver reserveret dér.

Drop-in med betaling

Et betalt hold uden dækning betales med det samme: med MobilePay eller med kort via Stripe, alt efter hvad studiet har sat op. Har studiet begge dele, vælger kunden selv mellem MobilePay (Vipps for NOK-studier) og betalingskort, og MobilePay er forvalgt. Er ingen betaling sat op, sendes kunden til studiets bookingside. Booking-boksen har feltet «Har du en rabatkode?».

Fortsæt som gæst

Køb af én drop-in uden konto, når studiet har slået «Walk-in som gæst» til (Indstillinger → Udvidede funktioner → Booking & salg). Gælder kun betalte drop-in-hold, ikke medlemskabshold eller fulde hold.

Gæster

Holdtyper der tillader gæster, får en gæste-tæller. Hver gæst betaler holdets drop-in-pris, også når medlemmet selv er dækket. Rabatkode og gæster kan ikke kombineres.

Klippekort, abonnement og gavekort

«Køb» i holdstyring-pricing og «Køb gavekort» i holdstyring-gift-cards åbner købet i widgeten med MobilePay eller kort via Stripe. Har studiet begge dele, vælger kunden selv, og MobilePay er forvalgt. Gavekort kræver ikke login: 100-5.000 i studiets valuta, navn og e-mail, valgfri modtager-e-mail og hilsen.

Afmelding

Et booket hold kan afmeldes i booking-boksen og i holdstyring-bookings. Studiets afmeldingsregler gælder.

Sendes videre til studiets side

Hold der kræver et medlemskab kunden ikke har, deltagernavne, ansvarsfraskrivelse, intake-spørgsmål første gang, «Book hele holdet», «Book med gæster» (gæste-kategorier eller gæster på klippekort), venteliste på et fuldt hold når kundens klippekort dækker det (klippet reserveres dér), sæsontilmelding samt op-/nedgradering, faste pladser og introtilbud. Studiets side viser så en bjælke med vej tilbage til din side i op til 4 timer (kun fra godkendte domæner).

Tilpasning & Theming

Widgets henter automatisk dit studies primærfarve og designskabelon fra Holdstyring (samme som på studiets egen side — skabelonen bestemmer bl.a. hjørnerne). Du kan overstyre udseendet pr. widget-tag med theme-attributterne herunder.

Tilgængelige theme-attributter

AttributEksempelBeskrivelse
theme-primary#8B5CF6Primærfarve (knapper, links, markeringer) i hex. Overstyrer studiets brandfarve
theme-secondary#1A1A2EAndenfarven i farveovergangene (billeder uden foto, «Populær»-mærket). Standard er en mørk nuance af primærfarven
theme-accent#F59E0BFremhævninger: rammen om den populære prisplan og «i dag» i ugekalenderen. Standard er primærfarven
theme-radius12pxHjørner på kort, knapper og felter, fx 0 for skarpe hjørner. Overstyrer skabelonens hjørner
theme-fontMontserratSkrifttype. Den skal allerede være indlæst på din side; standard er Inter med systemfont som reserve
theme-modeauto"light" (standard), "dark" eller "auto" (følger den besøgendes lyse/mørke tilstand). Ukendte værdier giver light
Eksempel: Lilla tema med Montserrat fonthtml
<holdstyring-schedule
  api-key="DIN_FULDE_API_NØGLE"
  base-url="https://dit-studio.holdstyring.dk"
  theme-primary="#8B5CF6"
  theme-font="Montserrat"
  theme-mode="auto"
></holdstyring-schedule>
Dit studies farver (standard)
Lilla tema
Pink tema

Komplette eksempler

Booking-side med alle widgets

komplet-booking-side.htmlhtml
<!DOCTYPE html>
<html lang="da">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Book en klasse - Mit Yoga Studie</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      max-width: 1200px;
      margin: 0 auto;
      padding: 2rem;
    }
    .widget-section {
      margin-bottom: 3rem;
    }
    h2 {
      margin-bottom: 1rem;
      color: #374151;
    }
    .user-area {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 2rem;
    }
  </style>
</head>
<body>
  <header>
    <h1>Mit Yoga Studie</h1>
    <nav><!-- Din navigation --></nav>
  </header>

  <main>
    <!-- Login / Bruger info -->
    <section class="widget-section">
      <holdstyring-login
        api-key="DIN_FULDE_API_NØGLE"
        base-url="https://dit-studio.holdstyring.dk"
      ></holdstyring-login>
    </section>

    <!-- Holdoversigt -->
    <section class="widget-section">
      <h2>Vores hold</h2>
      <holdstyring-schedule
        api-key="DIN_FULDE_API_NØGLE"
        base-url="https://dit-studio.holdstyring.dk"
        view-toggle="true"
      ></holdstyring-schedule>
    </section>

    <!-- Brugerens dashboard -->
    <section class="widget-section user-area">
      <div>
        <h2>Mine bookinger</h2>
        <holdstyring-bookings api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-bookings>
      </div>
      <div>
        <h2>Mit medlemskab</h2>
        <holdstyring-membership api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-membership>
      </div>
    </section>
  </main>

  <!-- Holdstyring Widget Script -->
  <script src="https://widgets.holdstyring.dk/v1/holdstyring-widgets.min.js" async></script>

  <!-- Event listeners -->
  <script>
    window.addEventListener('holdstyring-widget-login', (e) => {
      console.log('Velkommen,', e.detail.user.firstName)
    })
  </script>
</body>
</html>

Minimal integration (kun holdoversigt)

minimal.htmlhtml
<!-- Tilføj dette hvor du vil vise holdoversigten -->
<holdstyring-schedule api-key="DIN_FULDE_API_NØGLE" base-url="https://dit-studio.holdstyring.dk"></holdstyring-schedule>

<!-- Tilføj scriptet før </body> -->
<script src="https://widgets.holdstyring.dk/v1/holdstyring-widgets.min.js" async></script>

Teknik: events, login og sikkerhed

For dig der bygger siden og vil vide, hvad der sker under motorhjelmen.

Events

Alle events sendes på window — lyt med window.addEventListener(…).

EventHvornårevent.detail
holdstyring-widget-loginKunden er logget ind (i holdstyring-login eller i en login-boks under booking){ user }
holdstyring-widget-registerKunden har oprettet en konto{ user }
holdstyring-widget-logoutKunden har klikket log ud i holdstyring-login-
holdstyring-widget-booking-cancelledKunden har afmeldt en booking i holdstyring-bookings{ bookingId, className }

user indeholder id, email, firstName, lastName og role. Der sendes ikke events for gennemførte bookinger eller betalinger.

Sådan taler widgets med Holdstyring

  • Hver widget kalder <base-url>/api/widget/… med nøglen i headeren X-API-Key. Alle widgets på en side deler ét opstartskald (/api/widget/init), så ti widgets koster ikke ti opstarter.
  • Serveren tjekker i rækkefølge: at nøglen findes og er aktiv → at widgets er slået til for studiet → at sidens domæne (browserens Origin) står på nøglens tilladte domæner.
  • Én forbindelse pr. side: alle widgets på samme side bruger den samme nøgle og base-url. Står der widgets med forskellige nøgler eller adresser på én side (fx en gammel blok), bruger alle widgets den sidst indlæste — typisk med fejl til følge.
  • Login giver et kortlivet adgangstoken (signeret JWT, gyldigt i 15 minutter) og et fornyelsestoken (7 dage), som widgeten selv fornyer og skifter ud ved hver fornyelse. Bliver et allerede brugt fornyelsestoken præsenteret igen, afbrydes hele den login-session. Tokens gemmes i browserens localStorage pr. nøgle, så alle widgets på siden deler login, og kunden forbliver logget ind mellem besøg (op til 7 dage uden brug).
  • Rate limits (fejlkoden RATE_LIMITED): login 5 forsøg pr. minut pr. IP-adresse og 5 pr. time pr. e-mail; kontooprettelse og "Fortsæt som gæst" tilsammen 3 pr. time pr. IP-adresse; glemt password 3 pr. time pr. e-mail; kontaktformular og nyhedsbrev 5 pr. minut. Rabatkode-forsøg og gavekortkøb er også begrænset pr. IP-adresse. Almindelig visning af skema, priser og andet indhold har ingen widget-specifik grænse.

Content-Security-Policy (CSP)

Bruger din side en Content-Security-Policy, skal den tillade widgets:

Eksempel på CSP-tilføjelsertext
script-src  https://widgets.holdstyring.dk
connect-src https://dit-studio.holdstyring.dk
img-src     https://dit-studio.holdstyring.dk
frame-src   https://www.google.com https://maps.google.com https://www.openstreetmap.org

Brug din egen base-url i connect-src og img-src (billeder af hold, instruktører m.m. hentes derfra). frame-src skal kun med, hvis du bruger kortet i holdstyring-contact-info. Betaling sker ved at kunden sendes videre til MobilePay eller Stripe og tilbage igen, så det kræver ingen CSP-ændring. Blokerer CSP'en kaldene, viser widgeten "Could not reach your Holdstyring studio".

Platform-guider

🧩

WordPress: brug vores plugin «Class Booking»

Anbefalet

Den klart nemmeste vej hvis du er på WordPress. Du slipper for at røre footer.php eller indsætte script-tags i hånden — plugin'et står for det hele og sender dit WordPress-domæne til godkendelse med ét klik. Du godkender det under API-nøgler på Widgets-siden, og så virker widgetten.

  1. 1Installer plugin’et «Class Booking Holdstyring» i WordPress (Plugins → Tilføj nyt).
  2. 2Gå til Indstillinger → Class Booking i WordPress, indsæt din fulde API-nøgle og base-url (begge fra Widgets-siden i din Holdstyring-administration), og klik «Forbind og tjek». Plugin’et viser hvilket studie du er forbundet til — og mangler dit WordPress-domæne på nøglen, klikker du «Send domænet til godkendelse». Godkend det derefter under API-nøgler på Widgets-siden i din Holdstyring-administration.
  3. 3Indsæt med Gutenberg-blokken «Class Booking» eller shortcoden [class_booking type="schedule"]. Færdig — og gratis.

Plugin'et dækker typerne schedule, weekly-schedule, upcoming-classes, pricing, class-types, instructors, testimonials, contact-info, contact-form og gift-cards. Shortcoden tager desuden theme-primary, theme-mode, hold-type-slugs, layout, limit og title, fx [class_booking type="pricing" theme-mode="auto"]. Loader-scriptet lægges automatisk i footeren på alle sider, så snart API-nøglen er gemt — vil du bruge en widget plugin'et ikke har (fx login, bookinger eller medlemskab), kan du derfor nøjes med at sætte selve tagget (med api-key og base-url) ind i en «Custom HTML»-blok.

📣 Plugin'et udgives på WordPress.org i disse dage (det er lige nu i review hos WordPress). Så snart det er godkendt, finder du det her: https://wordpress.org/plugins/class-booking-holdstyring/. Indtil da kan du bruge den manuelle metode nedenfor.

Manuel metode (alle platforme)

Foretrækker du at gøre det i hånden — eller er du på en anden platform end WordPress — er det samme to trin overalt: læg loader-scriptet ét sted (helst i footeren, så det ikke bliver strippet), og sæt widget-tags ind hvor de skal vises. Her er de præcise steder pr. platform.

🧩

WordPress

  1. 1Loader-script: Udseende → Temaeditor → footer.php (lige før </body>), eller et plugin som «Insert Headers and Footers» (Footer).
  2. 2Widget-tags: indsæt dem i en «Custom HTML»-blok på den side de skal vises.

⚠️ Vær opmærksom: Læg ALDRIG loader-scriptet i en page-builder-HTML-boks (Elementor, Kubio m.fl.) — den kan strippe scriptet, så widgets aldrig loader. Selve widget-tags må gerne stå i en HTML-boks.

⬛

Squarespace

  1. 1Loader-script: Indstillinger → Avanceret → Code Injection → Footer.
  2. 2Widget-tags: tilføj en «Code Block» på siden og indsæt dem der.

⚠️ Vær opmærksom: Code Blocks kræver et Business-abonnement eller højere — på lavere planer er feltet ikke tilgængeligt.

🔷

Wix

  1. 1Tilføj et «Embed → Embed HTML»-element og indsæt BÅDE loader-scriptet og dine widget-tags i det. Wix viser elementet i en iframe, så et script under «Custom Code» når ikke ind til widgeten.
  2. 2Publicér og åbn siden. Viser widgeten en rød boks med et domæne (fx https://www-mit-studie-dk.filesusr.com), så tilføj præcis det under «Tilladte domæner» på din nøgle. Gentag hvis boksen viser et nyt domæne — Wix kan bruge flere.

⚠️ Vær opmærksom: Det er iframens filesusr.com-domæne, ikke dit eget domæne, der skal stå på nøglen. Giv også Embed-elementet rigelig højde — Wix beskærer indhold der er højere end elementets faste højde.

🌊

Webflow

  1. 1Loader-script: Project Settings → Custom Code → Footer Code.
  2. 2Widget-tags: træk et «Embed»-element ind på siden og indsæt dem.

⚠️ Vær opmærksom: Embed-elementet har en tegngrænse — hold loader-scriptet i site-footeren og kun tags i embed’et.

Fejlfinding

Viser en widget en rød fejlboks i stedet for indhold, står der en engelsk besked i boksen. Find beskeden herunder — så ved du præcis hvad der skal rettes. Koden i parentes står i svaret på kaldet til /api/widget/… (F12 → Network).

⚠️
Udfyld altid «Tilladte domæner» — det er påkrævet

En nøgle kan ikke gemmes uden domæner, for en tom liste afviser ALLE kald (fejlen ORIGIN_NOT_ALLOWED). Skriv mindst ét domæne på nøglen, fx https://www.mit-studie.dk. Mangler der et domæne senere, klikker du "Ret domæner" på nøglen under API-nøgler. Bruger du WordPress-plugin'et, kan det sende sit domæne til godkendelse med ét klik — du godkender det under API-nøgler.

Besked i widgetenHvad betyder det?Sådan retter du det
This website (…) is not on your API key's allow-list (ORIGIN_NOT_ALLOWED)Det domæne siden kører på, står ikke på nøglens tilladte domæner (eller listen er tom).Find nøglen under API-nøgler på Widgets-siden, klik "Ret domæner", tilføj domænet og gem — eller brug WordPress-plugin'ets "Send domænet til godkendelse" og godkend det på nøglen. Nøglen og dine widgets er uændrede, så der skal ikke sættes ny kode ind. Husk at www. og uden www. er to domæner (eller brug *.mit-studie.dk), og test på den publicerede side, ikke i dit CMS' forhåndsvisning.
This website (…) is waiting for the studio's approval (ORIGIN_PENDING_APPROVAL)Domænet har bedt om at vise dine widgets (fx via WordPress-plugin'et), men du har ikke godkendt det endnu. Et domæne bliver aldrig tilføjet automatisk.Find nøglen under API-nøgler på Widgets-siden, og klik "Godkend" ved domænet under "Venter på din godkendelse". Kender du ikke domænet, så klik "Afvis".
Invalid API key. Paste the FULL key… (INVALID_API_KEY)Nøglen er forkert, forkortet eller deaktiveret — eller der står to forskellige nøgler på samme side.Indsæt den fulde nøgle — den vises kun én gang ved oprettelsen. Brug ikke den forkortede wk_live_…... fra nøgle-listen (kopi-ikonet dér kopierer også kun starten). Brug samme nøgle på alle widgets på siden. Er nøglen væk eller deaktiveret, så opret en ny.
An api-key attribute is required (MISSING_API_KEY)api-key-attributten mangler helt på tagget.Tilføj api-key="…" på widget-tagget. Kopiér hele tagget fra admin, så kommer den med.
Widgets are not enabled for this studio (WIDGETS_DISABLED)Widgets er ikke slået til på din konto.Slå "Widgets til egen hjemmeside" til under Indstillinger → Udvidede funktioner → Hjemmeside & indhold, eller klik "Slå widgets til" på Widgets-siden. Uden det afvises kald selv med gyldig nøgle.
Could not resolve the Holdstyring hostWidgeten ved ikke hvilket studie den skal hente fra: base-url mangler (og siden ligger ikke på en *.holdstyring.dk-adresse).Tilføj base-url="https://dit-studio.holdstyring.dk" (eller din class-booking.com-adresse / dit eget domæne) på tagget. Det er ikke en CORS-fejl.
Could not reach your Holdstyring studio (NETWORK_ERROR)Widgeten kunne ikke få forbindelse til adressen i base-url.Tjek at base-url er stavet rigtigt og er dit studies adresse (fx class-booking.com for et Class Booking-studie) — kopiér den fra Widgets-siden. Bruger din side en Content-Security-Policy, så se CSP.
Too many … / For mange forespørgsler (RATE_LIMITED)For mange forsøg på kort tid — fx login, kontooprettelse, kontaktformular eller nyhedsbrev.Vent og prøv igen. Ved login kan spærringen vare op til en time, hvis der er prøvet mange gange med samme e-mail. Se grænserne.
Intet visesTagget står tomt — hverken indhold, spinner eller fejlboks.Loader-scriptet er ikke indlæst: det mangler, er strippet af en page-builder, eller blokeres af en CSP. Tjek F12 → Console for Yoga Widgets v… loaded.
Tom kalenderWidgeten loader fint, men viser ingen hold.Der er ingen kommende hold i perioden, holdene er skjult fra den offentlige kalender eller ligger ud over holdskabelonens bookinghorisont, eller hold-type-slugs, template-id eller weeks er for snævre. Tjek i F12 → Network at kaldet til /api/widget/classes giver 200 og går til din studie-adresse.

Opsætningsfejl som disse vises altid på engelsk, fordi de henvender sig til den der bygger siden. Dine kunder ser dem aldrig, så længe widgeten er sat rigtigt op. (Grænsen for kontaktformular og nyhedsbrev vises på studiets sprog.)

Ofte stillede spørgsmål

Påvirker widgets min sides hastighed?▼
Kun minimalt. Med async blokerer scriptet ikke din side, og alle widgets på siden deler ét opstartskald til Holdstyring. Hver widget henter sine data, så snart den står på siden — også selvom den ligger længere nede.
Kan jeg style widgets med min egen CSS?▼
Nej, ikke direkte. Widgets bruger Shadow DOM, så de er isoleret fra din sides CSS. Du tilpasser dem med theme-attributterne (farver, hjørner, skrifttype og lys/mørk/auto); resten følger studiets designskabelon.
Virker widgets på WordPress/Wix/Squarespace?▼
Ja! Widgets virker på alle platforme der tillader custom HTML. Du skal blot indsætte script-tagget og widget-elementerne. På WordPress er plugin’et «Class Booking Holdstyring» den nemmeste vej.
Hvad sker der hvis min API-nøgle lækker?▼
Nøglen står synligt i din sides kildekode, så den er ikke en hemmelighed. Den virker kun fra de domæner der står på den, og den giver kun adgang til studiets offentlige indhold — kundernes egne data kræver at kunden logger ind. Står der et domæne du ikke kender under nøglens «Domæner», så fjern det med «Ret domæner». Vil du skifte selve nøglen: opret en ny, sæt den ind på dine widgets, og klik «Deaktiver» på den gamle.
Kan jeg have flere widgets på samme side?▼
Ja, du kan have så mange widgets du vil. De deler automatisk login-status, så kunden kun behøver logge ind én gang. Brug den samme nøgle og base-url på alle widgets på siden — blandes to nøgler eller adresser, bruger alle widgets den sidst indlæste, og så fejler kaldene typisk.
Kan jeg rette domænerne på en nøgle?▼
Ja. Klik «Ret domæner» på nøglen under API-nøgler på Widgets-siden, ret listen og gem. Nøglen og dine widgets er uændrede, så der skal ikke sættes ny kode ind på hjemmesiden. Listen skal have mindst ét domæne. WordPress-plugin’et kan sende sit domæne til godkendelse, og du godkender det under API-nøgler.
Kan kunderne betale direkte i widgeten?▼
Ja. Drop-in, gæster, klippekort, abonnement og gavekort betales med MobilePay eller kort (Stripe) direkte fra widgeten. Har studiet begge dele, vælger kunden selv. Mere komplekse køb fortsætter på studiets egen side, med en vej tilbage til din side.
Kan jeg lave en «Book»-knap i stedet for en hel widget?▼
Ja. Widget-byggeren på Widgets-siden har embed-typerne «Knap» og «Flydende knap». De giver et almindeligt link til din bookingside og kræver ikke loader-scriptet.
Understøtter widgets flere sprog?▼
Ja. Widgets følger automatisk dit studies sprog og understøtter dansk, engelsk, tysk, svensk, norsk, spansk og fransk. Du skal ikke sætte noget op. Kun opsætningsfejl — fx en manglende api-key eller base-url — vises altid på engelsk, da de henvender sig til den der bygger siden.

Brug for hjælp?

Vores team er klar til at hjælpe dig med at få det meste ud af dine widgets. Vi tilbyder også gratis opsætningshjælp for nye kunder.

Widget Integration Guide | Holdstyring