# SnelPlan-reserveringen in elke site, in een paar minuten

> Bron: https://snelplan.nl/integreren
> English version: https://snelplan.nl/integreren.en.md

Bouw je sites voor restaurants, salons of studio's? Gebruik SnelPlan als achterkant. De zaak beheert boekingen, tijden en bevestigingen in SnelPlan, en jij zet één stukje code op de site. Niets na te bouwen, niets te onderhouden.

## Wat je kunt inbouwen

- **De widget**: De boekingspagina van de zaak ín je site: datum, aantal personen of dienst, de vrije tijden en de bevestiging. Groeit vanzelf mee in hoogte, op elke schermbreedte.
- **Een reserveerknop**: Een gewone link die de boekingspagina in een nieuw tabblad opent. Werkt op elke sitebouwer, ook waar scripts niet mogen.
- **Een prompt voor je AI-bouwer**: Bouw je met Base44, Lovable, Claude of v0? Eén prompt met alles erin: de component, waar die moet komen, wat de AI niet mag aanpassen en hoe je test.

## Zo werkt het

1. De zaak zet reserveringen of afspraken aan in SnelPlan en krijgt een adres, zoals `https://jouwzaak.snelplan.nl/boeken`.
2. In SnelPlan, onder Reserveringen, Instellingen, "Op je eigen site", staat de code met dat adres erin, per sitebouwer.
3. Jij plakt die code op de site. Boekingen, bevestigingen en herinneringen lopen via SnelPlan.

## Per sitebouwer

Dezelfde stappen als in SnelPlan zelf, hier met een voorbeeldadres.

### AI-bouwer (Base44, Lovable, Claude, v0, Bolt)

Bouw je je site met een AI? Geef hem deze prompt: daar staat alles in wat hij nodig heeft, met jouw adres erin.

1. Kopieer de prompt.
2. Plak hem in de chat van je bouwer en laat hem het werk doen.
3. Open de nieuwe reserveerpagina, ga naar een andere pagina en kom terug: de widget hoort er weer te staan.

- Werkt de widget niet in de voorbeeldweergave van je bouwer? Kijk dan op de gepubliceerde site: sommige voorbeeldweergaven blokkeren scripts van andere sites.
- Bouw je in een Claude-artifact? Daar laden scripts van andere sites niet. Laat Claude de code voor je echte site schrijven en test het daar.

Code: Prompt voor je AI-bouwer (zie "De code" hieronder).

### WordPress (Blok-editor, Elementor, Divi)

Plak de widget in een HTML-blok op de pagina waar gasten moeten boeken.

1. Open de pagina in de editor en klik op + (blok toevoegen).
2. Kies "Aangepaste HTML" (in Elementor de widget "HTML", in Divi de module "Code").
3. Plak de widgetcode en klik op Bijwerken. Bekijk het resultaat op de gepubliceerde pagina, niet in de editor.

- Alleen beheerders en redacteuren mogen scripts plaatsen; bij anderen haalt WordPress het script weg. Op WordPress.com werkt het alleen met een betaald abonnement waarop plugins aan staan.
- Gebruik je WP Rocket of Autoptimize? Zet `embed.js` bij de uitgesloten scripts, anders verschijnt de widget pas als een bezoeker de pagina aanraakt.
- Lukt het niet? De reserveerknop werkt altijd.

Code: Widget (HTML), Reserveerknop (HTML) (zie "De code" hieronder).

### Wix of Squarespace (Wix, Wix Studio, Squarespace)

Het makkelijkst is een gewone knop van je sitebouwer met je boekingslink erachter. Wil je de widget in de pagina zelf, gebruik dan een codeblok.

1. Wix: voeg een knop toe, klik op het link-icoon, kies "Webadres", plak je boekingslink en kies openen in een nieuw venster.
2. Squarespace: voeg een knop-blok toe, plak je boekingslink en zet "Openen in nieuw tabblad" aan.
3. Liever ingebouwd? In Wix: Toevoegen, Code insluiten, HTML insluiten; plak de widgetcode en maak het vak minstens 900 pixels hoog. In Squarespace: een Code-blok met de widgetcode.

- Wix zet ingebouwde code in een eigen kader met een vaste hoogte: de widget groeit daar niet vanzelf mee. Daarom is de knop op Wix de beste keus.
- Squarespace voert scripts alleen uit op een Core-, Plus- of Advanced-abonnement, en toont ze niet zolang je bent ingelogd: bekijk de pagina in een privévenster.

Code: Je boekingslink (`https://jouwzaak.snelplan.nl/boeken?via=embed`), Widget (HTML) (zie "De code" hieronder).

### Zelf in code (HTML, React, Next.js, Vue)

Zet de div waar de widget moet komen en laad het script één keer. Het script vindt de widget ook als die later verschijnt, bijvoorbeeld na een route-wissel.

1. Gewone HTML: plak de widgetcode op de plek van de widget.
2. React of Next.js: maak de component aan en zet `<SnelplanBooking />` op je reserveerpagina.
3. Geen vaste hoogte, geen `sandbox` en geen eigen iframe: de widget bepaalt zelf zijn hoogte.

- Vue, Svelte of Angular: zet alleen de div in de template en laad het script één keer, in `index.html` of bij het mounten van de component. Een `<script>`-tag in een template laat zo'n framework weg.
- Heeft je site een Content-Security-Policy? Sta het adres van de boekingspagina toe in `script-src` en `frame-src`.
- Staat de widget in een shadow root? Roep dan `window.SnelplanBooking.mount(element)` aan.

Code: Widget (HTML), React-component (zie "De code" hieronder).

## De code

Met het voorbeeldadres `https://jouwzaak.snelplan.nl/boeken`. De code van een echte zaak staat in haar instellingen en is precies hetzelfde, alleen met haar eigen adres.

### Widget (HTML)

Plak dit waar de widget moet komen. Het script zet de boekingspagina erin en laat haar meegroeien. Eén keer laden is genoeg, ook in een app met route-wissels.

```html
<div data-snelplan-booking="https://jouwzaak.snelplan.nl/boeken"></div>
<script src="https://jouwzaak.snelplan.nl/embed.js" async></script>
```

### React-component

Voor React, Next.js en de AI-bouwers die React maken. Zet `<SnelplanBooking />` waar de widget moet komen.

```jsx
'use client'
import { useEffect } from 'react'

const BOOKING_URL = 'https://jouwzaak.snelplan.nl/boeken'
const SCRIPT_URL = 'https://jouwzaak.snelplan.nl/embed.js'

export default function SnelplanBooking() {
  useEffect(() => {
    if (document.querySelector(`script[src="${SCRIPT_URL}"]`)) return
    const script = document.createElement('script')
    script.src = SCRIPT_URL
    script.async = true
    document.body.appendChild(script)
  }, [])

  return <div data-snelplan-booking={BOOKING_URL} />
}
```

### Reserveerknop (HTML)

Werkt overal: een gewone link, geen script.

```html
<a href="https://jouwzaak.snelplan.nl/boeken?via=embed" target="_blank" rel="noopener" style="display:inline-block;padding:12px 24px;border-radius:12px;background:#9a3412;color:#ffffff;font:600 16px/1.2 system-ui,-apple-system,sans-serif;text-decoration:none">Reserveren</a>
```

### Prompt voor je AI-bouwer

Plak dit in de chat van je AI-bouwer. In de instellingen van de zaak staat dezelfde prompt met het echte adres, en in proefmodus met de testlink.

````
Zorg dat bezoekers van deze website online een tafel kunnen reserveren.

Het boeken zelf draait op SnelPlan; de website toont alleen de widget van SnelPlan. Bouw dus geen eigen boekingsformulier, agenda, database of e-mails, en vraag niet om een API-sleutel: die is niet nodig.

1. Maak een React-component `SnelplanBooking` (bestand `SnelplanBooking.jsx` bij de andere componenten, of `SnelplanBooking.tsx` in een TypeScript-project) met precies deze code:

```jsx
'use client'
import { useEffect } from 'react'

const BOOKING_URL = 'https://jouwzaak.snelplan.nl/boeken'
const SCRIPT_URL = 'https://jouwzaak.snelplan.nl/embed.js'

export default function SnelplanBooking() {
  useEffect(() => {
    if (document.querySelector(`script[src="${SCRIPT_URL}"]`)) return
    const script = document.createElement('script')
    script.src = SCRIPT_URL
    script.async = true
    document.body.appendChild(script)
  }, [])

  return <div data-snelplan-booking={BOOKING_URL} />
}
```

2. Maak een pagina "Reserveren" (of hetzelfde in de taal van de site) op het pad `/reserveren`, met een korte kop en daaronder `<SnelplanBooking />` over de volle breedte van de inhoud. Laat elke bestaande knop of link om te boeken naar die pagina gaan; staat er nog geen in het menu, zet hem er dan in. Heeft de site maar één pagina? Zet de widget dan in een sectie met id `reserveren` en laat die knoppen daarheen scrollen.

Is dit geen React-project? Gewone HTML of WordPress: zet in plaats van de component deze code op de plek waar de widget moet komen. Vue, Svelte, Angular of een ander framework: zet alleen de div in de template van de pagina en laad het script één keer, in `index.html` of bij het mounten van de component (zoals de React-component hierboven doet); een `<script>`-tag in een template laat zo'n framework weg.

```html
<div data-snelplan-booking="https://jouwzaak.snelplan.nl/boeken"></div>
<script src="https://jouwzaak.snelplan.nl/embed.js" async></script>
```

Niet aanpassen:
- Neem het adres `https://jouwzaak.snelplan.nl/boeken` en het script `https://jouwzaak.snelplan.nl/embed.js` letterlijk over.
- Geen eigen `<iframe>`, geen `sandbox` en geen vaste hoogte, `height` of `overflow: hidden` op de widget of de div eromheen: de widget bepaalt zelf zijn hoogte.
- Laad het script niet via `dangerouslySetInnerHTML` of een `<script>`-tag in JSX of in een template. Gebruik je de React-component, zet het dan niet nog eens in `index.html`: de component laadt het één keer, en daarna vindt het script de widget ook na een paginawissel.
- Laat de div leeg: het script vult hem.
- Heeft de site een Content-Security-Policy? Sta dan `https://jouwzaak.snelplan.nl` toe in `script-src` en `frame-src`.

Testen:
1. Open `/reserveren` (op een site met één pagina: de sectie `#reserveren`): binnen een paar seconden staat de widget er (datum, aantal personen en de vrije tijden).
2. Heeft de site meer pagina's? Ga dan naar een andere pagina en weer terug: de widget staat er opnieuw.
3. Laadt de widget niet in de voorbeeldweergave van de bouwer? Kijk dan op de gepubliceerde site: sommige voorbeeldweergaven blokkeren scripts van andere sites.
4. De zaak is live: elke boeking is echt. Maak dus geen testboeking, of annuleer hem meteen via de link in de bevestigingsmail.
````

## Eerst uitproberen: de proefmodus

Een zaak kan haar boekingspagina eerst in proefmodus zetten. Ze krijgt dan een geheime testlink, en de code in haar instellingen bevat die testlink. Zet die code op je testsite: alles werkt zoals straks, maar elke boeking is een testboeking. Die telt nergens mee, de gast krijgt alleen een testmail en er gaat geen sms of WhatsApp de deur uit. Zoekmachines vinden de testpagina niet.

Staat de site al openbaar online? Maak de pagina met de widget dan wel, maar link er pas naartoe als de zaak live is: anders boeken echte bezoekers testboekingen. Gaat de zaak live, dan blijft dezelfde code werken en wordt er vanaf dat moment echt geboekt. Opnieuw plakken hoeft niet. Gaat de zaak later terug naar de proefmodus, dan krijgt ze een nieuwe testlink; de widget op de echte site laat in die tijd zien dat online boeken even niet kan. Heeft de zaak ook een website bij SnelPlan, dan moet die gepubliceerd zijn voordat de widget gasten toont.

Zet de zaak haar pagina offline, dan toont de widget een rustige melding met het telefoonnummer of e-mailadres van de zaak, in plaats van een lege plek of een foutpagina. Zodra de pagina weer live staat, werkt dezelfde widget weer.

## Veelgestelde vragen

### Hoe hoog wordt de widget?

Zo hoog als nodig. Het script begint op 720 pixels en past de hoogte aan zodra de pagina geladen is, ook na het boeken. Zet dus geen vaste hoogte. Zonder script, bijvoorbeeld in het kader van Wix, kies je de hoogte zelf: reken op zo'n 900 pixels.

### Mijn site heeft een Content-Security-Policy. Wat moet ik toestaan?

Het adres van de boekingspagina, in `script-src` (voor `embed.js`) en in `frame-src` (voor de iframe). Bij een adres op snelplan.nl is dat `https://*.snelplan.nl`; heeft de zaak een eigen domein, dan dat domein. Andersom mag de boekingspagina alleen in embed-modus worden ingelijst, en daar zorgt de code zelf voor.

### Plaatst de widget cookies? Hoe zit het met de AVG?

Het script en de boekingspagina plaatsen geen cookies en volgen bezoekers niet, dus voor de widget hoef je je cookiemelding niet aan te passen. Wat een gast invult (naam, e-mail, telefoon) gaat rechtstreeks naar SnelPlan, niet naar je site: tussen de widget en je site gaat alleen de hoogte heen en weer. SnelPlan verwerkt die gegevens in opdracht van de zaak en slaat ze op in de EU; voor een paar taken, zoals het versturen van de bevestigingsmail, werken we met verwerkers buiten de EU, met de standaardcontractbepalingen van de Europese Commissie als waarborg. De volledige lijst staat in de privacyverklaring.

### Kan ik de widget een eigen kleur of letter geven?

De widget neemt de merkkleur van de zaak over. Meer stijlknoppen, zoals letter en hoeken, komen later in de instellingen. Eigen CSS in de widget kan bewust niet: zo blijft hij werken en toegankelijk bij elke update van SnelPlan, wat er ook op de site eromheen staat.

### Werkt het in een app die de pagina zelf opbouwt, zoals React, Vue of Next.js?

Ja. Laad het script één keer; het vindt de widget ook als die later verschijnt of na een route-wissel opnieuw wordt geplaatst. Voor React is er een kant-en-klare component. Staat de widget in een shadow root, roep dan `window.SnelplanBooking.mount(element)` aan.

### Kan ik twee zaken of vestigingen op één pagina zetten?

Ja: zet twee divs, elk met hun eigen adres. Eén script is genoeg.

### In welke taal staat de widget?

In de taal van de zaak. Wil je een andere taal die de zaak aanbiedt, zet dan bijvoorbeeld `data-lang="en"` op de div.

### Ziet de zaak welke boekingen via mijn site binnenkwamen?

Ja. De zaak ziet in SnelPlan per kanaal hoeveel boekingen er deze maand binnenkwamen; de widget telt als "Widget op je site". Met `data-via` op de div tel je de boeking onder een ander bestaand kanaal, zoals `data-via="instagram"` (of google, facebook, apple, whatsapp, qr). Een andere waarde telt als "Overig".

### Wat als het adres van de zaak verandert?

Kiest de zaak een ander adres, dan werkt de oude code niet meer: plak dan de nieuwe code uit haar instellingen. Krijgt de zaak er een eigen domein bij, dan blijft de oude code werken: het oude adres stuurt door. Heeft je site een Content-Security-Policy, zet dat eigen domein dan ook in `frame-src`, anders blokkeert de browser de doorverwijzing.

## Bouw je sites voor zaken? Word partner

Wil je SnelPlan bij meer klanten inzetten, hulp bij een eerste integratie of meedenken over wat er nog ontbreekt? We werken graag samen met webbouwers. Neem contact op, dan bespreken we hoe.

- [Neem contact op](https://snelplan.nl/help/contact?subject=Partner%20worden%20als%20webbouwer&category=general)
- Of mail naar support@snelplan.nl
