import { ref } from 'vue' // Wraps Klaviyo's legacy client-side list-subscribe endpoint. // Klaviyo requires any non-standard property names to be declared in `$fields` // for them to be persisted on the profile — this composable handles that for you. const ENDPOINT = 'https://manage.kmail-lists.com/ajax/subscriptions/subscribe' export default () => { const loading = ref(false) const success = ref(false) const error = ref('') const reset = () => { loading.value = false success.value = false error.value = '' } const subscribe = async ({ listId, email, firstName, lastName, name, source, properties = {}, } = {}) => { if (!listId) { error.value = 'Missing listId' return } if (!email) { error.value = 'Missing email' return } loading.value = true error.value = '' // `name` is a convenience: first token → first_name, rest → last_name let fName = firstName let lName = lastName if (name && !fName && !lName) { const parts = name.trim().split(/\s+/) fName = parts.shift() lName = parts.join(' ') || undefined } const body = { g: listId, email } if (fName) body.first_name = fName if (lName) body.last_name = lName const extraFields = [] if (source) { body.$source = source extraFields.push('$source') } for (const [key, value] of Object.entries(properties)) { if (value === undefined || value === null || value === '') continue body[key] = value extraFields.push(key) } if (extraFields.length) body.$fields = extraFields.join(',') try { await $fetch(ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Cache-Control': 'no-cache', }, body: new URLSearchParams(body), }) success.value = true } catch (err) { console.error('useKlaviyo subscribe error', err) error.value = err?.toString().split('Error: ')[1] || 'Subscription failed' } loading.value = false } // Fires a Klaviyo event (metric) — append-only history, good for things // segments will slice on like "Submitted RSVP" with per-event properties. // Throws on failure; doesn't touch the shared loading/success/error refs, // so callers can pair it with subscribe() without state collisions. const track = ({ email, metric, properties = {} }) => { if (!email || !metric) { throw new Error('useKlaviyo.track: email and metric are required') } return $fetch('/api/klaviyo-track', { method: 'POST', body: { email, metric, properties }, }) } return { loading, success, error, subscribe, track, reset, } }