@signup-storm/sdk
v1.0.0
Published
TypeScript SDK for Signup Storm API integration
Maintainers
Readme
Signup Storm TypeScript SDK
A comprehensive TypeScript SDK for integrating Signup Storm email signup functionality into your applications and landing pages.
Features
- 🚀 Easy Integration - Simple API for email signups and management
- 🎯 Attribution Tracking - Automatic UTM parameter capture
- 📱 Browser Utilities - Form integration and widget creation
- 🔒 Type Safety - Full TypeScript support with comprehensive types
- 🎨 Customizable - Flexible styling and behavior options
- 📊 Event System - Listen to signup events and responses
- 🌐 Universal - Works in browser and Node.js environments
- ⚡ Lightweight - Zero dependencies, small bundle size
Installation
npm install @signup-storm/sdkyarn add @signup-storm/sdkpnpm add @signup-storm/sdkQuick Start
Basic Usage
import { SignupStorm } from '@signup-storm/sdk';
const client = new SignupStorm({
apiKey: 'your-api-key',
baseUrl: 'https://your-signup-samurai-instance.com'
});
// Subscribe an email
const response = await client.signup({
email: '[email protected]',
list: 'newsletter',
tags: ['landing-page', 'early-access']
});
console.log('Signup successful:', response);Browser Integration
import { createBrowserClient } from '@signup-storm/sdk';
const { client, browser } = createBrowserClient({
apiKey: 'your-api-key',
baseUrl: 'https://your-signup-samurai-instance.com'
});
// Integrate with existing form
browser.integrateForm({
form: '#signup-form',
list: 'newsletter',
onSuccess: (response) => {
console.log('User subscribed:', response.email);
},
onError: (error) => {
console.error('Signup failed:', error.message);
}
});API Reference
SignupStorm Client
Constructor
new SignupStorm(config: SignupStormConfig)Config Options:
apiKey(string, required) - Your API keybaseUrl(string, required) - Your Signup Storm instance URLtimeout(number, optional) - Request timeout in milliseconds (default: 10000)headers(object, optional) - Custom headers to include with requestsdebug(boolean, optional) - Enable debug logging (default: false)
Methods
signup(request: SignupRequest): Promise<SignupResponse>
Subscribe an email address to a list.
const response = await client.signup({
email: '[email protected]',
list: 'newsletter',
tags: ['blog', 'early-access'],
utm: {
source: 'twitter',
medium: 'social',
campaign: 'launch'
},
customFields: {
firstName: 'John',
company: 'Acme Corp'
}
});SignupRequest Properties:
email(string, required) - Email address to subscribelist(string, optional) - List slug to subscribe totags(string[], optional) - Tags to apply to the subscriberutm(UTMParameters, optional) - UTM parameters for attributionpageUrl(string, optional) - URL where signup occurred (auto-detected in browser)referrer(string, optional) - Referrer URL (auto-detected in browser)customFields(object, optional) - Custom fields to store with subscriberipAddress(string, optional) - IP address (auto-detected if not provided)userAgent(string, optional) - User agent (auto-detected in browser)consentTimestamp(string, optional) - GDPR consent timestampgdprConsent(boolean, optional) - GDPR consent status
unsubscribe(request: UnsubscribeRequest): Promise<UnsubscribeResponse>
Unsubscribe an email address from a list or globally.
const response = await client.unsubscribe({
email: '[email protected]',
list: 'newsletter', // Optional - omit for global unsubscribe
reason: 'No longer interested'
});getSubscriberStatus(email: string): Promise<SubscriberStatus>
Check the subscription status of an email address.
const status = await client.getSubscriberStatus('[email protected]');
console.log('Status:', status.status); // 'subscribed', 'unsubscribed', etc.
console.log('Lists:', status.lists);
console.log('Tags:', status.tags);Event System
Listen to SDK events:
client.on('signup:success', (event) => {
console.log('Signup successful:', event.data);
});
client.on('signup:error', (event) => {
console.error('Signup failed:', event.data);
});
client.on('request:start', (event) => {
console.log('Request started:', event.data.type);
});Available Events:
signup:success- Successful signupsignup:error- Signup errorunsubscribe:success- Successful unsubscribeunsubscribe:error- Unsubscribe errorrequest:start- Request startedrequest:complete- Request completed
Browser Utilities
Form Integration
Integrate with existing HTML forms:
const cleanup = browser.integrateForm({
form: '#my-form', // Form selector or element
emailField: 'email', // Email input name/selector (default: 'email')
list: 'newsletter',
tags: ['website'],
customFields: {
firstName: '[name="first_name"]',
company: '[name="company"]'
},
onSuccess: (response) => {
// Handle success
showSuccessMessage('Thanks for subscribing!');
},
onError: (error) => {
// Handle error
showErrorMessage(error.message);
},
onLoading: (loading) => {
// Handle loading state
toggleLoadingSpinner(loading);
},
preventDefault: true, // Prevent default form submission
showLoadingState: true, // Show loading on submit button
disableFormDuringSubmission: true // Disable form during submission
});
// Call cleanup when done
cleanup();Widget Creation
Create embedded signup widgets:
const widget = browser.createWidget({
container: '#signup-container',
list: 'newsletter',
tags: ['widget'],
placeholder: 'Enter your email address',
buttonText: 'Subscribe Now',
successMessage: 'Thanks for subscribing!',
cssClasses: {
container: 'my-signup-widget',
form: 'signup-form',
input: 'email-input',
button: 'subscribe-btn',
success: 'success-message',
error: 'error-message'
},
styles: {
container: {
padding: '20px',
borderRadius: '8px',
backgroundColor: '#f5f5f5'
},
input: {
padding: '12px',
fontSize: '16px',
border: '1px solid #ddd',
borderRadius: '4px'
},
button: {
padding: '12px 24px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}
}
});Auto-Capture
Automatically capture emails from forms on the page:
const cleanup = browser.autoCapture({
selector: 'input[type="email"]', // Email input selector
lists: ['newsletter'], // Auto-subscribe to these lists
tags: ['auto-capture'],
onCapture: (email) => {
console.log('Email captured:', email);
}
});
// Call cleanup when done
cleanup();Utilities
Email Validation
import { validateEmail } from '@signup-storm/sdk';
if (validateEmail('[email protected]')) {
console.log('Valid email');
}UTM Parameter Extraction
import { extractUTMFromURL, extractUTMFromCurrentPage } from '@signup-storm/sdk';
// Extract from specific URL
const utm = extractUTMFromURL('https://example.com?utm_source=twitter&utm_medium=social');
// Extract from current page (browser only)
const currentUTM = extractUTMFromCurrentPage();Browser Detection
import { isBrowser } from '@signup-storm/sdk';
if (isBrowser()) {
// Browser-specific code
console.log('Running in browser');
}Examples
React Integration
import React, { useEffect, useRef } from 'react';
import { createBrowserClient } from '@signup-storm/sdk';
const SignupForm: React.FC = () => {
const formRef = useRef<HTMLFormElement>(null);
const [message, setMessage] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
const { browser } = createBrowserClient({
apiKey: process.env.REACT_APP_SIGNUP_SAMURAI_API_KEY!,
baseUrl: process.env.REACT_APP_SIGNUP_SAMURAI_URL!
});
const cleanup = browser.integrateForm({
form: formRef.current!,
list: 'newsletter',
onSuccess: () => {
setMessage('Thanks for subscribing!');
setLoading(false);
},
onError: (error) => {
setMessage(error.message);
setLoading(false);
},
onLoading: setLoading
});
return cleanup;
}, []);
return (
<div>
<form ref={formRef}>
<input
type="email"
name="email"
placeholder="Enter your email"
required
/>
<button type="submit" disabled={loading}>
{loading ? 'Subscribing...' : 'Subscribe'}
</button>
</form>
{message && <p>{message}</p>}
</div>
);
};Vue.js Integration
<template>
<form ref="signupForm" @submit.prevent>
<input
type="email"
name="email"
placeholder="Enter your email"
required
/>
<button type="submit" :disabled="loading">
{{ loading ? 'Subscribing...' : 'Subscribe' }}
</button>
<p v-if="message">{{ message }}</p>
</form>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { createBrowserClient } from '@signup-storm/sdk';
const signupForm = ref<HTMLFormElement>();
const message = ref('');
const loading = ref(false);
let cleanup: (() => void) | null = null;
onMounted(() => {
const { browser } = createBrowserClient({
apiKey: import.meta.env.VITE_SIGNUP_SAMURAI_API_KEY,
baseUrl: import.meta.env.VITE_SIGNUP_SAMURAI_URL
});
cleanup = browser.integrateForm({
form: signupForm.value!,
list: 'newsletter',
onSuccess: () => {
message.value = 'Thanks for subscribing!';
loading.value = false;
},
onError: (error) => {
message.value = error.message;
loading.value = false;
},
onLoading: (isLoading) => {
loading.value = isLoading;
}
});
});
onUnmounted(() => {
cleanup?.();
});
</script>Node.js Server Usage
import { SignupStorm } from '@signup-storm/sdk';
const client = new SignupStorm({
apiKey: process.env.SIGNUP_SAMURAI_API_KEY!,
baseUrl: process.env.SIGNUP_SAMURAI_URL!
});
// API endpoint for server-side signups
app.post('/api/signup', async (req, res) => {
try {
const { email, list, tags } = req.body;
const response = await client.signup({
email,
list,
tags,
ipAddress: req.ip,
userAgent: req.get('User-Agent'),
pageUrl: req.get('Referer')
});
res.json({ success: true, data: response });
} catch (error) {
res.status(400).json({
success: false,
error: error.message
});
}
});Error Handling
The SDK throws SignupStormError for API-related errors:
import { SignupStormError } from '@signup-storm/sdk';
try {
await client.signup({ email: 'invalid-email' });
} catch (error) {
if (error instanceof SignupStormError) {
console.log('Error code:', error.code);
console.log('HTTP status:', error.status);
console.log('Message:', error.message);
console.log('Details:', error.details);
}
}TypeScript Support
The SDK is written in TypeScript and provides comprehensive type definitions:
import type {
SignupRequest,
SignupResponse,
UTMParameters,
SubscriberStatus
} from '@signup-storm/sdk';
const request: SignupRequest = {
email: '[email protected]',
list: 'newsletter',
utm: {
source: 'twitter',
medium: 'social'
}
};Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone the repository
git clone https://github.com/yourusername/signup-samurai.git
cd signup-samurai/packages/sdk
# Install dependencies
pnpm install
# Start development mode
pnpm dev
# Run tests
pnpm test
# Run linting
pnpm lintPublishing (Maintainers Only)
The SDK is published to npm as @signup-storm/sdk. To publish a new version:
# Using the publish script (recommended)
./scripts/publish.sh
# Or manually
pnpm version patch # or minor/major
pnpm prepublishOnly # runs tests, linting, and build
npm publishThe package follows semantic versioning and includes automated checks before publishing.
License
This SDK is licensed under the MIT License. See LICENSE for details.
Support
- Documentation: https://docs.signup-samurai.com
- Issues: GitHub Issues
- Discord: Join our community
Made with ❤️ by Applied Designs, LLC
