---
title: "Vue"
description: "Integrate Inttegro Checkout as embedded content or inside an application-owned dialog in Vue."
canonical: "https://studio.inttegro.com/web/vue"
format: inttegro-machine-docs/v1
language: "Python"
sdk_version: "v12.0.0"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/python/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 585
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "curated"
recommended_mcp_tools: ["design_integration","check_integration_readiness"]
estimated_tokens: 2609
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** Use the Vue component with a backend-created Order ID, treat emitted lifecycle events as UI signals, and let the backend verify payment after checkout.

### Five questions

#### Q1. What must the Vue page receive from its backend?

Only the finalized Order ID needed by Checkout. Keep API credentials, customer payment details, and decisions about line items and amount in the trusted backend; [Orders](https://studio.inttegro.com/machine/python/api/orders.md#create-an-order) defines creation and [web setup](https://studio.inttegro.com/machine/python/web.md) describes the handoff.

#### Q2. Which package and presentation does Vue use?

Install @inttegro/vue and render its documented Checkout component for embedded or modal presentation; a hosted-page handoff does not mount the component. Choose one path in [the Vue guide](https://studio.inttegro.com/machine/python/web/vue.md#choose-and-render-a-presentation) before wiring lifecycle events.

#### Q3. What does the completed event mean?

Use @completed for UI or navigation, then ask the backend to [look up the Order](https://studio.inttegro.com/machine/python/api/orders.md#lookup-an-order) before fulfillment. Handle the documented error and other lifecycle signals separately; [events](https://studio.inttegro.com/machine/python/web/vue.md#handle-emitted-events) are not a replacement for server state.

#### Q4. How do updates and server rendering affect Checkout?

A changed Order ID, features, timeout, or title creates a new Checkout instance; supported appearance/locale changes can update an active one. Server rendering produces an empty host; the adapter mounts Checkout after client hydration. See [routes and server rendering](https://studio.inttegro.com/machine/python/web/vue.md#use-routes-and-server-rendering).

#### Q5. What can an integration agent verify first?

With an authenticated MCP connection, [design_integration](https://studio.inttegro.com/machine/python/inttegro-mcp/tools.md#design_integration) can plan the backend/browser boundary and [check_integration_readiness](https://studio.inttegro.com/machine/python/inttegro-mcp/tools.md#check_integration_readiness) can audit declared secret, idempotency, and lookup controls. Compile the Vue example and test success, cancellation, and failure with disposable orders.

## Document content

# Inttegro for Vue

Use `@inttegro/vue` to render Inttegro-hosted Checkout with Vue props, emitted
events, exposed controls, and lifecycle cleanup.

## Prerequisites

- Vue 3.4 or newer
- A backend that [creates](https://studio.inttegro.com/machine/python/api/orders.md#create-an-order) and
  [finalizes](https://studio.inttegro.com/machine/python/api/orders.md#finalize-an-order) an Inttegro Order
- A client-safe finalized Order ID or Purchase Intent ID

## Install the component

> Web Sdk Install Tabs is interactive content. Use the canonical page to view it.

## Choose and render a presentation

The [Nuxt live demo](https://nuxt-demo.inttegro.dev) uses `@inttegro/vue` for
both presentations while keeping Order creation in Nitro; its
[released Vue plugin](https://github.com/inttegro/inttegro-demos/blob/nuxt-v1.8.3/nuxt/plugins/inttegro-checkout.client.ts)
shows the adapter boundary. Compare the presentations below, then use the
matching implementation that follows. Open any screenshot at full size when you
need to inspect the layout.

> Demo Presentation Gallery is interactive content. Use the canonical page to view it.

Both presentations use the same `Checkout` component and finalized Order. Vue
templates use kebab-case for multiword props and events.

### Embedded

Choose embedded Checkout for a dedicated payment route, checkout step, or
invoice layout where the form should remain visible. Your Vue template owns the
component's position and surrounding content; Inttegro owns the hosted payment
surface inside it.

```vue
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { Checkout } from '@inttegro/vue'

defineProps<{ orderId: string }>()
const router = useRouter()
const message = ref('')

function handleError(error: Error) {
  message.value = error.message
}
</script>

<template>
  <main>
    <h1>Complete your order</h1>
    <section aria-label="Payment">
      <Checkout
        :appearance="{ theme: 'system' }"
        :order-id="orderId"
        locale="en-GH"
        @completed="router.push('/payment-status')"
        @error="handleError"
      />
    </section>
    <p aria-live="polite">{{ message }}</p>
  </main>
</template>
```

Keep `Checkout` mounted while payment or provider confirmation is in progress.
Your layout controls the
outer element's width and placement; merchant CSS does not reach the hosted
controls. Let Checkout report its own height; avoid fixed heights or overflow
clipping on the payment region.

### Modal

Choose a modal when payment starts from a button and the current page should
remain mounted underneath. Your application owns the dialog, trigger, close
control, focus restoration, and scrolling. Use `v-if` so the same `Checkout`
component exists only while the dialog is open.

```vue
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { Checkout } from '@inttegro/vue'

defineProps<{ orderId: string }>()
const router = useRouter()
const dialog = ref<HTMLDialogElement | null>(null)
const open = ref(false)
const message = ref('')

function openDialog() {
  open.value = true
  dialog.value?.showModal()
}

function handleError(error: Error) {
  message.value = error.message
}
</script>

<template>
  <button :disabled="open" @click="openDialog">Pay now</button>
  <dialog ref="dialog" aria-labelledby="payment-title" @close="open = false">
    <h2 id="payment-title">Complete payment</h2>
    <button type="button" @click="dialog?.close()">Close</button>
    <Checkout
      v-if="open"
      :appearance="{ theme: 'system' }"
      :order-id="orderId"
      @completed="router.push('/payment-status')"
      @error="handleError"
    />
  </dialog>
  <p aria-live="polite">{{ message }}</p>
</template>
```

Closing the application dialog resets `open`; Vue then unmounts `Checkout` and
releases its controller and subscriptions. Keep the dialog open while a payment
attempt or provider confirmation is in progress.

## Start from a Buy link

Pass a Buy link's public Purchase Intent instead of creating a finalized Order:

```vue
<Checkout :purchase-intent-id="purchaseIntentId" />
```

Use the same prop with `presentation="modal"` for the managed modal experience.
Checkout renders the full Buy experience and creates the finalized Order only
after the buyer continues. Payment then continues in the same component.
Provide either `order-id` or `purchase-intent-id`, never both.

The component also accepts `features`, `timeout`, and `title`. `features`
controls line-item visibility, post-payment invoice and receipt actions, and
whether an attached payment method can be replaced. Changing `appearance` or
`locale` updates the active Checkout. Changing `features`, `orderId`,
`purchaseIntentId`, `timeout`, or `title` creates a new instance.

## Handle emitted events

| Event       | Emitted when                                            |
| ----------- | ------------------------------------------------------- |
| `canceled`  | The payer leaves managed modal Checkout.                |
| `completed` | Checkout reaches its successful terminal experience.    |
| `error`     | Loading or mounting fails before Checkout can continue. |
| `event`     | Any privacy-safe lifecycle event is received.           |
| `failed`    | Checkout reaches a terminal failure.                    |
| `ready`     | Checkout is ready for customer interaction.             |

The `error` event contains an `Error` for loader or mount failures. The `event`
event receives the canonical Checkout lifecycle, including recoverable
`paymentAttemptFailed` events and the terminal `completed`, `canceled`, and
`failed` events. Order-backed events carry the full client-safe Order.

Use these events for interface state and telemetry. Before fulfillment, have
your backend [look up the Order](https://studio.inttegro.com/machine/python/api/orders.md#lookup-an-order); the `completed` event
alone is not authoritative money state.

## Focus or update Checkout

Use a template ref to call the exposed `focus()` method:

```vue
<script setup lang="ts">
import { ref } from 'vue'
import { Checkout } from '@inttegro/vue'

defineProps<{ orderId: string }>()

const checkout = ref<{ focus(): void } | null>(null)

function focusCheckout() {
  checkout.value?.focus()
}
</script>

<template>
  <Checkout ref="checkout" :order-id="orderId" @ready="focusCheckout" />
</template>
```

The component also exposes `update()`, which accepts only `appearance` and
`locale`. Prefer reactive props when these values already live in Vue state.

## Use routes and server rendering

The adapter waits for Vue's `onMounted` hook before loading Checkout. With
server rendering, the server produces the empty host element and the adapter
mounts the hosted experience after client hydration.

## Related resources

- [JavaScript runtime and loader](https://studio.inttegro.com/machine/python/web/javascript.md) - Review options, events,
  CSP, and modal behavior.
- [Inertia](https://studio.inttegro.com/machine/python/web/inertia.md) - Use this component with an Inertia Vue frontend.
- [Web Checkout overview](https://studio.inttegro.com/machine/python/web.md) - Prepare the server and verify payment state.
