Skip to content

Netlify Deployment: Complete Guide for Modern Web Projects

DodaTech Updated 2026-06-23 8 min read

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 main branch deploys to production at example.com
  • The staging branch deploys to staging--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:

  1. Create a static site with an index page, about page, and contact form
  2. Add a <a href="/web-servers-hosting/netlify/">netlify</a>/functions/subscribe.js function that accepts POST requests
  3. Configure <a href="/web-servers-hosting/netlify/">netlify</a>.toml with redirects, headers, and build settings
  4. Enable form handling on the contact form
  5. Set up environment variables for API URLs in production and preview
  6. Connect the repo to Netlify and deploy
  7. 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

Can I use Netlify for single-page applications (SPAs)?

Yes. Add a redirect rule from /* to /index.html with status 200 to handle client-side routing. This ensures all routes serve the SPA entry point.

What are Netlify's build limits?

The free plan includes 300 build minutes per month, 100 GB bandwidth, 100 form submissions, and 125K function invocations. Paid plans increase these limits significantly.

How does Netlify handle SSL certificates?

Netlify automatically provisions free SSL certificates via Let's Encrypt for all deployments, including custom domains. Certificates renew automatically.

Can I use Netlify with a headless CMS?

Yes. Netlify is commonly paired with headless CMS platforms like Contentful, Sanity, or Strapi. Build webhooks trigger redeployments when content changes.

What is the difference between Netlify Functions and Edge Functions?

Netlify Functions use AWS Lambda with Node.js/Go runtimes. Netlify Edge Functions (launched 2023) run on Deno at the edge with lower latency and global distribution.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro