Booking widget
The booking widget puts a rental's whole booking flow on the rental's own site: the search, the car types, insurance, extras, the driver's details, the payment and the confirmation. It is one script and one tag. It works on any site that takes HTML: plain pages, WordPress, Squarespace, Webflow, Next.js, Nuxt, and pages from a CMS such as Prismic or Sanity.
Code
A booking made through the widget lands on the rental's Website channel, at that channel's prices, as any other booking in Mellow.
Before you start
- In Mellow, open Settings · Widget and press Add widget. Pick the Website channel the site sells for. Mellow makes the widget's keys.
- Under Sites, add each site that shows the widget, such as
https://www.example.com. A widget takes at most 10 sites, https only. The live key works only from these sites. - The Install card gives the code above with your rental's slug and live key. Copy code copies it.
- The Test card gives the same code with the test key. Use it on your own machine first: see Test key.
The live key needs an online payment processor on the rental in Mellow, as the customer pays on the last step.
The flow
- Search. Pickup and return location, dates and times, and an optional driver age and coupon.
- Car type. The car types for the search, each with its price.
- Insurance. Levels, packages and add-on covers, laid out from what the rental sells, with the excess for each peril and the deposit.
- Extras. Extras, and packages that hold no insurance.
- Driver. The customer's details.
- Pay. A bot check, then a hold on one car at a fixed total, then the payment on the hold in the processor's own form.
- Done. The processor's paid webhook makes the booking from the hold. The page shows the reference and links to manage the booking and to check in online.
Before Pay, the order is a cart in the browser. It keeps no car. Pay holds one car for 15 minutes.
A search on the home page
The search can stand alone and send the customer to the booking page. Give it the rental and the key, and the booking page's path in action:
Code
The search goes to /book in the address, and the booking opens on the car types.
Your own markup
An element with no child elements draws Mellow's default content. An element with child elements draws nothing of its own: it binds your children. Thus you can start with the one tag, and later take over one part at a time. This page gives the car types your own card and leaves every other step as it is:
Code
Elements lists every part.
One car type on its own page
A car type's own page gets a search for that car type only. Give <mellow-search> the car type's slug, id or code in car-type, and the booking page in action. Once a location, both dates and both times are set, it shows the price, such as "ISK 82,800 for 5 days", with Book. Book opens the booking page with the search and the car type chosen, on the insurance step. When the car type is not free on those dates, the search says so and offers See other campers (or cars), which opens the booking page's car type step for the same dates. The customer can also change the dates.
Code
<mellow-car-type> and the other parts outside a booking or a search read the first one on the page, here the search. Put <mellow-booking> on /book.
To book on the car type's page itself, put the <mellow-car-type> in a booking that has no car type step. It chooses itself, and the steps follow on the same page:
Code
The script
https://mllw.is/widget/1/mellow.js defines every element. Any Mellow host serves the same script, and the script calls the API on its own host. The 1 is the version of the elements. A new build of version 1 reaches every site within 5 minutes, and the address does not change. Two copies of the script on one page do no harm.
The script is about 118 kB, 35 kB with gzip. Load it with type="module": a module script waits for the page, so it never blocks the first paint.
Languages
locale sets the language: en, is, de, fr, es or it. Without it the widget reads the page's <html lang>, and then takes English. Prices and dates follow the language, and the money is the rental's currency.
Types for React and Vue
The tags and their attributes come as TypeScript types, for JSX in React 19 and for Vue templates:
https://mllw.is/widget/1/types/elements.d.ts: the attributes and the events.https://mllw.is/widget/1/types/react.d.ts: the tags in React's JSX.https://mllw.is/widget/1/types/vue.d.ts: the tags in Vue templates, with@mellow-bookedfor an event.
Save the three files in your project, in one folder. The Next.js and Nuxt recipes use them.
The browser key goes in auth. React and Vue both keep key for themselves and never put it on an element, so auth works in every framework. An older snippet with key still works in plain HTML.
A site with a Content-Security-Policy
The bot check at Pay runs in a small frame on Mellow's host, https://mllw.is/widget/1/check. A site whose Content-Security-Policy names its frames must allow that host in frame-src. Without it the frame does not load, and Pay stops with "The security check did not pass." The script, the Plain preset's stylesheet and the API come from the same host, so script-src, style-src and connect-src take it too:
Code
The Plain preset writes the rental's look in a <style> tag, which 'unsafe-inline' allows. The processor's card form adds its own hosts. The site no longer needs Cloudflare's Turnstile host: the frame loads Turnstile itself.
The frame opens only on the widget's own sites, and on localhost for the test key.
Next
- Elements: every element, its attributes and its state.
- Events and the store: what the widget tells your page, and how your code drives it.
- Look: the Plain preset, its tokens, and your own CSS.
- Pages and paths: one page for each step, and your own router.
- Recipes: the widget on each kind of site.