svelteesp32

repository·main·Indexed 42 days ago

https://github.com/bcsabaengine/svelteesp32

A tool to convert Svelte or other frontend JS applications into a single C++ header file for serving from ESP32 or ESP8266 web servers. It supports engines such as PsychicHttp, ESPAsyncWebServer, and Arduino WebServer, eliminating the need for separate filesystem partitions like SPIFFS or LittleFS. Version 3.2.6 provides features for Gzip compression, ETag caching, and SPA configurations to enable efficient flash-based serving and single-binary OTA updates.

Tokens
17.4K
Snippets
50
Records
66
Agent score
51%

What's inside svelteesp32

  1. Understand the generated svelteesp32 header content

    main

    The generated header file contains:

    • Metadata: Engine and configuration details.
    • Constants: File counts (SVELTEESP32_COUNT), total uncompressed size (SVELTEESP32_SIZE), and total gzip size (SVELTEESP32_SIZE_GZIP).
    • Data Arrays: static const uint8_t arrays containing the gzipped file data.
    • ETags: static const char arrays for file ETags.
    • File Manifest: A SVELTEESP32_FileInfo struct array (SVELTEESP32_FILES) containing path, size, gzipSize, etag, and contentType for each file.
    • Initialization Function: A function (e.g., initSvelteStaticFiles) that sets up the routes and handles requests, including ETag/304 logic and Gzip content encoding.
    • Weak Hook: An extern "C" void __attribute__((weak)) SVELTEESP32_onFileServed(const char* path, int statusCode) function that you can override for logging or metrics.
  2. Understand SvelteESP32 Build Environments and Flags

    main

    SvelteESP32 generates different header variants based on ETag, Gzip, and SPA configurations. Each environment corresponds to a specific directory under include/ which must be added to your include path (-I).

    Environment Suffix Key

    • e: --etag=always enabled.
    • g: --gzip=always enabled.
    • c: Feature is compiler-controlled (requires #ifdef and build defines).
    • _: Feature is disabled.

    Environment Mapping Table

    EnvironmentHeader FlagsBuild DefinesNotes
    idfNoneNoneDefault
    idf_E--etag=alwaysNone
    idf_G--gzip=alwaysNone
    idf_EG--etag=always --gzip=alwaysNone
    idf_EC--etag=compilerSVELTEESP32_ENABLE_ETAG
    idf_GC--gzip=compilerSVELTEESP32_ENABLE_GZIP
    idf_ECG--etag=compiler --gzip=alwaysSVELTEESP32_ENABLE_ETAG
    idf_EGC--etag=always --gzip=compilerSVELTEESP32_ENABLE_GZIP
    idf_ECGC--etag=compiler --gzip=compilerSVELTEESP32_ENABLE_ETAG, SVELTEESP32_ENABLE_GZIP
    idf_SPA--etag=always --gzip=always --spa --basepath=/uiNoneRoutes live under /ui instead of /

    All variants are generated with --cachetime=86400.

  3. How svelteesp32 fits into the development workflow

    main

    SvelteESP32 is designed to be used in the release step, not the daily development loop.

    1. Inner Loop (Daily Dev): Develop your frontend using standard tools like vite dev. Use hot reloading and point your frontend's fetch() calls to the ESP32's REST API (either a real device on your network or a mock server). This avoids the slow process of flashing firmware every time you change a UI component.
    2. Release Step (Deployment): When the UI is ready, run npm run build to generate the dist/ folder, then use npx svelteesp32 (or the Vite plugin) to generate the C++ header. Finally, compile this header into your firmware and flash/OTA the device.
  4. How the Svelte DEMO app integrates with ESP32 firmware

    main

    The Svelte DEMO app demonstrates how a reactive web application (HTML, JS, CSS) is served directly from an ESP32.

    Workflow:

    1. Build the UI: Running npm run build in the demo directory produces a dist folder containing the compiled Svelte application.
    2. Firmware Integration: The ESP32 firmware (implemented via psychic, async, or webserver engines in ../esp32/src, or espidf in ../esp32idf/src/main.c) serves these static files alongside API endpoints.
    3. Data Flow: The application interacts with the hardware by calling JSON endpoints. For example, src/App.svelte calls GET /api/status and POST /api/toggle to manage LED status and uptime.
    4. Header Generation: Running the root project's dev commands (e.g., npm run dev:psychic) watches src/index.ts and converts the dist folder into a C++ header file (demo/esp32/include/svelteesp32.h), which is then flashed to the ESP32 via PlatformIO.
    # Build the Svelte application
    npm run build
    
    # From the repo root, watch and convert dist to C++ header
    npm run dev:psychic
  5. Setup the PlatformIO ESP32 demo project

    main

    To use the minimalistic PlatformIO project as a template for embedding Svelte static files into an ESP32 application, follow these steps:

    1. Configure WiFi Credentials: Copy src/credentials.h.example to src/credentials.h and enter your WiFi SSID and password.
    2. Generate Headers: Run the packaging script from the repository root to generate the necessary header files into the include/ directory.

    Important: The generated headers are gitignored. Do not hand-edit them; always regenerate them using the script to ensure consistency with your web assets.

    # From the repo root
    ./package.script
  6. Integrate svelteesp32 with ESP32 Web Servers

    main

    Once the header file is generated, include it in your C++ project and call the generated initialization function (default: initSvelteStaticFiles) with your server instance.

    // PsychicHttpServer V2 (Recommended)
    #include <PsychicHttp.h>
    #include "svelteesp32.h"
    PsychicHttpServer server;
    void setup() {
        server.listen(80);
        initSvelteStaticFiles(&server);
    }
    
    // ESPAsyncWebServer
    #include <ESPAsyncWebServer.h>
    #include "svelteesp32.h"
    AsyncWebServer server(80);
    void setup() {
        initSvelteStaticFiles(&server);
        server.begin();
    }
    
    // Arduino WebServer
    #include <WebServer.h>
    #include "svelteesp32.h"
    WebServer server(80);
    void setup() {
        initSvelteStaticFiles(&server);
        server.begin();
    }
    void loop() {
        server.handleClient();
    }
    
    // Native ESP-IDF
    #include <esp_http_server.h>
    #include "svelteesp32.h"
    httpd_handle_t server = NULL;
    void app_main() {
        httpd_config_t config = HTTPD_DEFAULT_CONFIG();
        httpd_start(&server, &config);
        initSvelteStaticFiles(server);
    }
  7. Quick Setup with `init`

    main

    Use the init command to interactively create a .svelteesp32rc.json configuration file. This avoids having to pass numerous CLI flags manually. The command will prompt you for the engine, source path, output path, and ETag preference, then write the RC file and optionally run the tool immediately.

    npx svelteesp32 init
  8. Integrate svelteesp32 with ESP-IDF (CMake)

    main

    For ESP-IDF projects, use add_custom_command in your CMakeLists.txt to regenerate the header during the build process. This allows you to leverage specific caching strategies, such as setting cachetimehtml=0 (to ensure index.html is never cached and always checks for updates) and a long cachetimeassets (to cache content-hashed JS/CSS bundles for up to a year).

    // CMakeLists.txt
    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/main/svelteesp32.h
        COMMAND npm run build
        COMMAND npx svelteesp32
            -e espidf
            -s ${CMAKE_CURRENT_SOURCE_DIR}/frontend/dist
            -o ${CMAKE_CURRENT_SOURCE_DIR}/main/svelteesp32.h
            --etag=always --gzip=always
            --cachetimehtml=0 --cachetimeassets=31536000
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        COMMENT "Generating svelteesp32.h from frontend build"
        VERBATIM
    )
    
    add_custom_target(frontend_header
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main/svelteesp32.h
    )
    
    add_dependencies(${COMPONENT_LIB} frontend_header)
    
    // main/app_main.c
    #include <esp_http_server.h>
    #include "svelteesp32.h"
    
    void app_main(void) {
        // ... WiFi init ...
        httpd_config_t config = HTTPD_DEFAULT_CONFIG();
        config.max_uri_handlers = SVELTEESP32_MAX_URI_HANDLERS;
        httpd_handle_t server = NULL;
        httpd_start(&server, &config);
        initSvelteStaticFiles(server);
    }
  9. Enable SPA Routing (Client-Side Routers)

    main

    If your web app uses a client-side router (like SvelteKit or Vue Router), refreshing a sub-page (e.g., /settings) will return a 404 unless you enable SPA mode. Adding the --spa flag makes all unmatched GET requests fall through to index.html.

    Requirement: The source directory must contain an index.html or index.htm file.

    npx svelteesp32 -e async -s ./dist -o ./output.h --spa
  10. Generate Header File via CLI

    main

    You can manually generate the C++ header file using the CLI by specifying the engine (-e), source path (-s), and output path (-o).

    # PsychicHttpServer (recommended for ESP32)
    npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always
    
    # ESPAsyncWebServer (ESP32 + ESP8266)
    npx svelteesp32 -e async -s ./dist -o ./esp32/svelteesp32.h --etag=always
    
    # Arduino WebServer (ESP32, synchronous, no dependencies)
    npx svelteesp32 -e webserver -s ./dist -o ./esp32/svelteesp32.h --etag=always
    
    # Native ESP-IDF
    npx svelteesp32 -e espidf -s ./dist -o ./esp32/svelteesp32.h --etag=always
  11. Generate a C++ header from a web app using the CLI

    main

    After building your frontend (using Vite, Rollup, or Webpack), use the svelteesp32 CLI to convert your dist/ directory into a single C++ header file. This header can be included in your ESP32/ESP8266 project to serve the web app directly from flash memory.

    Basic Usage

    npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always

    Production-Safe Defaults

    For production, it is recommended to enable gzip compression, ETags for caching, and specific cache-control headers to ensure HTML is never cached (so updates are immediate) while assets (JS/CSS) are cached heavily.

    npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h \
      --etag=always --gzip=always --cachetimehtml=0 --cachetimeassets=31536000