ESP32 Web Server Tutorial : Step-by-Step Guide to Create a Web Server

Table of Contents

Overview

In this step-by-step tutorial, you’ll learn how to set up a web server with ESP32 and create a web page using HTML and CSS.

What You Will Learn

What is a Web Server?

The web server is a place to send and receive information, process the information and store it. The web server can also display this information on a web page.

the server communicates with the user through a protocol called the Hypertext Transfer Protocol (HTTP).

When a request is sent to this server (for example, its address is searched in the browser), the server returns a code as a response (for example, code 200, which means the connection is established correctly, or code 404, which indicates that the address is not correct). You can find the full list of these codes here

Required Materials

Hardware Components

ESP32 × 1

Software Apps

Arduino IDE

Setting up ESP32 in Station Mode (STA)

In this case, the ESP32 module is connected to the Wi-Fi router as a Client and can access the Internet through the router.

ESP32 Web server Code

To start the ESP32 web server in STA mode, just upload the following code on the board. If you are a beginner with ESP32, read the ESP32 tutorial here. 

/*
  ESP32 Web Server - STA Mode
  modified on 25 MAy 2019
  by Mohammadreza Akbari @ Electropeak
  
Home
*/ #include <WiFi.h> #include <WebServer.h> // SSID & Password const char* ssid = "*****"; // Enter your SSID here const char* password = "*****"; //Enter your Password here WebServer server(80); // Object of WebServer(HTTP port, 80 is defult) void setup() { Serial.begin(115200); Serial.println("Try Connecting to "); Serial.println(ssid); // Connect to your wi-fi modem WiFi.begin(ssid, password); // Check wi-fi is connected to wi-fi network while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected successfully"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); //Show ESP32 IP on serial server.on("/", handle_root); server.begin(); Serial.println("HTTP server started"); delay(100); } void loop() { server.handleClient(); } // HTML & CSS contents which display on web server String HTML = "<!DOCTYPE html>\ <html>\ <body>\ <h1>My First Web Server with ESP32 - Station Mode &#128522;</h1>\ </body>\ </html>"; // Handle root url (/) void handle_root() { server.send(200, "text/html", HTML); }

Once you’ve uploaded the code, open the serial monitor window. If you’ve entered the correct SSID and password, after a few seconds, ESP32 will connect to the router and give you an IP address. 

By entering this IP in your browser you can see the web page you have just created. 

Your PC (your browser source) should be connected to the same router as the ESP32.
Note

About the ESP32 Web server Code:

#include <WiFi.h>
#include <WebServer.h>

Two required libraries have been added at the beginning of the code. The WiFi.h library is used to set up the wifi section and WebServer.h library to build a web page. 

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

Enter the SSID and the password of your router in these two lines.

WebServer server(80);

This command defines an object called the server from the webserver class. With this object, you can create a web page on Port 80.

In the setup section, serial communication is initially started.

WiFi.begin(ssid, password);

With the WiFi.begin command, ESP32 attempts to connect to your wifi router with the SSID and the password that is defined in the code.

while (WiFi.status() != WL_CONNECTED) { 
  delay(1000); 
  Serial.print("."); 
  } 
  Serial.println(""); 
  Serial.println("WiFi connected successfully");
The above code print the “.” carachter on the serial monitor until the ESP32 is connected to the Wi-Fi router. When the connection is established correctly, “WiFi connected successfully” is displayed on the serial monitor. 
Serial.print("Got IP: "); 
Serial.println(WiFi.localIP());
Then the IP address of ESP32 will be printed on the serial monitor. To manage HTTP requests and specify what part of the code to run when a URL address is searched, the on method is used.
server.on("/", handle_root);

In the above code, when the main address (place a / after the IP) is searched in the browser, the handle_root function is called.

Finally, with the server. begin command, your web server starts working.

In the loop section, only the handleClient method is called, so your code (the server that you built) is always checking the web server to manage the events occurring on the server.

String HTML = "<!DOCTYPE html>\
<html>\
<body>\
<h1>My First Web Server with ESP32 - Station Mode &#128522;</h1>\
</body>\
</html>";

The HTML string contains the code that should be displayed on the web page. At the end of this tutorial, you can find a basic tutorial on HTML coding for beginners.

Tip
To write a command in a few lines, just add a backslash (\) at the end of each line. 
void handle_root() { 

  server.send(200, "text/html", HTML); 

}

Setting up ESP32 in Access Point Mode (AP)

In this case, ESP32 acts as a router and creates a local wifi network with the desired name and password. Since there is a limited number of devices that can connect to this connection point, it is also referred to as the Soft Access Point. 

Code

Upload the following code on your board to set up the ESP32 in the AP mode.
/*
  ESP32 Web Server - AP Mode
  modified on 25 MAy 2019
  by Mohammadreza Akbari @ Electropeak
  
Home
*/ #include <WiFi.h> #include <WebServer.h> // SSID & Password const char* ssid = "Electripeak"; // Enter your SSID here const char* password = "123456789"; //Enter your Password here // IP Address details IPAddress local_ip(192, 168, 1, 1); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); WebServer server(80); // Object of WebServer(HTTP port, 80 is defult) void setup() { Serial.begin(115200); // Create SoftAP WiFi.softAP(ssid, password); WiFi.softAPConfig(local_ip, gateway, subnet); Serial.print("Connect to My access point: "); Serial.println(ssid); server.on("/", handle_root); server.begin(); Serial.println("HTTP server started"); delay(100); } void loop() { server.handleClient(); } // HTML & CSS contents which display on web server String HTML = "<!DOCTYPE html>\ <html>\ <body>\ <h1>My First Web Server with ESP32 - AP Mode &#128522;</h1>\ </body>\ </html>"; // Handle root url (/) void handle_root() { server.send(200, "text/html", HTML); }
Connect to the connection point you made once you’ve uploaded the code.
Now enter the 192.168.1.1 IP in your browser.

About the Code

const char* ssid = "Electropeak";  

const char* password = "123456789";
In this section, you should enter an arbitrary SSID and password so that the ESP32 creates a Wi-Fi connection point with that name.
IPAddress local_ip(192, 168, 1, 1); 

IPAddress gateway(192, 168, 1, 1); 

IPAddress subnet(255, 255, 255, 0);
Then you need to enter your IP to create the network. (You can use the same IPs that are defined in the code.)
WiFi.softAP(ssid, password); 

WiFi.softAPConfig(local_ip, gateway, subnet);
The above commands create a Wi-Fi connection point.  The rest of the code is the same as STA.

HTML and CSS Basic Commands

HTML has tags that place between <>. All HTML commands should be placed between these tags. You can use this link to test your codes online.

CSS stands for Cascading Style Sheets. CSS commands specify how HTML code and instructions are displayed to the user. 

<!DOCTYPE html> 

The first line of each HTML code should be <DOCTYPE html> . This command is not an HTML command. With this code, you are anouncing the browser which version of HTML you used to write the web page.

<!DOCTYPE html>
Should be written Immediately after . All the codes are placed between this tag. 
<html> codes… <\html>

Inserting Headlines  

You can use the tags to to create headlines in different sizes.

<h1>This is heading 1</h1>

Inserting Paragraphs

Use the tag to insert a new paragraph and write your text between it.

<p>Your first paragraph.</p>
<p>Your second paragraph.</p>

Bold Texts 

You can use the  HTML tag or the  CSS command to bold the texts. 

<b>This is bold text</b>

Adding a Link 

With the tag you can place the URL as a link in your page. 

<a href="https://electropeak.com/">Visit Electropeak</a>

Adding Images 

You can add images using the tag. 

<img src="image URL" alt="Smiley face" width="42" height="42">

Adding Buttons 

With the <button> tag you can add a button to your web page.

 

To learn more about HTML and CSS commands, visit w3schools.

Related Tutorials

Liked What you see?

Get updates and learn from the best

More To Explore

Comments (24)

  • Nur Ahmad Dwi Wibowo Reply

    Hi, my name Nur Ahmad. You can call me Wiwid like others.
    I try your code to build the web server inside the esp, i think this code unique. because use String HTML to create the Web Server.
    I had try code with Client.println() to build the web server like Github share what they did.
    But, your code not give feedback when client connect to ur server.
    And i combine both, the coe from Github and your code to build script that give feedback when client connect to your server.
    But, combination not working. Because different style script when build the HTML web server

    with your style script , can you help me to script ESP32 to give feedback when client connect to our server?
    thank you

    November 8, 2019 at 8:03 am
    • Saeed Hosseini Reply

      Hi Wiwid.
      We will check it 🙂

      November 10, 2019 at 5:12 am
  • Antonio Reply

    Very interesting! Now. as a newbie, my question is related to:
    Click Me! …
    is there a way to send a digitalWrite command to the ESP32 board when the button is clicked?
    Thanks in advance 🙂

    April 4, 2020 at 12:20 pm
  • Fernanda Santos Reply

    Hello

    I’m not able to insert the images, do you have any examples that can help me? I used the same code from the reference above and inserted a line of code for the image I want, but it doesn’t work, can you help me?

    April 7, 2020 at 8:33 pm
    • Amir Mogoeir Reply

      In the code img src="image URL" , you should replace “image URL” with a real valid image URL. This one should work:
      https://electropeak.com/learn/wp-content/uploads/2019/07/webserver-cover-400x300-1.jpg

      May 30, 2020 at 1:25 pm
  • Randy Reply

    Thanks for the examples. I found that the AP mode required me to set a manual IP address. The line:

    WiFi.softAPConfig(local_ip, gateway, subnet);

    Seems to disable DHCP. Commenting it out allowed DHCP to work, but I had to add the lines:

    Serial.print(“My IP address: “);
    Serial.print(WiFi.softAPIP());

    To confirm what IP Address the ESP32 gave itself

    October 14, 2020 at 5:24 pm
    • Mehran Maleki Reply

      Thanks for sharing.

      December 6, 2020 at 11:08 am
  • Marcel K Reply

    Hello, thats a great example but I’ve one question? Where I can find the libary “WebServer.h”? I’ve tried to find in web but I’ve no access. Is it a standard libary, if yes what the name in the libary manager?

    Thanks, Marcel.

    November 8, 2020 at 9:49 am
  • Bogdan Lazar Reply

    Is it possible to have a files repo stored on the board so that I can host an existing webpage? (HTML, CSS and some images) Or maybe link the file tree to the board? Thanks in advance!

    December 4, 2020 at 9:31 am
    • Mehran Maleki Reply

      Yes, it’s possible. You can do that based on the tutorial explained in this article. But in order to make a public webpage, you will need static IP and config your rooter/modem.

      December 9, 2020 at 2:33 pm
  • Simple photo tips Reply

    An execllent posting from you, all helpful in stuffing my head
    up with helpful knowledge. I’ve also taken the time to
    share this on Twitter 🙂

    March 8, 2021 at 11:13 am
    • Mehran Maleki Reply

      You’re most welcome! And thanks for sharing.

      March 10, 2021 at 2:25 pm
  • Outdoor gardening Reply

    Your website has provided me a lot of useful info, and for that I thank you very much.
    This informative article is one of the best I’ve read up to now on your
    web site, so I felt I needed to take the time to comment.

    You have given myself a variety of tips to help me in the foreseeable future.

    April 20, 2021 at 4:18 pm
    • Mehran Maleki Reply

      You’re most welcome! We’re filled up with energy by such motivating comments.

      April 21, 2021 at 5:38 am
  • Vinícius Barros Reply

    I’m having a problem after uploading the code in the board.
    It says: “leaving… Hard resetting via RTS pin”
    what should I do?
    I’m connecting the esp32 directly at the USB of my computer, with no resistance and stuff.
    I’m trying to make the web server to work, with ssid and password filled correctly.
    Thanks for the explaining, it was pretty good.

    August 18, 2021 at 4:31 pm
    • Mehran Maleki Reply

      Hi Vinicius,
      You’ve got no problem actually! This message means that the uploading has been successfully done.

      August 21, 2021 at 7:43 am
      • Vinícius Barros Reply

        I see… thanks for the information. One more thing: Is it normal that the serial monitor is completely empty? It is completely white… and i can’t access the server even with my correct ip address.

        August 23, 2021 at 2:27 pm
      • Vinícius Barros Reply

        Wow! It worked! I just had to press the RTS button to the module run the uploades code.
        Thanks a lot Mehran! Have a nice life!

        August 23, 2021 at 2:46 pm
        • Mehran Maleki Reply

          You’re quite welcome!
          You too!

          August 25, 2021 at 5:46 am
  • Javier Otero Reply

    very intersting

    April 8, 2022 at 9:25 pm
    • Mehran Maleki Reply

      Thanks!🙏

      April 9, 2022 at 6:48 am
  • haretha Reply

    hi..
    it is amazing
    but i have a question please
    how can i handle Input Fields with webserver.h esp32? and reading query parameters in url?
    is there a clear documents for webserver ?
    and thank you so much

    October 3, 2022 at 10:54 am

Leave a Reply

Your email address will not be published. Required fields are marked *