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 emailapp.post('/api/send-email', async (req, res) => {const { to, subject, html } = req.bodytry {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 templaterouter.post('/send-order-confirmation', async (req, res) => {const { email, orderNumber, items, total } = req.bodytry {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 resetrouter.post('/send-password-reset', async (req, res) => {const { email, resetToken } = req.bodyconst 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 notificationsrouter.post('/notify-users', async (req, res) => {const { users, message } = req.bodytry {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.bodytry {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 URLrouter.post('/get-upload-url', async (req, res) => {const { filename, mimeType, size } = req.bodytry {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 completerouter.post('/confirm-upload', async (req, res) => {const { assetId } = req.bodytry {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 errorsif (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',})}