Custom storefront14 examples
Composition / Development
Custom storefront
Keep the product UI in the host and open native checkout.
Previewlight site theme
Loading storefront…
CodeApp.tsx
import {
LockerversePayment,
type LockerversePaymentSelectionItem,
type LockerversePaymentTheme,
} from "@lockerverse/react/payment";
import "@lockerverse/react/payment.css";
import { useLockerverseWidget } from "@lockerverse/react/widget";
import { useState } from "react";
import { exampleRuntime } from "../example-runtime";
const widgetOptions = {
apiBaseUrl: exampleRuntime.apiBaseUrl,
communitySlug: exampleRuntime.communitySlug,
environment: "development" as const,
sentryDsn: null,
widgetSlug: exampleRuntime.widgetSlug,
};
function formatMoney(amountCents: number | null) {
if (amountCents === null) {
return "Choose amount";
}
return new Intl.NumberFormat("en-US", {
currency: "USD",
style: "currency",
}).format(amountCents / 100);
}
export default function CustomStorefrontExample({
theme = "light",
}: {
theme?: LockerversePaymentTheme;
}) {
const widget = useLockerverseWidget(widgetOptions);
const [selection, setSelection] =
useState<LockerversePaymentSelectionItem | null>(null);
if (selection) {
return (
<div className="storefront-checkout">
<button
className="example-secondary-button"
onClick={() => setSelection(null)}
type="button"
>
← Products
</button>
<LockerversePayment
selection={[selection]}
style={{ "--lockerverse-accent": "#f1511b" }}
theme={theme}
widget={widget}
/>
</div>
);
}
if (widget.loading) {
return <p className="example-status">Loading storefront…</p>;
}
if (widget.error) {
return <p className="example-status">{widget.error.message}</p>;
}
if (!widget.catalog) {
return null;
}
return (
<div className="storefront-grid">
{widget.catalog.products.map((product) => (
<button
className="storefront-product"
key={product.id}
onClick={() =>
setSelection(
product.pricingMode === "custom"
? {
amountCents: product.minimumAmountCents ?? 100,
productSlug: product.slug,
}
: { productSlug: product.slug, quantity: 1 }
)
}
type="button"
>
<span>{product.name}</span>
<strong>{formatMoney(product.amountCents)}</strong>
</button>
))}
</div>
);
}