> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Main component

> Optional container providing layout slots and automatic state management.

## \<primer-main>

Optional container that provides structured slots for payment methods, checkout completion, and initialization errors. Handles state transitions (loading, success, error) automatically.

## Quick reference

|                   |                                                   |
| ----------------- | ------------------------------------------------- |
| **Parent**        | `<primer-checkout>` (in `main` slot)              |
| **Slots**         | `payments`, `checkout-complete`, `checkout-error` |
| **CSS Variables** | `--primer-space-small`                            |

***

## Examples

### Default (all methods)

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <primer-main slot="main"></primer-main>
</primer-checkout>
```

Renders all available payment methods automatically.

### Custom payment methods

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <primer-main slot="main">
    <div slot="payments">
      <primer-payment-method type="PAYMENT_CARD"></primer-payment-method>
      <primer-payment-method type="PAYPAL"></primer-payment-method>
      <primer-error-message-container></primer-error-message-container>
    </div>
  </primer-main>
</primer-checkout>
```

### Custom success screen

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <primer-main slot="main">
    <div slot="checkout-complete">
      <h2>Thank you for your order!</h2>
      <p>Your payment has been processed.</p>
      <a href="/orders">View Orders</a>
    </div>
  </primer-main>
</primer-checkout>
```

### Custom initialization error screen

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <primer-main slot="main">
    <div slot="checkout-error">
      <h2>We could not load the checkout</h2>
      <p>Please try again later or contact support.</p>
    </div>
  </primer-main>
</primer-checkout>
```

For error details (e.g. to log or branch on the failure), listen for `primer:state-change` and read `primerJsError` from the event detail — see [Error handling](/docs/checkout/primer-checkout/build-your-ui/error-handling).

### Both slots

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <primer-main slot="main">
    <div slot="payments">
      <h2>Choose payment method</h2>
      <primer-payment-method type="PAYMENT_CARD"></primer-payment-method>
    </div>
    <div slot="checkout-complete">
      <h2>Order confirmed!</h2>
    </div>
  </primer-main>
</primer-checkout>
```

***

## Slots

| Slot                | Description                                                        | Default                   |
| ------------------- | ------------------------------------------------------------------ | ------------------------- |
| `payments`          | Payment method area                                                | All available methods     |
| `checkout-complete` | Success screen                                                     | Default success component |
| `checkout-error`    | Shown when the SDK fails to initialize (e.g. invalid client token) | Default error component   |

***

## Events

`<primer-main>` does not emit its own events. It subscribes to parent events internally to manage slot visibility. When bypassing `<primer-main>`, you handle these events yourself.

### Relevant parent events

| Event                   | Emitted by          | How `<primer-main>` uses it                                                                                              |
| ----------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `primer:state-change`   | `<primer-checkout>` | Switches between `payments`, `checkout-complete`, and `checkout-error` slots based on `isSuccessful` and `primerJsError` |
| `primer:methods-update` | `<primer-checkout>` | Populates the `payments` slot with available methods (when slot is not customized)                                       |

### When you bypass `<primer-main>`

If you use a custom `<div slot="main">` instead of `<primer-main>`, you must handle these events directly:

```javascript theme={"dark"}
const checkout = document.querySelector('primer-checkout');

checkout.addEventListener('primer:state-change', (event) => {
  const { isSuccessful, isProcessing } = event.detail;

  if (isSuccessful) {
    document.getElementById('payment-form').hidden = true;
    document.getElementById('success-screen').hidden = false;
  }
});
```

***

## CSS properties

| Property               | Description                 | Default |
| ---------------------- | --------------------------- | ------- |
| `--primer-space-small` | Gap between payment methods | `8px`   |

***

## States

This component automatically manages visibility based on checkout state:

| State          | Description               | Visible Slot                           |
| -------------- | ------------------------- | -------------------------------------- |
| **Loading**    | SDK initializing          | Loading indicator                      |
| **Ready**      | Payment methods available | `payments` slot                        |
| **Processing** | Payment in progress       | `payments` slot (with loading overlay) |
| **Success**    | Payment completed         | `checkout-complete` slot               |
| **Error**      | SDK initialization failed | `checkout-error` slot                  |

***

## Usage guidelines

### Do

* Use for structured customization with automatic state handling
* Include `<primer-error-message-container>` when customizing `payments` slot (for payment failures)
* Provide custom success screen via `checkout-complete` slot
* Provide a custom initialization-failure screen via `checkout-error` slot

### Don't

* Don't use if you need full control over state — use custom `main` slot on `<primer-checkout>` instead
* Don't confuse `checkout-error` (SDK initialization failures) with `<primer-error-message-container>` (payment failures) — see [Error handling](/docs/checkout/primer-checkout/build-your-ui/error-handling)

***

## Alternative: full customization

For complete control, bypass `<primer-main>`:

```html theme={"dark"}
<primer-checkout client-token="your-token">
  <div slot="main">
    <!-- Your implementation -->
    <!-- Must handle state via primer:state-change event -->
  </div>
</primer-checkout>
```

***

## Content guidelines

### Success screen text

| Do                                | Don't                                |
| --------------------------------- | ------------------------------------ |
| "Thank you for your order!"       | "Payment successful" (too technical) |
| "Your payment has been processed" | "Transaction complete"               |

### Section headings

| Do                      | Don't                        |
| ----------------------- | ---------------------------- |
| "Choose payment method" | "SELECT YOUR PAYMENT METHOD" |
| Use sentence case       | Use all caps                 |

***

## See also

<CardGroup cols={2}>
  <Card title="primer-checkout" icon="cube" href="/docs/sdk/primer-checkout-web/components/primer-checkout">
    Parent component
  </Card>

  <Card title="Layout customization" icon="table-layout" href="/docs/checkout/primer-checkout/build-your-ui/layout-customization">
    Slot usage guide
  </Card>

  <Card title="Error handling" icon="triangle-exclamation" href="/docs/checkout/primer-checkout/build-your-ui/error-handling">
    Error display patterns
  </Card>
</CardGroup>
