Skip to main content

Documentation Index

Fetch the complete documentation index at: https://danestvesllc-2b77d201.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The embedded checkout renders Polar’s checkout form in an overlay on top of your page rather than redirecting the customer away. This keeps your branding in view throughout the payment flow and typically improves conversion rates. The package ships a Blade directive, a Blade component, and an HTML data- attribute — covering Blade, Inertia, React, and Vue with minimal setup.
How it differs from hosted checkout: Instead of returning a redirect from your controller, you pass the checkout URL to your view and render a button with data-polar-checkout. The Polar JavaScript library intercepts the click and opens the overlay.

Setup

1

Add the embed script to your layout

Include the @polarEmbedScript directive inside the <head> tag of your layout. This loads the Polar JavaScript library that intercepts clicks and renders the overlay:
<head>
    ...
    @polarEmbedScript
</head>
The directive outputs a single <script> tag that defers loading and auto-initialises, so it does not block page rendering.
2

Create the checkout with an embed origin

In your controller or route, build the checkout session and call withEmbedOrigin with your application’s URL. This tells Polar’s iframe which origin is allowed to communicate with it:
use Illuminate\Http\Request;

Route::get('/billing', function (Request $request) {
    $checkout = $request->user()
        ->checkout(['product_id_123'])
        ->withEmbedOrigin(config('app.url'));

    return view('billing', ['checkout' => $checkout]);
});
Do not call redirect() or return the $checkout directly — pass it to the view so the front end can use the URL.
3

Render the button in your Blade view

Use the <x-polar-button> component. Pass the $checkout object and the component resolves the URL and wires up the data-polar-checkout attribute automatically:
<x-polar-button :checkout="$checkout">
    Upgrade to Pro
</x-polar-button>
The component renders an <a> tag. You can pass any standard HTML attribute and it will be forwarded to the anchor element.

Changing the theme

The embedded checkout defaults to a light colour scheme. To use a dark scheme, pass the data-polar-checkout-theme attribute:
<x-polar-button :checkout="$checkout" data-polar-checkout-theme="dark">
    Upgrade to Pro
</x-polar-button>

Inertia.js

For Inertia applications you cannot use the Blade component directly. Instead, pass the checkout URL as a prop and add the data-polar-checkout attribute to any <a> tag. The Polar script picks up the attribute and opens the overlay on click:
<!-- resources/js/Pages/Billing.vue -->
<template>
  <a :href="checkoutUrl" data-polar-checkout>
    Upgrade to Pro
  </a>
</template>

<script setup>
defineProps({
  checkoutUrl: String,
});
</script>
// resources/js/Pages/Billing.jsx
export default function Billing({ checkoutUrl }) {
  return (
    <a href={checkoutUrl} data-polar-checkout>
      Upgrade to Pro
    </a>
  );
}
Pass data-polar-checkout-theme="dark" on the element if you want the dark colour scheme.
The data-polar-checkout attribute is what the Polar JavaScript library looks for. As long as the @polarEmbedScript directive is present in the page <head> and your <a> tag carries data-polar-checkout, the overlay will open regardless of whether you are using Blade, Inertia, or a fully client-side framework.

Passing the checkout URL from the server

When using Inertia, share the checkout URL from your controller:
use Illuminate\Http\Request;

Route::get('/billing', function (Request $request) {
    $checkoutUrl = $request->user()
        ->checkout(['product_id_123'])
        ->withEmbedOrigin(config('app.url'))
        ->url();

    return inertia('Billing', [
        'checkoutUrl' => $checkoutUrl,
    ]);
});
Calling ->url() triggers an API call to Polar every time it is invoked. Cache the result if the same URL is rendered on repeated requests.