ESP8266: Setting a simple HTTP web server

The objective of this post is to explain how to set a HTTP web server on a ESP8266 and how to make some requests to it using a web browser.


The objective of this post is to explain how to set an HTTP web server on a ESP8266 and how to make some requests to it using a web browser.

We assume the use of the ESP8266 libraries for the Arduino IDE. You can check here how to configure the Arduino IDE to support the ESP8266.

The tests were performed using a NodeMCU board, a very cheap and easy to use ESP8266 board. The board can be bought at eBay here.

The code

First of all, we include the ESP8266WiFi library, which will make available the functionality needed for the ESP8266 to connect to a WiFi network. You can check a more detailed explanation on how to connect to a WiFi network from the ESP8266 on this previous post.

Then, we include the ESP8266WebServer library, which will make available the class ESP8266WebServer that we will use during this post. Naturally, this class has some methods available that will help us setting up a server and handle incoming HTTP requests without needing to worry about low level implementation details. You can check the implementation of the library here.

#include "ESP8266WiFi.h"
#include "ESP8266WebServer.h"

Next, we declare a global object variable from the previously mentioned class, so we will be able to access it in our functions.

As argument for the constructor of this class, we will pass the port where the server will be listening to. Since 80 is the default port for HTTP [1], we will use this value, so we will not need to specify it in the URL when accessing to our ESP8266 server using a browser.

ESP8266WebServer server(80);

Since we need to pre-configure our HTTP server before actually running it, we will do most of the coding in the setup function.

First of all, we open a serial connection for debugging.


Then, we will need to connect to the WiFi network, as shown with the code below. If you need a detailed explanation on how to connect to a WiFi network with the ESP8266, check here.

WiFi.begin("Network name", "Password");

while (WiFi.status() != WL_CONNECTED) {   //Wait for connection

   Serial.println("Waiting to connect...");


Since we are not going to do any domain name resolution, we need to know the IP where the ESP8266 is listening to incoming requests, which will be the local IP assigned in the WiFi network.

To get this value, we just call the localIP method on the WiFi global variable and then print it to the serial port, so we will know which URL to call on our web browser.


Then, we will start to specify which code to execute when an HTTP request is performed to each path. To do so, we call the on method on our previously declared server global object.

The more elegant method consists on defining a handling function somewhere in our code and passing it to the on function, alongside the URL that will trigger the execution of that function. This is exemplified below.

server.on("/", handleRootPath);

So, the code mentioned bellow indicates that when an HTTP request is received on the root (“/”) path, it will trigger the execution of the handleRootPath function. Note that we don’t specify the IP or port where the ESP8266 is listening, but only the path of the URL from that point onward.

For the sake of simplicity, let’s assume that our handleRootPath only answers with the text “Hello World” to the incoming HTTP request. So, to define an answer to a request, we call the send method on our server object.

Although the method can be called with a different set of arguments, its simplest form consists on receiving the HTTP response code, the content type and the content. Check the code below.

void handleRootPath() {

   server.send(200, "text/plain", "Hello world");


In this case, we are sending the code 200, which corresponds to the “OK” response [2]. Then, we are specifying the content type as “text/plain“, since we are only responding with a simple “Hello world”, and finally the actual response text.

Naturally, this function needs to be declared outside the setup function.

We can also specify the handling function when calling the on method. In this case, we don’t need to declare a separate function and we can do everything in the setup function, as demonstrated bellow.

server.on("/other", [](){

   server.send(200, "text/plain", "Other URL");


In this case, if we receive an HTTP request in the path “/other”, we will answer with a “Other URL” sentence.

Now, to start our server, we call the begin method on the server object. This is the last line of code we need to include in our setup function.


Finally, to handle the actual incoming of HTTP requests, we need to call the handleClient method on the server object, on the main loop function.

void loop() {



The complete code can be seen bellow.

#include "ESP8266WiFi.h"
#include "ESP8266WebServer.h"

ESP8266WebServer server(80);

void setup() {

  WiFi.begin("Network name", "Password");  //Connect to the WiFi network

  while (WiFi.status() != WL_CONNECTED) {  //Wait for connection

    Serial.println("Waiting to connect…");


  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //Print the local IP

  server.on("/other", []() {   //Define the handling function for the path

    server.send(200, "text / plain", "Other URL");


  server.on("/", handleRootPath);    //Associate the handler function to the path
  server.begin();                    //Start the server
  Serial.println("Server listening");


void loop() {

  server.handleClient();         //Handling of incoming requests


void handleRootPath() {            //Handler for the rooth path

  server.send(200, "text/plain", "Hello world");


Testing the code

To test the code we just need to open our browser and make an HTTP request to the IP of the ESP8266, on a path we defined early. The format is shown bellow:


Since, as stated before, we are listening on the 80 port, the browser will assume it by default, so we don’t need to specify it:


So, we substitute the serverIP by the IP printed on the serial console, and we make a request as shown in figure 1.


Figure 1 – HTTP request via browser on the root path (Google Chrome).

In this case, only the IP is shown because the browser removed the “/” from the root path. Also, the http:// was removed by the browser. Although some browsers perform the request when we only specify the IP, others assume that we want to search something in a search engine. So, the safest way is to always specify the http:// before the IP.

The example from figure 2 shows a request on the path “/other” that we also defined.


Figure 2 – HTTP request via browser on the “/other” path (Firefox).

Finally, note that if we specify a path not defined, the ESP will return a message indicating that the resource was not found, as we can see in figure 3, where we sent an HTTP request to the path “/notdefined”.


Figure 3 – HTTP request via browser on a path not defined.

Important: The IP that will be printed by the ESP8266 will be its private IP on the network. It won’t be possible for a client outside the network to contact it on that IP (and thus, the URL will not work). In order for a client to be able to contact the ESP8266 from outside its network, it would need to use the external IP of the network and the router would need to be configured to forward the requests on its public IP for that port to the private IP of the ESP8266. Since port forwarding depends on the router used, explaining how to do it is outside of the scope of this post.

Related posts




Technical details

ESP8266 libraries: v2.3.0

39 thoughts on “ESP8266: Setting a simple HTTP web server”

  1. Hi,
    How I install in the Arduino IDE and add to the project the ESP8266WebServer library?.

    Best Regards,

  2. Hi,
    How I install in the Arduino IDE and add to the project the ESP8266WebServer library?.
    Best Regards,

Leave a Reply