Both the contact form (/contact) and the homepage "Tell us about your project" inline lead form post to /api/contact. Updated that single handler to build the nodemailer transport from a clean set of SMTP_* env vars per spec: SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS SMTP_FROM + SMTP_FROM_NAME -> "From: Ajay Ghanwat <ghanwat.ajay@workroot.in>" MAIL_ADMIN_TO -> admin notification recipient (falls back to SMTP_FROM, then legacy CONTACT_EMAIL_TO / CONTACT_EMAIL / SMTP_USER) SMTP_REQUIRE_TLS -> force STARTTLS upgrade on port 587 SMTP_CONNECTION_TIMEOUT_MS -> defaults to 10000 SMTP_GREETING_TIMEOUT_MS -> defaults to 10000 SMTP_SOCKET_TIMEOUT_MS -> defaults to 10000 Behaviour preserved: - Existing user-facing auto-reply (the block previously at L270) kept. Subject + body now adapt for project-inquiry sources (homepage-inline, homepage-hero, homepage-final-cta, mobile-sticky) so the admin inbox can triage [Project Inquiry] vs [Contact Form] at a glance. - Graceful degradation per FORM_INTEGRATION.md: missing env vars or a failed nodemailer import logs a structured warning and returns 200 — the site never 500s on email config. - Rate limiting, honeypot, CORS, validation, and fire-and-forget background dispatch are untouched. Observability: - Structured console logs at: transport created, admin accepted (with messageId), user auto-reply accepted (with messageId), and send-failure (with smtp code/command/response). SMTP_PASS is never logged. Misc: - .env.example updated to document the new variables and the legacy aliases that are still honored.
Astro SSR Standalone Server
An Astro-based web application configured for server-side rendering (SSR) with standalone Node.js deployment.
Quick Start
Development
npm install
npm run dev
The development server will start at http://localhost:4321
Production
npm run build
npm start
The production server will start at http://0.0.0.0:10000
Deployment
This application is configured for standalone Node.js deployment with SSR enabled.
📋 Domain Migration Documentation
- Quick Deploy:
QUICK-DEPLOY.md- Fast deployment reference for DevOps- Full Checklist:
DOMAIN-MIGRATION-CHECKLIST.md- Complete deployment checklist- Migration Summary:
MIGRATION-SUMMARY.md- Executive summary of changes- Deployment Guide:
DEPLOYMENT.md- General deployment instructions
Build Process
Build the application for production:
npm run build
This command:
- Compiles the Astro application with SSR enabled
- Generates a standalone Node.js server in the
dist/directory - Creates the server entry point at
dist/entry.mjs - Optimizes assets for production
Running the Server
Start the standalone Node server:
npm start
The server will:
- Bind to
0.0.0.0(accessible from all network interfaces) - Listen on port
10000by default - Serve server-side rendered pages with full SSR functionality
Environment Configuration
Environment variables can be configured using a .env file. See .env.example for available options:
| Variable | Description | Default |
|---|---|---|
| HOST | Server bind address. Use 0.0.0.0 for deployment (all interfaces) or localhost for local dev |
0.0.0.0 |
| PORT | Server port. Can be overridden by platform (e.g., Heroku, Railway) | 10000 |
| NODE_ENV | Runtime environment (production, development, test) |
production |
Example Configuration
For production deployment:
HOST=0.0.0.0
PORT=10000
NODE_ENV=production
For local development:
HOST=localhost
PORT=3000
NODE_ENV=development
Available Scripts
| Command | Description |
|---|---|
npm run dev |
Start development server with hot reload |
npm run build |
Build for production with SSR |
npm start |
Run production server |
npm run preview |
Preview production build locally |
npm run clean |
Remove build artifacts |
npm run prod |
Full production build and start |
Architecture
SSR Configuration
The application uses:
- Output mode:
server(full SSR) - Adapter:
@astro/nodein standalone mode - Server runtime: Node.js standalone server
This configuration ensures:
- Server-side rendering for all pages
- SEO optimization with pre-rendered HTML
- Dynamic content support
- No external dependencies for deployment
Server Entry Point
The standalone server is located at server.mjs and configures:
- Host binding to
0.0.0.0for deployment accessibility - Port
10000with environment variable override support - Production-ready server setup
Deployment Platforms
Generic Node.js Platforms
Compatible with any platform that supports Node.js:
-
Build the application:
npm run build -
Set environment variables (if needed):
export HOST=0.0.0.0 export PORT=10000 export NODE_ENV=production -
Start the server:
npm start
Platform-Specific Notes
Railway / Render / Fly.io:
- These platforms automatically set the
PORTenvironment variable - The server will use the platform's provided port
- Ensure
npm startis set as the start command
Heroku:
- Uses the
PORTenvironment variable automatically - Add
node_modulesto.gitignore(already configured) - Ensure
package.jsonhas"engines"field for Node version
Docker:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
EXPOSE 10000
CMD ["npm", "start"]
Project Structure
.
├── src/
│ ├── pages/ # Astro pages (SSR routes)
│ ├── layouts/ # Page layouts
│ └── components/ # Reusable components
├── public/ # Static assets
├── dist/ # Production build output
│ └── entry.mjs # Server entry point
├── server.mjs # Standalone server configuration
├── astro.config.mjs # Astro configuration
├── .env.example # Environment variables template
└── package.json # Project dependencies and scripts
Features
- Server-Side Rendering (SSR): Full SSR support for dynamic content and SEO
- Standalone Deployment: Self-contained Node.js server with no external dependencies
- Environment Configuration: Flexible configuration via environment variables
- Production-Ready: Optimized build with asset optimization and performance tuning
- SEO Optimized: Meta tags, Open Graph, and structured data support
- Performance Optimized: Image optimization with WebP, lazy loading, and asset optimization
Troubleshooting
Port Already in Use
If you see EADDRINUSE error:
# Windows
netstat -ano | findstr :10000
taskkill /PID <PID> /F
# Linux/Mac
lsof -ti:10000 | xargs kill -9
Server Not Accessible
Ensure the server is bound to 0.0.0.0 (not localhost) for external access:
HOST=0.0.0.0
Build Failures
Clear the build cache and rebuild:
npm run clean
npm run build
License
MIT