JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q44227F
  • License MIT

Vue components and composables for QueueZero viral waitlists

Package Exports

  • @queuezero/vue

Readme

@queuezero/vue

Vue components and composables for QueueZero viral waitlists.

Installation

npm install @queuezero/vue

Quick Start

<script setup>
import { provideWaitlist, WaitlistForm, WaitlistStatus, ReferralShare } from '@queuezero/vue';

// Get referral code from URL if present
const referrerCode = new URLSearchParams(window.location.search).get('ref');

// Provide waitlist to all child components
provideWaitlist('my-campaign', { 
  apiUrl: 'https://api.queuezero.io' 
});
</script>

<template>
  <WaitlistForm 
    :referrer-code="referrerCode"
    @success="(res) => console.log('Joined!', res)"
  />
  <WaitlistStatus />
  <ReferralShare show-social-buttons />
</template>

Plugin Usage

For app-wide integration:

import { createApp } from 'vue';
import { createWaitlistPlugin } from '@queuezero/vue';

const app = createApp(App);

app.use(createWaitlistPlugin({
  campaign: 'my-campaign',
  config: { apiUrl: 'https://api.queuezero.io' }
}));

app.mount('#app');

Components

WaitlistForm

Ready-to-use signup form.

<template>
  <!-- Basic -->
  <WaitlistForm />

  <!-- With options -->
  <WaitlistForm
    :referrer-code="referrerCode"
    :metadata="{ role: 'Developer' }"
    placeholder="Enter your work email"
    button-text="Get Early Access"
    @success="onSuccess"
    @error="onError"
  />

  <!-- With scoped slot -->
  <WaitlistForm v-slot="{ email, setEmail, submit, loading, error }">
    <input :value="email" @input="setEmail($event.target.value)" />
    <button @click="submit">{{ loading ? '...' : 'Join' }}</button>
  </WaitlistForm>
</template>

WaitlistStatus

Displays position, score, and referral count.

<template>
  <!-- Basic -->
  <WaitlistStatus />

  <!-- With options -->
  <WaitlistStatus
    :show-score="true"
    :show-referrals="true"
    position-label="Your position:"
  />

  <!-- With scoped slot -->
  <WaitlistStatus v-slot="status">
    <h2>#{{ status.position }}</h2>
    <p>{{ status.priority_score }} points</p>
  </WaitlistStatus>
</template>

ReferralShare

Share referral link with copy and social buttons.

<template>
  <!-- Basic -->
  <ReferralShare />

  <!-- With social buttons -->
  <ReferralShare 
    show-social-buttons 
    share-message="Join me on this awesome waitlist!" 
  />

  <!-- With scoped slot -->
  <ReferralShare v-slot="{ link, code, copy, copied }">
    <code>{{ code }}</code>
    <button @click="copy">{{ copied ? 'Copied!' : 'Copy' }}</button>
  </ReferralShare>
</template>

Composables

useWaitlist

Standalone composable for full control.

<script setup>
import { useWaitlist } from '@queuezero/vue';

const { status, loading, join, getReferralLink } = useWaitlist('my-campaign', {
  apiUrl: 'https://api.queuezero.io',
});

async function handleSubmit(email) {
  await join(email, { role: 'Developer' });
}
</script>

provideWaitlist / useWaitlistContext

For component tree sharing.

<!-- Parent.vue -->
<script setup>
import { provideWaitlist } from '@queuezero/vue';

provideWaitlist('my-campaign');
</script>

<!-- Child.vue -->
<script setup>
import { useWaitlistContext } from '@queuezero/vue';

const { status, join } = useWaitlistContext();
</script>

Styling

Components use qz-* class names:

.qz-form { }
.qz-form-row { display: flex; gap: 8px; }
.qz-form-input { flex: 1; padding: 12px; }
.qz-form-button { padding: 12px 24px; }
.qz-form-error { color: red; }

.qz-status { display: flex; gap: 16px; }
.qz-status-label { font-size: 12px; }
.qz-status-value { font-size: 24px; font-weight: bold; }

.qz-share-input { flex: 1; }
.qz-share-social { display: flex; gap: 8px; }

TypeScript

Full TypeScript support:

import type { 
  UseWaitlistReturn,
  WaitlistFormProps,
  UserStatus 
} from '@queuezero/vue';

License

MIT