Pre-launch waitlist landing page for voult.dev — a developer-first authentication platform.
- Overview
- Features
- Project Layout
- Getting Started
- How Email Sending Works
- Customizing
- Deploying
- Contributing
- Tests
- Questions & Support
- License
This repository contains a pre-launch waitlist landing page for voult.dev, built using the same stack and conventions as the main voult.dev repository. It includes a waitlist form, live countdown, feature highlights, and footer with legal links.
Built with: Node.js + Express 5, EJS (with ejs-mate layouts), Bootstrap 5, Mongoose, Nodemailer over Brevo SMTP, Helmet, express-rate-limit, express-validator.
- Hero with a typewriter-style code snippet showing what the SDK feels like.
- Waitlist form — email input that POSTs to
/api/waitlist. On success:- The email is stored in MongoDB at
mongodb://127.0.0.1:27017/usersEmail - A confirmation email is sent via Brevo SMTP (same transport as voult.dev's
config/mailer.js)
- The email is stored in MongoDB at
- Fancy live countdown to launch (configurable via the
LAUNCH_DATEenv var). - MVP features grid — Security, lightweight SDK + docs, smooth DX, rich developer portal, OAuth & passwordless, pre-built UI kits.
- Footer with placeholder slots for your legal links (Terms, Privacy, Cookies, Security, Contact) — wire up the hrefs when your legal pages are ready.
voult-landing/
├── src/
│ └── index.js # Express app entry (mirrors voult/src/index.js style)
├── config/
│ ├── database.js # Mongoose connection to mongodb://127.0.0.1:27017/usersEmail
│ └── mailer.js # Brevo SMTP transporter (copied 1:1 from voult/config/mailer.js)
├── models/
│ └── WaitlistEmail.js # Mongoose schema for stored emails
├── routes/
│ └── waitlist.js # POST /api/waitlist (validated + rate-limited)
├── services/
│ └── emailService.js # sendWaitlistEmail() — same pattern as voult/services/emailService.js
├── views/
│ ├── layout/boilerplate.ejs # ejs-mate layout (matches voult's pattern)
│ ├── home/landing.ejs # the landing page
│ └── error/404.ejs
├── public/
│ ├── css/landing.css # dark, developer-style design (Inter + JetBrains Mono)
│ └── js/
│ ├── countdown.js # live launch countdown
│ └── waitlist.js # form fetch + UX states
├── .env.example
├── .gitignore
└── package.json
cd voult-landing
npm installThe app connects to mongodb://127.0.0.1:27017/usersEmail by default. Make sure MongoDB is running locally:
# macOS (brew)
brew services start mongodb-community
# or via docker
docker run -d -p 27017:27017 --name mongo mongo:7cp .env.example .envThen fill in .env:
PORT=3000
NODE_ENV=development
MONGO_URI=mongodb://127.0.0.1:27017/usersEmail
LAUNCH_DATE=2026-11-21T09:00:00Z
BREVO_USER=your_brevo_smtp_user
BREVO_SMTP_KEY=your_brevo_smtp_key
MAIL_FROM="voult.dev" <olabodeoluwapelumi838@gmail.com>You can reuse the same Brevo credentials you already use in the main voult.dev project (BREVO_USER, BREVO_SMTP_KEY).
npm run dev # nodemon
# or
npm startOpen http://localhost:3000.
This is intentionally a 1:1 mirror of the main repo's pattern:
| voult.dev | voult-landing |
|---|---|
config/mailer.js — Brevo transporter |
config/mailer.js — same Brevo transporter |
services/emailService.js — welcomeEmail, verifyEndUsers, etc. |
services/emailService.js — sendWaitlistEmail |
transporter.sendMail({ from, to, subject, html }) |
identical call shape |
When a visitor submits their email:
POST /api/waitlistis hit (routes/waitlist.js).express-validatorvalidates + normalizes the email;express-rate-limitblocks abuse (10/req per 10 min per IP).- The email is upserted into the
waitlistemailscollection inside theusersEmailMongoDB database. sendWaitlistEmail(email)is called fire-and-forget — it uses the exact same Brevo transporter as voult.dev to deliver a dark-themed confirmation email.
If the email is already in the DB, the API returns a friendly "you're already on the list" message instead of erroring.
mongosh
> use usersEmail
> db.waitlistemails.find().pretty()Each document looks like:
{
_id: ObjectId("..."),
email: "dev@example.com",
source: "landing",
userAgent: "...",
ip: "127.0.0.1",
createdAt: ISODate("..."),
updatedAt: ISODate("...")
}- Launch date → change
LAUNCH_DATEin.env(ISO-8601, UTC recommended). - From address → change
MAIL_FROMin.env. - Footer legal links → edit
views/home/landing.ejs, in the<footer>block. Replace thehref="#"placeholders with your real Terms / Privacy / Cookie / Security / Contact URLs. - Features copy → edit the
.features-gridblock inviews/home/landing.ejs. - Colors / theme → all tokens live at the top of
public/css/landing.css(:root).
Same pattern as voult.dev (Render, Railway, Fly, etc.). Required env vars in production:
NODE_ENV=productionMONGO_URI(point at a hosted MongoDB — Atlas works well)BREVO_USER,BREVO_SMTP_KEY,MAIL_FROMLAUNCH_DATE
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate if you add new functionality.
This project currently does not have automated tests. Manual testing is recommended:
- Test the waitlist form submission with valid and invalid emails
- Verify emails are stored correctly in MongoDB
- Check that confirmation emails are sent via Brevo
- Test the live countdown functionality
- Ensure all links in the footer work correctly when updated
For questions, feedback, or support regarding this project:
- Email: privacy@voult.dev (for privacy-related inquiries)
- GitHub Issues: https://github.com/DevOlabode/voult-landing/issues
- Please check the Privacy Policy for information on how we handle your data.
ISC — same as the main voult.dev repo.
See LICENSE for details.