Loading and preloading
Keep catalog and payment interactions fast without losing package code splitting.
Separate entry points keep Stripe out of catalog pages.
Route-level split
import type { LockerversePaymentSelectionItem } from "@lockerverse/react/payment";
import { useLockerverseWidget } from "@lockerverse/react/widget";
import { lazy, Suspense } from "react";
import "@lockerverse/react/payment.css";
const Payment = lazy(() =>
import("@lockerverse/react/payment").then((module) => ({
default: module.LockerversePayment,
}))
);
const selection: LockerversePaymentSelectionItem[] = [
{ productSlug: "ticket", quantity: 1 },
];
function CheckoutSkeleton() {
return <p aria-live="polite">Loading secure checkout…</p>;
}
export function CheckoutRoute() {
const widget = useLockerverseWidget({
communitySlug: "your-community",
widgetSlug: "your-widget",
});
return (
<Suspense fallback={<CheckoutSkeleton />}>
<Payment selection={selection} widget={widget} />
</Suspense>
);
}Preload on intent
import type { LockerverseCatalog } from "@lockerverse/sdk/checkout";
let paymentModule: ReturnType<typeof importPayment> | undefined;
function importPayment() {
return import("@lockerverse/react/payment");
}
export async function preloadPayment(catalog: LockerverseCatalog) {
paymentModule ??= importPayment();
const { preloadLockerversePayment } = await paymentModule;
return preloadLockerversePayment(catalog);
}
Call preloadPayment(catalog) on checkout pointerenter, focus, or when the
cart becomes valid. The browser reuses both the payment module and the Stripe
load when React renders payment. LockerverseDonateLauncher does this
automatically when its dialog opens.