A full-stack newsletter and subscription management system built with React and Node.js.

newsletter/
βββ package.json # Root package.json with dev scripts
βββ package-lock.json # Root dependency lock file
βββ backend/ # Node.js API server
β βββ package.json # Backend dependencies
β βββ package-lock.json # Backend dependency lock file
β βββ config/ # Database configuration
β βββ middleware/ # Auth and admin middleware
β βββ models/ # Database models (MongoDB/PostgreSQL)
β βββ routes/ # API routes
β βββ server.js # Express server entry point
βββ frontend/ # React web application
β βββ package.json # Frontend dependencies (includes optional markdown packages)
β βββ package-lock.json # Frontend dependency lock file
β βββ public/ # Static assets
β βββ src/
β βββ components/ # Reusable React components
β βββ pages/ # Page components (Admin.js contains editor)
β βββ hooks/ # Custom React hooks
β βββ utils/ # Utilities and API functions
β βββ styles/ # CSS and styling
βββ shared/ # Shared utilities
Key Dependencies by Directory:
Important Files for CI/CD:
git clone <repository-url>
cd newsletter
# Install root dependencies (creates package-lock.json)
npm install
# Install backend dependencies (creates backend/package-lock.json)
cd backend
npm install
# Install frontend dependencies (creates frontend/package-lock.json)
cd ../frontend
npm install
# For markdown support (optional - if you want markdown editing capabilities)
# These packages enable dual Rich Text / Markdown editor modes
cd ../frontend
npm install marked react-markdown remark-gfm rehype-raw rehype-sanitize
npm install sanitize-html
Package Notes:
marked - Fast markdown parser and compilerreact-markdown - React component for rendering markdownremark-gfm - GitHub Flavored Markdown support (tables, task lists, etc.)rehype-raw - Allows raw HTML in markdownrehype-sanitize - Sanitizes HTML for securityWorkflow Best Practices:
package-lock.json files to version controlnpm ci in production/CI environments for faster, reliable installspackage-lock.json filesEnvironment Setup
Create a .env file in the backend directory:
PORT=5050
NODE_ENV=development
CLIENT_URL=http://localhost:3030
# Database Configuration
# Choose: 'mongodb' or 'postgresql'
DATABASE_TYPE=mongodb
# MongoDB Configuration (if using MongoDB)
MONGODB_URI=mongodb://localhost:27017/newsletter
# PostgreSQL Configuration (if using PostgreSQL)
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=newsletter
POSTGRES_USER=newsletter_user
POSTGRES_PASSWORD=newsletter_password
JWT_SECRET=your-super-secret-jwt-key
# Email configuration (optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
FROM_EMAIL=your-email@gmail.com
# hCaptcha configuration
HCAPTCHA_SECRET=your-hcaptcha-secret-key
Database Setup
The application supports both MongoDB and PostgreSQL. Choose your preferred database:
For MongoDB:
DATABASE_TYPE=mongodb in your .env fileFor PostgreSQL:
DATABASE_TYPE=postgresql in your .env fileSee MONGODB_SETUP.md for detailed database installation instructions.
Start the Application
From the root directory:
# Start both frontend and backend concurrently
npm run dev
# Or start them separately:
# Backend (from backend directory)
npm run dev
# Frontend (from frontend directory)
npm start
GET /api/newsletters - Get all published newslettersGET /api/newsletters/:id - Get newsletter by IDPOST /api/subscriptions/subscribe - Subscribe to newsletterPOST /api/subscriptions/unsubscribe - Unsubscribe from newsletterGET /api/subscriptions/status/:email - Check subscription statusPOST /api/auth/login - Admin loginPOST /api/auth/register - Admin registrationGET /api/newsletters/admin/all - Get all newsletters (including drafts)POST /api/newsletters - Create new newsletterPUT /api/newsletters/:id - Update newsletterDELETE /api/newsletters/:id - Delete newsletterGET /api/subscriptions/admin/all - Get all subscriptions/adminRoot directory:
npm run dev - Start both frontend and backendnpm run server - Start backend onlynpm run client - Start frontend onlynpm run build - Build frontend for productionnpm run install-all - Install all dependenciesnpm ci - Clean install from package-lock.json (recommended for CI/CD)Backend directory:
npm start - Start production servernpm run dev - Start development server with nodemonnpm ci - Clean install from package-lock.jsonFrontend directory:
npm start - Start development servernpm run build - Build for productionnpm test - Run testsnpm ci - Clean install from package-lock.jsonBackend environment variables (.env):
PORT - Server port (default: 5050)NODE_ENV - Environment (development/production)CLIENT_URL - Frontend URL for CORSDATABASE_TYPE - Database type (βmongodbβ or βpostgresqlβ)MONGODB_URI - MongoDB connection string (if using MongoDB)POSTGRES_* - PostgreSQL connection details (if using PostgreSQL)JWT_SECRET - Secret for JWT tokensSMTP_* - Email server configurationHCAPTCHA_SECRET - hCaptcha secret key for backend verificationPackage Lock Files:
Each directory contains a package-lock.json file that locks exact dependency versions:
./package-lock.json - Development tools (concurrently, etc.)./backend/package-lock.json - Server dependencies./frontend/package-lock.json - React app and build dependenciesProduction Deployment:
# Use npm ci for faster, reliable installs in production
npm ci # Install root dependencies
cd backend && npm ci # Install backend dependencies
cd ../frontend && npm ci # Install frontend dependencies
npm run build # Build frontend for production
Docker Considerations:
package*.json files before npm ci for better layer cachingNODE_ENV=production for optimized buildsPackage Lock File Conflicts If you encounter dependency conflicts or inconsistent installs:
# Clean install from lock files (recommended)
npm ci
# Or if you need to regenerate lock files:
rm -rf node_modules package-lock.json
npm install
# For specific directories:
cd backend
rm -rf node_modules package-lock.json
npm install
cd ../frontend
rm -rf node_modules package-lock.json
npm install
Markdown Dependencies (Optional) If you encounter issues with markdown packages:
# Clear npm cache and reinstall
npm cache clean --force
cd frontend
rm -rf node_modules package-lock.json
npm install
npm install marked react-markdown remark-gfm rehype-raw rehype-sanitize
Node Version Compatibility
.nvmrc file if present for recommended Node versionnpm list to check for dependency conflictsDatabase Connection Issues
.env filePort Conflicts If ports 3030 or 5050 are in use:
PORT=5050 in backend .env fileREACT_APP_API_URL in frontend if neededSMTP Email Issues
hCaptcha Issues
HCAPTCHA_SECRET is set in backend/.envAlways Commit These Files:
package.json (all directories)package-lock.json (all directories).env.example (environment template)Never Commit These Files:
node_modules/ (excluded by .gitignore).env (contains secrets)frontend/build/)Dependency Management:
npm install <package> to add new dependenciesnpm ci in CI/CD pipelines for consistent buildspackage-lock.json when changing dependenciesThis project is licensed under the MIT License.
For support or questions, please open an issue in the repository.
This project uses OpenCaptcha to prevent spam subscriptions.
Frontend & Backend:
cd frontend
C:\Users\marood\Documents\workspace\node-v22.18.0-win-x64\npm.cmd install axios
cd ../backend
C:\Users\marood\Documents\workspace\node-v22.18.0-win-x64\npm.cmd install axios
To control whether CAPTCHA is shown on the subscription form, set the following in frontend/.env:
REACT_APP_ENABLE_CAPTCHA=true # Show CAPTCHA (recommended)
REACT_APP_ENABLE_CAPTCHA=false # Hide CAPTCHA (not recommended for production)
The backend always requires CAPTCHA verification for subscriptions. The frontend controls whether the CAPTCHA widget is displayed to users.