Express / Node.js

Integrate Stack0 with Express or any Node.js application.

Installation

Terminal
npm install @stack0/sdk express

Basic Setup

server.ts
import express from 'express'
import { Stack0 } from '@stack0/sdk'
const app = express()
app.use(express.json())
const stack0 = new Stack0({
apiKey: process.env.STACK0_API_KEY!
})
// Send a single email
app.post('/api/send-email', async (req, res) => {
const { to, subject, html } = req.body
try {
const result = await stack0.mail.send({
from: 'noreply@yourdomain.com',
to,
subject,
html,
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to send email' })
}
})
app.listen(3000, () => {
console.log('Server running on port 3000')
})

Email Templates

Use templates for consistent email formatting:

routes/email.ts
import { Router } from 'express'
import { stack0 } from '../lib/stack0'
const router = Router()
// Send with template
router.post('/send-order-confirmation', async (req, res) => {
const { email, orderNumber, items, total } = req.body
try {
const result = await stack0.mail.send({
from: 'orders@yourdomain.com',
to: email,
subject: `Order Confirmation #${orderNumber}`,
templateId: 'order-confirmation',
templateVariables: {
orderNumber,
items,
total,
},
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to send confirmation' })
}
})
// Send password reset
router.post('/send-password-reset', async (req, res) => {
const { email, resetToken } = req.body
const resetUrl = `https://yourdomain.com/reset?token=${resetToken}`
try {
const result = await stack0.mail.send({
from: 'security@yourdomain.com',
to: email,
subject: 'Reset Your Password',
html: `
<h1>Password Reset Request</h1>
<p>Click the link below to reset your password:</p>
<a href="${resetUrl}">Reset Password</a>
<p>This link expires in 1 hour.</p>
`,
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to send reset email' })
}
})
export default router

Batch Sending

Send multiple emails efficiently:

routes/notifications.ts
import { Router } from 'express'
import { stack0 } from '../lib/stack0'
const router = Router()
// Send batch notifications
router.post('/notify-users', async (req, res) => {
const { users, message } = req.body
try {
const result = await stack0.mail.sendBatch({
emails: users.map((user: { email: string; name: string }) => ({
from: 'notifications@yourdomain.com',
to: user.email,
subject: 'New Notification',
html: `<p>Hi ${user.name},</p><p>${message}</p>`,
})),
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to send notifications' })
}
})
// Send broadcast (same content to multiple recipients)
router.post('/send-newsletter', async (req, res) => {
const { subscribers, subject, content } = req.body
try {
const result = await stack0.mail.sendBroadcast({
from: 'newsletter@yourdomain.com',
to: subscribers,
subject,
html: content,
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to send newsletter' })
}
})
export default router

File Uploads

Handle file uploads with the CDN:

routes/upload.ts
import { Router } from 'express'
import { stack0 } from '../lib/stack0'
const router = Router()
// Get presigned upload URL
router.post('/get-upload-url', async (req, res) => {
const { filename, mimeType, size } = req.body
try {
const result = await stack0.cdn.getUploadUrl({
filename,
mimeType,
size,
})
res.json(result)
} catch (error) {
res.status(500).json({ error: 'Failed to generate upload URL' })
}
})
// Confirm upload complete
router.post('/confirm-upload', async (req, res) => {
const { assetId } = req.body
try {
await stack0.cdn.confirmUpload({ assetId })
res.json({ success: true })
} catch (error) {
res.status(500).json({ error: 'Failed to confirm upload' })
}
})
export default router

Error Handling Middleware

Add proper error handling for Stack0 operations:

middleware/error.ts
import { Request, Response, NextFunction } from 'express'
export function errorHandler(
error: Error,
req: Request,
res: Response,
next: NextFunction
) {
console.error('Error:', error.message)
// Handle Stack0 specific errors
if (error.message.includes('rate limit')) {
return res.status(429).json({
error: 'Too many requests',
message: 'Please slow down and try again later',
})
}
if (error.message.includes('unauthorized')) {
return res.status(401).json({
error: 'Unauthorized',
message: 'Invalid API key',
})
}
res.status(500).json({
error: 'Internal server error',
message: 'Something went wrong',
})
}