Your CI/CD pipeline for JAMstack stalled?
Building your React SPA takes 15 minutes, after deployment links break due to incorrect redirects, and previews for pull requests have to be configured manually? We've encountered this dozens of times. Our team (5+ years of experience with Netlify and 50+ configured projects) solves these problems in a couple of hours. We guarantee: after our configuration, the average build time will drop to 2–3 minutes, and branch previews will appear within a minute.
We are engineers who work with Netlify, Vercel, and Cloudflare Pages every day. We'll set up deployment turnkey: from initial repository connection to production deployment with a custom domain, SSL, and monitoring.
What problems we solve with Netlify deployment
Build errors due to environment incompatibility
Wrong Node.js version, cluttered npm cache, or build scripts using global dependencies. In netlify.toml we strictly pin the Node version, NPM_FLAGS, and environment: NODE_VERSION = "20", NPM_FLAGS = "--prefer-offline".
Slow deployment and exceeding limits
Standard build without caching can take 10+ minutes. We use Netlify Large Media for images and cache node_modules between builds. Below is a comparison of Free and Pro limits:
| Parameter | Free | Pro |
|---|---|---|
| Build minutes/month | 300 | 1000 (can be topped up) |
| Functions timeout | 10 sec | 26 sec |
| Bandwidth/month | 100 GB | 500 GB |
| Concurrent builds | 1 | 5 |
Netlify automatically cancels a build if it runs longer than 15 minutes. — Netlify Documentation
Incorrect redirects and headers
SPAs require redirecting all routes to index.html, otherwise 404. API proxies are often forgotten. Our netlify.toml configuration covers these cases:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[redirects]]
from = "/api/*"
to = "https://api.example.com/:splat"
status = 200
force = true
How we set up deployment in 30 minutes (real case)
Project: SPA on Vue 3 with a contact form and custom API on Netlify Functions. Originally deployed via GitHub Pages — manual, without previews. What we did:
- Created netlify.toml with context separation (production, branch-deploy, deploy-preview).
- Configured the contact.ts function to send emails via Resend.
- Connected GitHub Actions for deployment — only on push to main and develop.
- Enabled Netlify Forms as fallback for data collection.
Result: automatic deployment, preview for PR in 1 minute, saving 4 hours of manual work per week. Netlify is configured 2–3 times faster than Vercel for static sites.
Complete netlify.toml configuration
Full netlify.toml configuration file
[build]
command = "npm run build"
publish = "dist"
functions = "netlify/functions"
[build.environment]
NODE_VERSION = "20"
NPM_FLAGS = "--prefix=/dev/null"
# SPA: redirect all routes to index.html
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
# API proxy
[[redirects]]
from = "/api/*"
to = "https://api.example.com/:splat"
status = 200
force = true
# Custom headers
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
# Split testing (A/B)
[context.deploy-preview]
command = "npm run build:preview"
[context.branch-deploy]
command = "npm run build:staging"
Netlify Functions for contact form
// netlify/functions/contact.ts
import type { Handler, HandlerEvent } from '@netlify/functions';
export const handler: Handler = async (event: HandlerEvent) => {
if (event.httpMethod !== 'POST') {
return { statusCode: 405, body: 'Method Not Allowed' };
}
const { name, email, message } = JSON.parse(event.body || '{}');
// Send via Nodemailer or Resend
await sendEmail({ name, email, message });
return {
statusCode: 200,
body: JSON.stringify({ success: true }),
headers: { 'Content-Type': 'application/json' },
};
};
Alternative: Netlify built-in forms
Suitable when custom validation or CRM integration is not needed.
<form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact">
<p class="hidden">
<label>Don't fill this: <input name="bot-field"></label>
</p>
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>
Submissions are available in Netlify Dashboard → Forms. Notifications can be configured there (email, Slack webhook).
GitHub Actions + Netlify CLI
name: Deploy to Netlify
on:
push:
branches: [main, develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Deploy to Netlify
run: |
npx netlify-cli deploy \
--dir=dist \
--site=${{ secrets.NETLIFY_SITE_ID }} \
--auth=${{ secrets.NETLIFY_AUTH_TOKEN }} \
${{ github.ref == 'refs/heads/main' && '--prod' || '' }}
Why Netlify Functions are not suitable for heavy computations?
The time limit (10 seconds on Free plan, 26 on Pro) prevents using them for video processing, PDF generation, or complex ETL tasks. For such cases, we connect external services: AWS Lambda, Google Cloud Functions, or specialized queues. Netlify Functions are ideal for lightweight API proxies, sending emails, and webhooks.
Netlify vs Vercel vs Cloudflare Pages: what to choose?
| Criteria | Netlify | Vercel | Cloudflare Pages |
|---|---|---|---|
| Serverless support | Functions (10-26 sec) | Edge Functions (50ms) | Workers (10ms CPU) |
| Built-in forms | Yes | No | No |
| Configuration | netlify.toml (flexible) | vercel.json (simpler) | wrangler.toml |
| Optimal stack | Static, SPA, Gatsby | Next.js, Nuxt | JAMstack, Workers |
| Free build limit | 300 min/month | 6000 min/month | 500 builds/month |
Netlify wins in simplicity of form setup and redirects, Vercel in Edge Functions performance, Cloudflare in global network and pricing.
Process
- Analysis — examine current repository, build scripts, dependencies.
- Design — determine contexts (production, staging, preview), environment variables, functions.
- Implementation — write netlify.toml, functions, CI/CD (GitHub Actions / GitLab CI).
- Testing — deploy to preview environment, check redirects, headers, and build time.
- Launch — switch DNS, check SSL, monitor logs.
Timeline and cost
Typical project (SPA/static) setup — 4–8 hours. For projects with custom functions and integrations — up to 16 hours. Cost is calculated individually after auditing your repository. On average, the project pays for itself by speeding up deployment 3–5 times. Manual deployment time savings can be up to $800–1200 per month at an average developer rate.
What is included in the work
- Working netlify.toml configuration with context separation.
- Custom Netlify domain setup and automatic SSL.
- Development of up to 5 Netlify Functions (contact forms, API proxies).
- Integration with GitHub Actions / GitLab CI.
- Support documentation (how to add a new function, change variables).
- 2 weeks of free support after deployment.
Why trust us with the setup?
- 5+ years of experience with Netlify and JAMstack projects.
- 50+ successful deployment setups for React, Vue, Angular, and Gatsby.
- Certified specialists in Netlify and CI/CD (GitHub Actions, GitLab CI).
- Stability guarantee — after deployment, all parameters are fixed and do not change without your knowledge.
Contact us for an audit of your current deployment — we'll identify problem areas and suggest optimization. Order a turnkey Netlify setup and forget about manual deployments forever.







