ESP32 S3 - Web Server on SD Card

In this tutorial, you will learn how to build a web server on the ESP32 S3 that serves web content directly from a MicroSD Card. Hosting your HTML, CSS, JavaScript, and image files on a MicroSD Card is a practical approach when your web pages are too large to store in the ESP32 S3's internal flash memory.

ESP32 S3 web server on a MicroSD card - serve HTML, CSS and image files from the SD card

What you'll build:

  1. An ESP32 S3 web server that connects to your local WiFi network
  2. A MicroSD Card module wired to the ESP32 S3 via SPI
  3. An HTML page with CSS styling and an image served from the SD card
  4. A browser-accessible web page reachable by IP address on any device on the network

Overview of ESP32 S3 and Web Server

The ESP32 S3 is a powerful microcontroller with built-in WiFi and Bluetooth, making it well-suited for web server projects. When combined with a MicroSD Card module over SPI, you can serve rich web content — including styled pages and images — without consuming precious internal flash storage. If you're not yet familiar with the ESP32 S3's web server or MicroSD Card capabilities, the following tutorials provide the necessary background:

Key Specifications

  • Microcontroller: Xtensa LX7 dual-core, up to 240 MHz
  • Built-in WiFi: 802.11 b/g/n (2.4 GHz)
  • Flash: 16 MB | PSRAM: 8 MB
  • SPI interface for MicroSD Card module
  • USB Type-C for programming and power

Wiring Diagram

Connect the MicroSD Card module to the ESP32 S3 using the SPI interface, ensuring all data and power lines are correctly mapped before powering the board.

The wiring diagram between ESP32 S3 Micro SD Card Module

This image is created using Fritzing. Click to enlarge image

Safety Notes

Always power down the ESP32 S3 before connecting or disconnecting the MicroSD Card module to avoid corrupting the card or damaging the SPI bus. Use a logic level-compatible SD card module (3.3 V) since the ESP32 S3 GPIO pins operate at 3.3 V — connecting a 5 V module directly may damage the board.

ESP32 S3 PinMicroSD Card Module Pin
3.3VVCC
GNDGND
GPIO10CS
GPIO11MOSI
GPIO12SCK
GPIO13MISO

Copy HTML Contents to MicroSD Card

Before uploading code to the ESP32 S3, prepare your SD card with the web files it will serve. Format the MicroSD Card using FAT32 (on Windows: right-click the drive → Format → select FAT32), then create the following files in the root directory of the card.

  • Please make sure that your Micro SD Card is formatted on FAT32 format as below (on Windows OS, right mouse click → format):
Micro SD Card format FAT32
  • Create a HTML file index.html and add the following code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ESP32 S3 Web Page</title> <link rel="icon" href="favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="container"> <h1>Web Page hosted on MicroSD Card</h1> <img src="luffy.jpg" alt="A beautiful image"> <p>Sponsored by <a href="https://amazon.com/diyables">DIYables</a></p> </div> </body> </html>
  • Create a CSS file styles.css and add the following code:
body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: white; } h1 { font-size: 28px; } .container { max-width: 800px; margin: 20px auto; text-align: center; } img { max-width: 80%; height: auto; display: block; margin: 20px auto; }
  • Prepare an image. This tutorial uses luffy.jpg, which is used in HTML code. You can download this image here:
luffy
  • (Optional) Prepare favicon image. This tutorial uses this favicon.ico
  • Put all files in the root directory of MicroSD Card, like below images:
ESP32 S3 HTML contents on microSD Card

Please note that you can add other files such as JavaScript, txt, csv...

ESP32 S3 Code - Web Server on MicroSD Card

The following code configures the ESP32 S3 as a web server that reads and serves files directly from the MicroSD Card over the SPI interface. When a browser requests a file, the server opens it from the SD card and streams it to the client, including proper MIME type headers for HTML, CSS, JavaScript, and image files. Update the WiFi credentials in the code to match your network before uploading.

/* * This ESP32 S3 code was developed by newbiely.com * * This ESP32 S3 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3/esp32-s3-web-server-on-sd-card */ /* * This ESP32-S3 code is created by esp32io.com * * This ESP32-S3 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-s3-web-server-on-sd-card */ #include <WiFi.h> #include <WebServer.h> #include <FS.h> #include <SPI.h> #include <SD.h> // MicroSD Card module on the default SPI pins: // CS -> ESP32-S3 pin GPIO10, MOSI -> ESP32-S3 pin GPIO11, SCK -> ESP32-S3 pin GPIO12, MISO -> ESP32-S3 pin GPIO13 #define PIN_SPI_CS 10 // ESP32-S3 pin GPIO10 connected to the CS pin of the MicroSD Card module // Replace with your network credentials const char* ssid = "YOUR_WIFI_SSID"; // CHANGE IT const char* password = "YOUR_WIFI_PASSWORD"; // CHANGE IT WebServer server(80); // create a web server object on port 80 // return the content type of a file from its extension String getContentType(const String& path) { if (path.endsWith(".html") || path.endsWith(".htm")) return "text/html"; if (path.endsWith(".css")) return "text/css"; if (path.endsWith(".js")) return "application/javascript"; if (path.endsWith(".json")) return "application/json"; if (path.endsWith(".png")) return "image/png"; if (path.endsWith(".jpg") || path.endsWith(".jpeg")) return "image/jpeg"; if (path.endsWith(".gif")) return "image/gif"; if (path.endsWith(".ico")) return "image/x-icon"; if (path.endsWith(".svg")) return "image/svg+xml"; if (path.endsWith(".txt")) return "text/plain"; if (path.endsWith(".csv")) return "text/csv"; return "application/octet-stream"; } // read the requested file from the MicroSD Card and send it to the browser void handleFile() { String path = server.uri(); if (path.endsWith("/")) path += "index.html"; // the home page is index.html if (!SD.exists(path)) { server.send(404, "text/plain", "404: File Not Found"); return; } Serial.print("Serving file: "); Serial.println(path); File file = SD.open(path, FILE_READ); server.streamFile(file, getContentType(path)); file.close(); } void setup() { Serial.begin(115200); // init MicroSD Card if (!SD.begin(PIN_SPI_CS)) { while (1) { Serial.println(F("SD CARD FAILED, OR NOT PRESENT!")); delay(1000); } } // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // Print the ESP32-S3's IP address Serial.print("ESP32 S3 Web Server's IP address: "); Serial.println(WiFi.localIP()); server.onNotFound(handleFile); // every request is served from the MicroSD Card server.begin(); } void loop() { server.handleClient(); }

Detailed Instructions

  1. New to ESP32 S3? Complete our Getting Started with ESP32 S3 guide first.
  2. Connect the MicroSD Card module to the ESP32 S3 board following the wiring diagram above.
  3. Format your MicroSD Card as FAT32 and copy the HTML, CSS, and image files to its root directory.
  4. Connect the ESP32 S3 board to your PC via a USB Type-C cable.
  5. Open Arduino IDE on your PC.
  6. Select the right ESP32 S3 board (e.g. ESP32S3 Dev Module) and the correct COM port.
  7. Open the Library Manager by clicking on the Library Manager icon on the left navigation bar of Arduino IDE.
  8. Search "DIYables ESP32 WebServer", then find the Web Server library created by DIYables.
  9. Click Install button to install the Web Server library.
  • Search for DIYables ESP32 WebServer created by DIYables.io and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Library Manager
Type:
All
Topic:
All
DIYables ESP32 WebServer by DIYables.io
DIYables ESP32 WebServer library designed for ESP32 boards. It includes multi-page web server capabilities and WebSocket support for real-time communication, perfect for IoT projects and DIYables ESP32 boards. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32S3 Dev Module on COM15
1
  1. Copy the above code and open with Arduino IDE.
  2. Change the WiFi information (SSID and password) in the code to yours.
  3. Click Upload button on Arduino IDE to upload code to ESP32 S3.
  4. Open the Serial Monitor and set the baud rate to 115200.
  5. Check out the result on Serial Monitor.
  6. Pro Tip: You can update your web page content (HTML, CSS, images) by simply swapping or editing files on the MicroSD Card — no need to re-upload the ESP32 S3 firmware each time.

Serial Monitor

After the code uploads successfully, open the Serial Monitor to confirm the ESP32 S3 connects to WiFi and starts the web server. You should see output similar to the following readings:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
[2026-01-15 08:32:11] Connecting to WiFi... [2026-01-15 08:32:14] Connected to WiFi [2026-01-15 08:32:14] ESP32 S3 Web Server's IP address: 192.168.0.3 [2026-01-15 08:32:28] Serving file: /index.html
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  • You will see an IP address on the Serial Monitor, for example: 192.168.0.3
  • Type the IP address on the address bar of a web browser on your smartphone or PC.
  • Please note that you need to change the 192.168.0.3 to the IP address you got on Serial Monitor.
  • You will see a page loads HTML, CSS, images from SD Card.
ESP32 S3 Web page on SD Card

As you can see, the HTML, CSS, and images stored on the MicroSD Card were loaded by the web browser. You can now modify the HTML and CSS files on the SD card and refresh your browser to see changes immediately, without re-uploading the firmware.

Applications

Serving web content from a MicroSD Card opens up a wide range of practical use cases where the web interface is too large or too dynamic to fit in internal flash memory:

  1. Home Automation Dashboard: Host a full-featured control panel with multiple pages, icons, and scripts to monitor and control smart home devices.
  2. Data Logger Display: Serve a web page that reads and displays CSV log files stored on the same SD card, giving you a browser-based data viewer.
  3. Portable Information Kiosk: Deploy a self-contained informational display (e.g. at a museum or tutorial) that serves a multi-page website from a single ESP32 S3 device.
  4. OTA Web Interface: Host an update page on the SD card that allows users to configure WiFi credentials or device settings without reflashing the firmware.
  5. Media Gallery: Serve image galleries or small audio files from the SD card for lightweight multimedia projects.

Video Tutorial

Watch the step-by-step video walkthrough for this ESP32 S3 project below.

Challenges

Now that your ESP32 S3 web server is serving files from a MicroSD Card, try extending the project with these challenges to deepen your understanding:

  1. Beginner: Add a second HTML page (e.g. about.html) to the SD card and create a navigation link between index.html and the new page.
  2. Intermediate: Add a JavaScript file on the SD card that periodically fetches a sensor reading from a new /data endpoint on the ESP32 S3 and displays it on the web page without a page reload.
  3. Advanced: Implement a file upload endpoint on the ESP32 S3 web server so that users can upload new HTML or image files directly to the MicroSD Card from a browser, enabling fully remote content management.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!