Utility Bar

ESP32 Web Server Tutorial - Connect to Wi-Fi and Host a Simple Web Page

ESP32 Web Server Tutorial

Ethan Zaitchik |

Table of Contents

    The ESP32 is a highly capable microcontroller which includes a built-in Wi-Fi radio and a full TCP/IP networking stack. This means it can connect to wireless networks, communicate using standard internet protocols, and even host real web pages directly from the board.

    This project demonstrates how to create a simple ESP32 web server using the Arduino IDE. By the end, you’ll understand how the ESP32 handles HTTP requests, how local IP addressing works, and how embedded devices can serve real web pages over Wi-Fi.

    New to ESP32? Start with our ESP32 Beginner Tutorials or follow our step-by-step guide on  Installing and Configuring Arduino IDE for ESP32 before continuing.
    What you’ll build:
    An ESP32 that connects to your home or office router, receives its own local IP address, and serves a live web page when you enter that IP address into a browser.

    How This Project Works

    The ESP32 supports two main Wi-Fi operating modes:

    • Access Point (AP) Mode – The ESP32 creates its own Wi-Fi network. Other devices connect directly to it.
    • Station (Client) Mode – The ESP32 connects to an existing Wi-Fi router, just like a laptop or smartphone.

    In this guide, we use Station Mode. This is how real-world IoT systems are typically built.

    Why Use Station Mode?

    Instead of connecting your computer directly to the ESP32, both your computer and the ESP32 connect to the same router. The router acts as the central hub that manages communication between devices.

    Communication Flow:

    Computer → Router → ESP32

    ESP32 Web Server Data Flow
    All devices must be connected to the same Wi-Fi network. If your ESP32 connects to a guest network, different router, or different subnet, your browser will not be able to reach it.

    This setup mirrors how larger IoT systems work. Devices join a shared network and communicate using standard internet protocols rather than direct wired or point-to-point connections.

    What Actually Happens Behind the Scenes

    When your ESP32 connects to the router:

    • The router assigns it a local IP address (for example, 192.168.1.104). This is similar to giving it a “house address” on your network.
    • The ESP32 opens a server on port 80, which is the default port used for HTTP web traffic.
    • When you type the IP address into your browser, the browser sends an HTTP request to that address.
    • The ESP32 receives that request and responds by sending back HTML code.
    • Your browser interprets that HTML and displays the web page.

    Even though this project runs on a small microcontroller, it follows the exact same request-response model used by large-scale web servers across the internet — just on a smaller scale and within your local network.

    Why this matters:
    Once your ESP32 can host a web page, you unlock the foundation of nearly every IoT project. You can create dashboards, display sensor data, toggle relays, monitor systems, and build full browser-based control panels — all without installing special apps.

    Hardware Required

    Get All the Parts You Need

    This tutorial is part of our comprehensive ESP32 learning series. Instead of buying components individually, save time and money with our ESP32 Basic Starter Kit. It includes everything you need for this lesson and 20+ other projects.

    What's Included: ESP32 board, OLED display, sensors (DHT11, PIR, LDR), relay module, buzzers, LEDs, buttons, breadboard, resistors, and all cables, plus access to our complete lesson plans.

    View ESP32 Starter Kit →

    Now let’s start by connecting the ESP32 to your router.

    Connecting the ESP32 to Your Router

    Replace YOUR_SSID and YOUR_PASSWORD with your Wi-Fi details.

    #include <WiFi.h>
    
    const char* ssid = "YOUR_SSID"; // Replace these
    const char* password = "YOUR_PASSWORD"; // Replace these
    
    void setup() {
      Serial.begin(115200);
    
      WiFi.begin(ssid, password);
      Serial.print("Connecting to Wi-Fi");
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println();
      Serial.println("Connected to Wi-Fi");
      Serial.print("ESP32 IP address: ");
      Serial.println(WiFi.localIP());
    }
    
    void loop() {
    }
    Once connected, your router assigns the ESP32 a local IP address. This is the address you will type into your browser.
    ESP32 connected to Wi-Fi showing IP address in Serial Monitor

    Create the ESP32 Web Server

    Now we create a server that listens for browser requests on port 80.

    #include <WiFi.h>
    
    /* ===== Wi-Fi Credentials ===== */
    const char* ssid     = "YOUR_SSID"; // Replace these
    const char* password = "YOUR_PASSWORD"; // Replace these
    
    /* ===== Create Server on Port 80 ===== */
    WiFiServer server(80);
    
    void setup() {
      Serial.begin(115200);
    
      WiFi.begin(ssid, password);
      Serial.print("Connecting to Wi-Fi");
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println("\nConnected!");
      Serial.print("IP Address: ");
      Serial.println(WiFi.localIP());
    
      server.begin();
    }
    
    void loop() {
    
      WiFiClient client = server.available();
    
      if (client) {
        while (client.connected()) {
          if (client.available()) {
            client.read();   // Read browser request (basic handling)
    
            // Send HTTP response
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
    
            // Simple HTML page
            client.println("<!DOCTYPE html>");
            client.println("<html>");
            client.println("<head>");
            client.println("<title>ESP32 Web Server</title>");
            client.println("<style>");
            client.println("body { font-family: Arial; text-align: center; }");
            client.println("h1 { color: red; }");
            client.println("</style>");
            client.println("</head>");
            client.println("<body>");
            client.println("<h1>ESP32 Web Server Running!</h1>");
            client.println("<h2>Your ESP32 is connected to Wi-Fi.</h2>");
            client.println("</body>");
            client.println("</html>");
            client.println();
    
            break;
          }
        }
        client.stop();
      }
    }

    Code Explanation

    We begin by including the Wi-Fi library, which allows the ESP32 to connect to a wireless network and handle internet communication.

    #include <wifi.h></wifi.h>

    Next, we store the name and password of the Wi-Fi network we want the ESP32 to join.

    const char* ssid = "YOUR_SSID";
    const char* password = "YOUR_PASSWORD";

    This line creates a web server that listens on port 80, the default port used for HTTP traffic.

    WiFiServer server(80);

    Inside setup(), we start serial communication so we can see messages in the Serial Monitor.

    Serial.begin(115200);

    We then begin connecting to the router using the credentials provided.

    WiFi.begin(ssid, password);

    This loop keeps checking the connection status until the ESP32 successfully connects to the network.

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }

    Once connected, the ESP32 prints its assigned local IP address. This is the address you enter into your browser.

    Serial.println(WiFi.localIP());

    We now start the web server so it can begin listening for incoming browser requests.

    server.begin();

    Inside the loop(), we check whether a device (client) is trying to connect to the server.

    WiFiClient client = server.available();

    If a client is detected, we wait until it sends data. This data is the HTTP request from the browser.

    if (client) {
      while (client.connected()) {
        if (client.available()) {
          client.read();

    Once a request is received, we send back an HTTP response header. This tells the browser the request was successful and that HTML content is being sent.

    client.println("HTTP/1.1 200 OK");
    client.println("Content-type:text/html");
    client.println("Connection: close");
    client.println();

    After the header, we send standard HTML code. The browser interprets this and displays it as a web page.

    client.println("<h1>ESP32 Web Server Running!</h1>");
    client.println("<h2>Your ESP32 is connected to Wi-Fi.</h2>");

    Finally, we close the connection so the ESP32 can handle the next request.

    client.stop();

    This entire process follows a simple request–response cycle: the browser sends a request, the ESP32 responds with HTML, and the browser renders the page.

    Access the ESP32 from Your Browser

    1. Upload the code
    2. Open the Serial Monitor
    3. Note the printed IP address
    4. Enter the IP address into a browser on the same network
    ESP32 IP address highlighted in Serial Monitor
    ESP32 Web Server Running! Your ESP32 is connected to Wi-Fi.

    How This Scales Into Real IoT Systems

    By connecting through your router instead of directly to the ESP32, you unlock the ability to:

    • Build multi-device dashboards
    • Control relays remotely
    • Monitor environmental data
    • Integrate with MQTT servers
    • Expand into home automation systems

    This simple web server forms the foundation of nearly every ESP32 IoT project.

    Troubleshooting

    • Make sure your ESP32 and browser device are on the same Wi-Fi network.
    • Check that the IP address in the Serial Monitor matches what you typed.
    • Ensure your router is not isolating devices (guest networks often block communication).
    • If the page won’t load, try restarting the ESP32 and your router.

    ESP32 IoT Systems Pathway

    Leave a comment