- Rename WhatsApp label from "WhatsApp" (8 chars) to "Chat" (4) so every visible label fits the ≤7-char action-verb policy and never triggers the new text-overflow:ellipsis safety net even at 320px (iPhone SE). - Bump inline SVG icons to 24×24 (was 22), set min-height 64px and min-width 44px per Apple HIG / WCAG 2.5.5 tap-target requirements. - Add white-space:nowrap + text-overflow:ellipsis as defensive safety net, plus a 320-359px breakpoint that nudges label to 11px / padding to 4px-horizontal so glyph-width drift can't cause overflow. - Rewrite aria-labels to be action-led + descriptive even when visible text is terse: "Call us", "Chat with us on WhatsApp", "Get a free quote" (WCAG 2.5.3 name-in-name). - Bump BaseLayout bottom-spacer from 64px → 72px so the new PricingTimelineBand and GuaranteeBand always have an 8px visual buffer above the fixed sticky bar (no overlap). Verified: build green, all 6 tests in tests/sticky-cta.spec.ts pass against the restarted frontend service. Probed live at 320 / 375 / 414 px — every button is 64px tall, ≥103px wide, icons 24×24, labels never truncate. Footer fully clears the bar at scroll-bottom.
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