Web SDKOne page, whole journey

One page, whole journey

There are two ways to embed DriveCars, and they ship the same bundles, the same components and the same money rules. Pick one:

Four elementsOne element
PagesFour — a listing, a vehicle page, a basket, a checkoutOne
Tags<drivecars-search>, <drivecars-car>, <drivecars-cart>, <drivecars-checkout><drivecars-journey>
NavigationBetween your own URLsNone — the element swaps steps in place
PaymentOn your checkout pageA step inside the element — the card form, then the confirmation, swapped in place like every other step
Used bydrivecars.ai itself

Neither is a downgrade. The four-element integration fits a site that already has routes and wants the widget inside them; the single element fits a site that wants a booking flow dropped into one page.

The whole thing

<drivecars-journey
  environment="sandbox"
  country="ma"
  city="casablanca"
></drivecars-journey>
 
<script src="https://sdk.drivecars.ai/v1/loader.js"></script>
<script src="https://sdk.drivecars.ai/v1/sdk.js"></script>
<script>
  // Your backend mints this. The client_secret never reaches the browser.
  const session = await fetch('/your/session-route', { method: 'POST' }).then((r) => r.json());
  DriveCars.init({ session, environment: 'sandbox' });
  DriveCars.mount('journey', document.querySelector('drivecars-journey'));
</script>

That is the integration. There is no second page to build and no event to listen for — the element owns every hop.

How it moves

  1. Search. The customer searches and sees results.
  2. Vehicle detail, in place. Clicking a result swaps the step; the URL does not change. The dates and hours they already chose carry across, so nothing is asked twice.
  3. Back returns to the results with filters and scroll intact — the search step stays mounted, so nothing is refetched.
  4. Basket, once a car is added.
  5. Payment, in a modal, when they continue.

Attributes

The union of what the composed elements take. Every one is optional except a publishable key if you want payment to work.

Attribute
environmentproduction (default) or sandbox. Decides the API host.
base-urlOverrides environment. For local development.
token, customer-tokenSet by DriveCars.mount(); you rarely write these.
country, citySeed the search.
date-from, date-toYYYY-MM-DD. Seed the dates.
pickup-hour, return-hour023.
driver-age, car-groupSeed the remaining search fields.
lang, display-currencyAs elsewhere.
maps-keyMap tiles on the results step.

Events

Event
bookingCreatedA draft booking exists; detail.reference is its reference. Useful for your own analytics.
dc:analyticsEvery analytics event the composed elements emit.
tokenRefreshNeededThe session needs refreshing, as elsewhere.

You do not need to listen for anything to make the journey work. That is the point of this integration.

One thing worth knowing about the payment step

The card form cannot mount inside a shadow root. On the payment step it therefore renders into the light DOM — two nodes placed immediately after the element, the card form and then the pay button — rather than inside the element’s own tree. They carry their own inline styles for the same reason: your stylesheet applies to them, and the widget’s compiled one does not.

If you style .dc-journey-payment-modal, style it as part of your own page.

Can I use both?

On the same page, no — mount either <drivecars-journey> or the four elements. They would otherwise compete for the same cart.

Across a site, yes: nothing stops a single-element booking widget on a landing page and the four-element integration in a fuller flow elsewhere.