Inttegro with Inertia
Inertia applications use the Inttegro adapter for their frontend renderer.
There is no separate Inertia package: React applications use
@inttegro/react, Vue applications use @inttegro/vue, and Svelte
applications use @inttegro/svelte.
Prerequisites
- An Inertia application using React, Vue, or Svelte
- The corresponding Inttegro adapter installed with npm, Yarn, Bun, or Deno
- A backend that creates and finalizes an Inttegro Order
Choose the renderer adapter
| Inertia frontend | Inttegro package | Installation and usage |
|---|---|---|
| React | @inttegro/react | React guide |
| Vue | @inttegro/vue | Vue guide |
| Svelte | @inttegro/svelte | Svelte guide |
The adapter already depends on @inttegro/js. Inttegro does not publish a
separate Inertia package.
Pass the Order ID as a page prop
Create and finalize the Order in the server-side controller or action that prepares the Inertia response. Return only the client-safe Order ID needed by the page. Do not include your secret API key, payment method data, or unnecessary customer details in page props.
Whichever server adapter you use, expose the same small page-prop contract:
export interface CheckoutPageProps {
orderId: string
}
Then pass orderId to the Checkout component for your renderer. A React page,
for example, needs no Inertia-specific Inttegro API.
For a Buy link, return purchaseIntentId as the page prop instead. Pass it to
the same renderer adapter in place of orderId. Fixed pricing continues
directly to payment; customer-selected pricing first collects the amount. Never
pass both references.
Choose and render a presentation
An Inertia-specific live demo has not been released. The Express live demo shows the same hosted payment surface in both presentations; its released presentation controller shows the server-to-browser boundary. Compare the presentations below, then use the matching React implementation that follows or translate it using the linked Vue and Svelte component conventions. Open any screenshot at full size when you need to inspect the layout.
- Desktop
- Mobile
Select any image to view it full screen.
The examples below use the React adapter. Vue and Svelte pages use the same page-prop boundary with the component syntax in the Vue and Svelte guides.
- Embedded
- Modal
Choose embedded Checkout when the Inertia visit leads to a dedicated payment page or checkout step. The page component owns the surrounding layout and keeps Checkout mounted until payment finishes or navigation deliberately ends the flow.
import { router } from '@inertiajs/react'
import { Checkout } from '@inttegro/react'
import { useState } from 'react'
interface CheckoutPageProps {
orderId: string
}
export default function CheckoutPage({ orderId }: CheckoutPageProps) {
const [message, setMessage] = useState('')
function handleError(error: Error) {
setMessage(error.message)
}
return (
<main>
<h1>Complete your order</h1>
<Checkout
orderId={orderId}
onCompleted={() => router.visit('/payment-status')}
onError={handleError}
/>
<p aria-live="polite">{message}</p>
</main>
)
}
Avoid replacing the page component while payment or provider confirmation is in progress; an Inertia visit unmounts the adapter and destroys that Checkout instance.
Choose a modal when payment begins from an action on a cart, order, or account page that should remain mounted underneath. The page owns the dialog, trigger, close control, focus restoration, scrolling, and open state. Inttegro owns the isolated payment surface inside it.
import { router } from '@inertiajs/react'
import { Checkout } from '@inttegro/react'
import { useRef, useState } from 'react'
interface OrderPageProps {
orderId: string
}
export default function OrderPage({ orderId }: OrderPageProps) {
const dialog = useRef<HTMLDialogElement>(null)
const [open, setOpen] = useState(false)
const [message, setMessage] = useState('')
function openDialog() {
setOpen(true)
dialog.current?.showModal()
}
function handleError(error: Error) {
setMessage(error.message)
}
return (
<>
<button disabled={open} onClick={openDialog}>
Pay now
</button>
<dialog
ref={dialog}
aria-labelledby="payment-title"
onClose={() => setOpen(false)}
>
<h2 id="payment-title">Complete payment</h2>
<button type="button" onClick={() => dialog.current?.close()}>
Close
</button>
{open ? (
<Checkout
orderId={orderId}
onCompleted={() => router.visit('/payment-status')}
onError={handleError}
/>
) : null}
</dialog>
<p aria-live="polite">{message}</p>
</>
)
}
When the application dialog closes, reset open; React then unmounts the
adapter and releases its controller and subscriptions. Keep the dialog open
while a payment attempt or provider confirmation is in progress.
The features prop is optional and controls line-item visibility, post-payment
document links, and whether the payer may replace an attached payment method.
Handle navigation and payment state
When the page component unmounts during an Inertia visit, the framework adapter destroys its Checkout instance and removes its subscription. If Checkout lives inside a persistent layout, remove it when payment collection ends rather than leaving a completed instance mounted across unrelated pages.
Changing orderId or purchaseIntentId creates a fresh Checkout instance.
Keep the reference in server-provided page props instead of preserving a stale
value in local component state.
Use the completed callback to visit a payment-status route or update the
interface. That callback does not authorize fulfillment. The status route
should have your backend look up the Order and act on
the current server-side state.
Related resources
- React, Vue, and Svelte - Install the adapter and follow its native component conventions.
- JavaScript runtime and loader - Review the shared runtime, lifecycle contract, CSP, and modal behavior.
- Web Checkout overview - Prepare the server and verify payment state.