Netlify Deployment: Complete Guide for Modern Web Projects
Netlify is a comprehensive deployment platform that combines global CDN hosting with serverless backend services, form handling, and split testing. Its Git-based workflow enables continuous deployment for Jamstack sites and frontend applications with minimal configuration.
In this tutorial, you will learn to connect a Git repository to Netlify, configure build settings, deploy serverless functions, set up form handling without a backend server, implement split testing, manage redirects and headers, and use the Netlify CLI for local development. DodaTech uses Netlify to deploy Doda Browser documentation sites and DodaZIP feature landing pages.
What You'll Learn
By the end of this guide, you will deploy a frontend project from GitHub to Netlify with automatic builds, configure serverless Netlify Functions, enable form submissions without a server, run A/B split tests on deployments, and manage custom domains.
Why Netlify Matters
Netlify pioneered the Git-based deployment workflow that has become the standard for Jamstack hosting. Its atomic deploys ensure that your site is never in a broken state during deployment. Split testing lets you route a percentage of traffic to different deployment versions. Built-in form handling eliminates the need for a separate backend for contact forms. Netlify is a key platform in the Web Servers ecosystem and a staple tool for DevOps teams.
Netlify Deployment Learning Path
flowchart LR
A[Git Repository] --> B[Import Project]
B --> C[Build Configuration]
C --> D[Netlify Functions]
D --> E[Split Testing]
E --> F{You Are Here}
style F fill:#f90,color:#fff
Importing a Project
Connect your Git repository to Netlify:
# Example: Create a static site and push to GitHub
mkdir dodatech-docs
cd dodatech-docs
echo "<h1>DodaTech Documentation</h1>" > index.html
echo "{}" > package.json
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/your-org/dodatech-docs.git
git branch -M main
git push -u origin main
Site-level configuration (netlify.toml)
[build]
command = "npm run build"
publish = "dist"
base = "/"
[build.environment]
NODE_VERSION = "18"
NPM_VERSION = "9"
[context.production]
environment = { API_URL = "https://api.dodatech.com" }
[context.deploy-preview]
environment = { API_URL = "https://staging-api.dodatech.com" }
[context.branch-deploy]
environment = { API_URL = "https://dev-api.dodatech.com" }
Expected output
✔ Checking for netlify.toml configuration
✔ Linked to dodatech-docs.netlify.app
✔ Starting build process...
$ npm run build
✔ Build complete
✔ Deploying to global CDN
✔ Deployed to https://dodatech-docs.netlify.app
Serverless Functions (Netlify Functions)
Netlify Functions are serverless Lambda functions deployed alongside your site:
// netlify/functions/products.js
exports.handler = async function (event, context) {
const products = [
{ id: 1, name: "Doda Browser", category: "browser" },
{ id: 2, name: "DodaZIP", category: "utilities" },
{ id: 3, name: "Durga Antivirus Pro", category: "security" },
];
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify(products),
};
};
// netlify/functions/subscribe.js
exports.handler = async function (event, context) {
if (event.httpMethod !== "POST") {
return {
statusCode: 405,
body: JSON.stringify({ error: "Method not allowed" }),
};
}
try {
const { email } = JSON.parse(event.body);
if (!email) {
return {
statusCode: 400,
body: JSON.stringify({ error: "Email is required" }),
};
}
// In production: save to database or email service
console.log(`New subscriber: ${email}`);
return {
statusCode: 200,
body: JSON.stringify({
message: `Successfully subscribed ${email}`,
}),
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: "Internal server error" }),
};
}
};
Testing functions with Netlify CLI
# Install Netlify CLI
npm install -g netlify-cli
# Run locally
netlify dev
# Test functions
curl http://localhost:8888/.netlify/functions/products
# [{"id":1,"name":"Doda Browser","category":"browser"},...]
curl -X POST http://localhost:8888/.netlify/functions/subscribe \
-H "Content-Type: application/json" \
-d '{"email":"user@dodatech.com"}'
# {"message":"Successfully subscribed user@dodatech.com"}
Form Handling
Netlify processes form submissions without a backend. Add <a href="/web-servers-hosting/netlify/">netlify</a> attribute to your HTML form:
<form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact" />
<p class="hidden">
<label>Bot field: <input name="bot-field" /></label>
</p>
<p>
<label>Name: <input type="text" name="name" required /></label>
</p>
<p>
<label>Email: <input type="email" name="email" required /></label>
</p>
<p>
<label>Message: <textarea name="message" required></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
Expected behavior
# Submit form via curl
curl -X POST https://dodatech-docs.netlify.app/ \
-d "form-name=contact&name=Test+User&email=test@dodatech.com&message=Hello"
# Submission appears in Netlify Dashboard > Forms
# Or configure email notifications
Split Testing (Branch-Based)
Route a percentage of traffic to different deployment versions:
# netlify.toml
[split_test]
# Route 90% to main, 10% to feature branch
branches = [
{ branch = "main", percentage = 90 },
{ branch = "beta", percentage = 10 }
]
# Create a beta branch
git checkout -b beta
echo "BETA: <h1>New Design</h1>" > index.html
git add .
git commit -m "Beta redesign"
git push -u origin beta
Checking split test results
View analytics in the Netlify Dashboard under Split Testing, which shows conversion rates and performance metrics per branch.
Redirects and Headers
Create a <a href="/web-servers-hosting/netlify/">netlify</a>.toml or _redirects file:
# netlify.toml redirect and header rules
[[redirects]]
from = "/old-path"
to = "/new-path"
status = 301
[[redirects]]
from = "/blog/*"
to = "https://blog.dodatech.com/:splat"
status = 301
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
[[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"
Alternative _redirects file (simpler syntax)
# /public/_redirects
/old-path /new-path 301
/blog/* https://blog.dodatech.com/:splat 301
/api/* /.netlify/functions/:splat 200
Expected behavior
curl -I https://dodatech-docs.netlify.app/assets/style.css
# cache-control: public, max-age=31536000, immutable
curl -I https://dodatech-docs.netlify.app/old-path
# location: /new-path
# status: 301
Common Errors
1. Build Fails with Missing Dependency
Check the build log for the exact error. Ensure all dependencies are in package.json and the install command completes successfully. Use the same Node.js version locally as Netlify uses.
2. Function Returns 404
The function file is in the wrong directory or not deployed. Netlify Functions must be in <a href="/web-servers-hosting/netlify/">netlify</a>/functions/ (default) or a custom directory specified in <a href="/web-servers-hosting/netlify/">netlify</a>.toml.
3. Form Submission Not Received
The form must have data-<a href="/web-servers-hosting/netlify/">netlify</a>="true" and a hidden form-name field matching the form's name attribute. Enable form detection in Netlify Dashboard > Forms.
4. Split Test Not Showing in Dashboard
Both branches must have distinct content and the split test configuration in <a href="/web-servers-hosting/netlify/">netlify</a>.toml must be valid. Allow up to 10 minutes for the test to appear.
5. Redirect Loop
Check that the redirect target is correct and not redirecting back to the same path. Use status 200 for proxy-style rewrites and 301/302 for actual redirects.
Practice Questions
1. How does Netlify Forms work without a backend server? Netlify intercepts form POST requests at the edge, processes them, and stores submissions in the Netlify Dashboard. You receive email notifications or can forward submissions via webhooks.
2. What is the difference between [context.production] and [context.deploy-preview] in netlify.toml?
[context.production] applies to the main branch production deployment. [context.deploy-preview] applies to pull request preview deployments. Each context can have different environment variables and build settings.
3. How do you test Netlify Functions locally?
Use <a href="/web-servers-hosting/netlify/">netlify</a> dev which starts a local development server that runs functions at /.<a href="/web-servers-hosting/netlify/">netlify</a>/functions/. It also serves static files and supports environment variables.
4. Challenge: Multi-branch preview environment
Configure a project where:
- The
mainbranch deploys to production atexample.com - The
stagingbranch deploys tostaging--example.<a href="/web-servers-hosting/netlify/">netlify</a>.app - Every pull request gets a preview at
<hash>--example.<a href="/web-servers-hosting/netlify/">netlify</a>.app - Staging uses a different API_URL environment variable than production
Mini Project: Complete Netlify Stack
Deploy a modern web project with serverless backend on Netlify:
- Create a static site with an index page, about page, and contact form
- Add a
<a href="/web-servers-hosting/netlify/">netlify</a>/functions/subscribe.jsfunction that accepts POST requests - Configure
<a href="/web-servers-hosting/netlify/">netlify</a>.tomlwith redirects, headers, and build settings - Enable form handling on the contact form
- Set up environment variables for API URLs in production and preview
- Connect the repo to Netlify and deploy
- Create a pull request branch and verify the preview deployment
# Deploy from CLI
netlify deploy --prod
# Open site
netlify open:site
# Check function logs
netlify functions:log subscribe
This setup mirrors how DodaTech deploys Doda Browser documentation and DodaZIP marketing pages with automated form handling and serverless APIs.
FAQ
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro