Lemon Squeezy
Lemon Squeezy is a popular payment gateway that allows you to accept payments online.
Nuxt Scripts provides a useScriptLemonSqueezy() composable and a headless Facade Component <ScriptLemonSqueezy> component to interact with lemon squeezy.
Nuxt Config Setup
Add this to your nuxt.config.ts to load Lemon Squeezy globally. Alternatively you can use the useScriptLemonSqueezy composable for more control.
export default defineNuxtConfig({
scripts: {
registry: {
lemonSqueezy: {
trigger: 'onNuxtReady',
}
}
}
})This config automatically enables first-party mode (proxy). See below to customise.
useScriptLemonSqueezy()
The useScriptLemonSqueezy composable lets you have fine-grain control over when and how Lemon Squeezy is loaded on your site.
const { proxy } = useScriptLemonSqueezy()
proxy.LemonSqueezy.Setup({ eventHandler })Please follow the Registry Scripts guide to learn more about advanced usage.
First-Party Mode: Privacy Focused Proxy
No extra config needed. Runtime requests are reverse-proxied through your server instead of going directly to Lemon Squeezy. User IPs are anonymised and requests work with ad blockers. Learn more.
export default defineNuxtConfig({
scripts: {
// ✅ First-party mode: proxied
registry: {
lemonSqueezy: {
trigger: 'onNuxtReady',
},
},
},
})Example
Using Lemon Squeezy in a component with the proxy to send events .
<script setup lang="ts">
const { proxy } = useScriptLemonSqueezy()
// noop in development, ssr
// just works in production, client
function handleAction() {
proxy.LemonSqueezy.Setup({ eventHandler })
}
</script>
<template>
<div>
<button @click="handleAction">
Send Event
</button>
</div>
</template><ScriptLemonSqueezy>
The <ScriptLemonSqueezy> component is headless Facade Component wrapping the useScriptLemonSqueezy() composable, providing a simple, performance optimized way to load Lemon Squeezy in your Nuxt app.
<template>
<ScriptLemonSqueezy>
<NuxtLink href="https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1">
Buy me - $9.99
</NuxtLink>
</ScriptLemonSqueezy>
</template>
It works by injecting a .lemonsqueezy-button class onto any a tags within the component then loading in
the Lemon Squeezy script with the visibility Element Event Trigger.
Demo
<script lang="ts" setup>
const ready = ref(false)
const events = ref([])
</script>
<template>
<div class="not-prose w-full">
<div class="flex items-center justify-center p-5">
<ScriptLemonSqueezy @lemon-squeezy-event="e => events.push(e)" @ready="ready = true">
<UButton to="https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1" class="block mb-3">
Buy me - $9.99
</UButton>
<UButton to="https://harlantest.lemonsqueezy.com/buy/76bbfa74-a81a-4111-8449-4f5ad564ed76?embed=1" class="block">
Buy me - pay what you want
</UButton>
</ScriptLemonSqueezy>
</div>
<div>
<UAlert v-if="!ready" class="mb-5" size="sm" color="blue" variant="soft" title="Lemon Squeezy is not loaded" description="It loads in when the DOM element is within the viewport." />
<UAlert v-else color="green" variant="soft" title="Lemon Squeezy is loaded">
<template #description>
<div class="mb-2">
Buttons are live and will open the modal, tracking events:
</div>
<div v-for="(event, index) in events" :key="index" class="text-xs">
{{ event.event }}
</div>
</template>
</UAlert>
</div>
</div>
</template>
Component API
See the Facade Component API for full props, events, and slots.
Events
lemon-squeezy-event
Events emitted by the Lemon.js script are forwarded through this event. The payload is an object with an event key and a data key.
export type LemonSqueezyEventPayload = { event: 'Checkout.Success', data: Record<string, any> }
& { event: 'Checkout.ViewCart', data: Record<string, any> }
& { event: 'GA.ViewCart', data: Record<string, any> }
& { event: 'PaymentMethodUpdate.Mounted' }
& { event: 'PaymentMethodUpdate.Closed' }
& { event: 'PaymentMethodUpdate.Updated' }
& { event: string }
useScriptLemonSqueezy()
The useScriptLemonSqueezy() composable lets you have fine-grain control over the Lemon Squeezy SDK. It provides a way to load the Lemon Squeezy SDK and interact with it programmatically.
export function useScriptLemonSqueezy<T extends LemonSqueezyApi>(_options?: LemonSqueezyInput) {}
Please follow the Registry Scripts guide to learn more about advanced usage.
export type LemonSqueezyEventPayload = { event: 'Checkout.Success', data: Record<string, any> }
& { event: 'Checkout.ViewCart', data: Record<string, any> }
& { event: 'GA.ViewCart', data: Record<string, any> }
& { event: 'PaymentMethodUpdate.Mounted' }
& { event: 'PaymentMethodUpdate.Closed' }
& { event: 'PaymentMethodUpdate.Updated' }
& { event: string }Example
Using the Lemon Squeezy SDK with a payment link.
<script setup lang="ts">
const { proxy } = useScriptLemonSqueezy()
onMounted(() => {
proxy.Setup()
})
</script>
<template>
<a href="https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1" class="lemonsqueezy-button">Buy now</a>
</template>