Storefront Embedding Guide
Embed Renta's rental booking experience into any website.
Renta's storefront can be embedded into any website, allowing customers to browse inventory and book rentals without leaving your site.
Embedding Options
| Option | Best For | Complexity |
|---|---|---|
| Renta Hosted Storefront | Full standalone rental site | None — just configure in Dashboard |
| Embeddable Widget | Adding rental to an existing website | Low — drop in a <script> tag |
| Custom with Storefront API | Full control over UI/UX | High — build your own using the API |
Option 1: Embeddable Widget
The simplest way to add rental booking to your existing website.
Add the embed script
<div id="renta-widget"></div>
<script
src="https://getrenta.io/embed/widget.js"
data-tenant="your-tenant-slug"
data-container="renta-widget"
async
></script>Configure the widget
<script
src="https://getrenta.io/embed/widget.js"
data-tenant="your-tenant-slug"
data-container="renta-widget"
data-theme="light"
data-primary-color="#C4572A"
data-show-categories="true"
data-default-pickup-location="loc_main"
async
></script>Widget Attributes
| Attribute | Required | Description |
|---|---|---|
data-tenant | ✅ | Your tenant slug |
data-container | ✅ | ID of the container element |
data-theme | — | light or dark (default: light) |
data-primary-color | — | Override primary brand color |
data-show-categories | — | Show category filter (default: true) |
data-default-pickup-location | — | Pre-select a pickup location |
Option 2: Custom Storefront API Integration
Build a fully custom booking experience using the Storefront API with a publishable key.
Install the SDK
npm install @renta/sdkInitialize the storefront client
import { RentaStorefront } from '@renta/sdk/storefront';
export const storefront = new RentaStorefront({
apiKey: process.env.NEXT_PUBLIC_RENTA_PK!, // renta_pk_live_...
});Build the inventory browser
'use client';
import { useEffect, useState } from 'react';
import { storefront } from '@/lib/renta';
export function RentalBrowser({
pickupDate,
returnDate,
}: {
pickupDate: string;
returnDate: string;
}) {
const [items, setItems] = useState([]);
useEffect(() => {
storefront.inventory({ pickup_date: pickupDate, return_date: returnDate })
.then(res => setItems(res.data));
}, [pickupDate, returnDate]);
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{items.map(item => (
<div key={item.id} className="border rounded-lg p-4">
{item.photos[0] && (
<img src={item.photos[0].url} alt={item.name} className="w-full rounded" />
)}
<h3 className="font-semibold mt-2">{item.name}</h3>
<p className="text-gray-600">{item.description}</p>
<p className="text-lg font-bold mt-2">
${(item.calculated_price / 100).toFixed(2)}
</p>
{item.available ? (
<button className="mt-2 bg-[#C4572A] text-white px-4 py-2 rounded">
Add to Booking
</button>
) : (
<span className="text-red-500">Unavailable</span>
)}
</div>
))}
</div>
);
}Handle the booking flow
import { storefront } from '@/lib/renta';
import { loadStripe } from '@stripe/stripe-js';
export async function completeBooking({
paymentIntentId,
pickupDate,
returnDate,
lineItems,
addons,
}: {
paymentIntentId: string;
pickupDate: string;
returnDate: string;
lineItems: Array<{ fleet_item_id: string }>;
addons?: Array<{ addon_id: string; quantity: number }>;
}) {
const result = await storefront.book({
payment_intent_id: paymentIntentId,
pickup_date: pickupDate,
return_date: returnDate,
line_items: lineItems,
addons,
});
return result;
}The publishable key (renta_pk_...) is safe to include in client-side code. It only has access to storefront endpoints — no admin data.
Security
- Publishable keys only — Never use secret keys in client-side code
- Payment via Stripe — Card data goes directly to Stripe, never to your server or Renta
- CORS — Storefront API endpoints allow cross-origin requests from any origin
- Rate limits — Publishable keys are limited to 100 requests/minute
Next Steps
- Storefront Endpoints — full endpoint reference
- Theming — customize the look and feel
- Payments API — payment intent creation