DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
spa_router.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file spa_router.h
6 * @brief Single-page-app micro-routing decision (DETWS_ENABLE_SPA_ROUTER).
7 *
8 * A single-page web UI does its own client-side routing: the browser navigates to `/dashboard` or
9 * `/devices/42`, but there is no such file on the device - the server must return the app shell
10 * (`index.html`) and let the JavaScript router take over, while still serving real asset files
11 * (`/app.js`, `/style.css`) and letting API calls (`/api/...`) fall through to their handlers. This is
12 * that routing decision: given a request path, return whether to serve the file, serve the shell, or
13 * pass through to the app.
14 *
15 * The rule: a path under a configured API prefix passes through; a path whose last segment has a file
16 * extension (a dot) is a real asset request; anything else is a client route and gets the shell. Pure,
17 * zero heap, no stdlib, host-testable; the caller wires the result into serve_static / the router.
18 */
19
20#ifndef DETERMINISTICESPASYNCWEBSERVER_SPA_ROUTER_H
21#define DETERMINISTICESPASYNCWEBSERVER_SPA_ROUTER_H
22
23#include "ServerConfig.h"
24#include <stddef.h>
25#include <stdint.h>
26
27#if DETWS_ENABLE_SPA_ROUTER
28
29/** @brief What to do with a request path. */
30enum class DetwsSpaAction : uint8_t
31{
32 DETWS_SPA_SERVE_FILE, ///< a real asset (has a file extension): serve it statically.
33 DETWS_SPA_SERVE_SHELL, ///< a client route (extensionless): serve the SPA shell (index.html).
34 DETWS_SPA_PASSTHROUGH ///< under the API prefix: let the app's handlers run.
35};
36
37/** @brief True if the last path segment has a file extension (a '.' after the last '/'). */
38bool detws_spa_has_extension(const char *path);
39
40/**
41 * @brief Decide how to route @p path for a single-page app.
42 * @param path the request path (e.g. "/devices/42", "/app.js", "/api/state").
43 * @param api_prefix a prefix whose paths pass through to handlers (e.g. "/api/"); null/empty = none.
44 * @return the routing action.
45 *
46 * "/" (or empty) serves the shell. A path starting with @p api_prefix passes through. A path whose last
47 * segment has an extension serves the file; otherwise the shell.
48 */
49DetwsSpaAction detws_spa_route(const char *path, const char *api_prefix);
50
51#endif // DETWS_ENABLE_SPA_ROUTER
52#endif // DETERMINISTICESPASYNCWEBSERVER_SPA_ROUTER_H
User-facing configuration for DeterministicESPAsyncWebServer.