Landing pages are built for one job: turning visitors from an ad, email or campaign into leads or customers. That makes speed and reliability critical: every extra second of load time loses visitors you already paid for. Hosting them on your own VPS gives you fast pages, unlimited campaigns and domains, and no per-page subscription fees.
Options for building the pages
| Approach | Pros | Cons |
|---|---|---|
| Static HTML/CSS (hand-made or a template) | Fastest, cheapest, most secure | Needs basic HTML skills to edit |
| Static site generator (Astro, Hugo, Eleventy) | Reusable components, many pages from data | Build step |
| WordPress + a page builder | Visual editing for marketers | Heavier; needs caching and updates |
| Export from a builder tool | Visual design, then static hosting | Exported code can be bloated |
For most campaigns, static pages are ideal: they load in milliseconds, survive traffic spikes from big ad budgets, and have almost nothing to hack. See static vs dynamic sites and static site generators.
Nginx setup for many landing pages
One server can host dozens of campaign pages, on subdirectories or separate domains:
server {
listen 80;
server_name offer.example.com;
root /var/www/landing/offer;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(css|js|webp|avif|png|jpg|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
gzip on;
gzip_types text/css application/javascript image/svg+xml;
}
Then add HTTPS:
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d offer.example.com
See installing Nginx on Ubuntu, hosting multiple domains with SSL, and Nginx subdomains.
Speed matters for ads
Ad platforms factor landing page experience into ad quality and cost, and visitors bounce from slow pages. Aim for:
- TTFB under 200 ms (easy for static files on a nearby VPS);
- LCP under 2.5 s on mobile: compressed hero images (WebP/AVIF), explicit image dimensions, fonts preloaded or system fonts;
- minimal JavaScript: every tracking pixel and chat widget costs speed.
Choose a VPS location close to the campaign audience, or put a CDN in front for global campaigns. See WebP and AVIF, web performance testing and CDN for websites.
Forms without a full backend
A landing page usually needs one form. Options:
- Post to your CRM or email marketing tool’s form endpoint (simplest).
- A small serverless-style handler on the same VPS: a tiny PHP script, or a Node/Python service, that validates input, stores it, and sends a notification.
- A self-hosted form backend.
Whatever you use, add spam protection (a honeypot field, a CAPTCHA such as Cloudflare Turnstile, rate limiting) and send notification emails through a proper SMTP service. See Nginx rate limiting and SMTP ports 25, 465 and 587.
Tracking and analytics
- Use UTM parameters on every campaign link.
- Self-hosted, privacy-friendly analytics (Plausible, Umami, Matomo) keep data on your server and are light on page weight. See Plausible self-hosted and Umami.
- Load ad pixels after the main content, and respect cookie consent rules in your visitors’ regions.
A/B testing
Without a SaaS tool, you can split traffic at the Nginx level:
split_clients "${remote_addr}${http_user_agent}" $variant {
50% "a";
* "b";
}
server {
# …
location = / {
try_files /index-$variant.html =404;
}
}
Record the variant in your analytics or form submissions, and run the test long enough to reach statistical significance. Keep the canonical tag pointing to the main URL. See canonical URLs.
SEO considerations
Paid campaign pages often shouldn’t be indexed (duplicate offers, thin content). Add noindex to them, or block them from your sitemap, and keep your SEO landing pages separate. See the robots.txt guide.
Deployment workflow
Keep pages in Git, and deploy with rsync or a CI pipeline, so you can roll back a broken page in seconds:
rsync -avz --delete dist/ deploy@server:/var/www/landing/offer/
See deploying a static site with rsync and GitHub Actions deployment to a VPS.
Quick checklist
| Item | Target |
|---|---|
| Page type | Static where possible |
| HTTPS | Certbot, auto-renew |
| Speed | TTFB < 200 ms, LCP < 2.5 s mobile |
| Form | Spam protection + reliable email |
| Tracking | UTMs, light analytics |
| Indexing | noindex for paid-only pages |
Related: Nginx FastCGI cache for WordPress-based landing pages, and HTTP caching headers.