Mithril m.route pushState and static hosting: missing SPA fallback on direct deep-link requests?
0 reputation · 29 Feb 2020, 02:22 UTC
0 reputation · 29 Feb 2020, 02:22 UTC
Run a Mithril SPA in production behind a static host or CDN while keeping the default History-API (`pushState`) mode of `m.route`. Direct browser entry or a hard refresh on a client route such as `/users/42` must return the SPA shell so Mithril can mount and render the route, rather than the host's 404 page.
Local preview servers often apply a history-API fallback automatically, which hides the gap during development. Mithril itself performs no server configuration and emits no build-time warning when the production fallback is absent. The unresolved choice is between adding a host-specific SPA rewrite/fallback and switching to hash-based routing. Hash routing removes the server dependency because the route stays after `#`, but the fragment is not sent to the server, which can affect analytics, canonical URLs, and logs. The History-vs-hash toggle is stable across Mithril 1.x and 2.x, but the exact property or function name should be confirmed against the installed version before changing application code.
35275 reputation · 29 Feb 2020, 04:46 UTC
The SPA fails to load on a direct request because the static host returns a 404 for URLs that do not map to a file, and Mithril’s pushState routing expects the HTML page to be served.
m.route uses the HTML5 History API (pushState) in versions 1.x and 2.x.m.route.mode function toggles between pushState and hash modes; it is client‑side only and does not affect server configuration.index.html for unknown paths, the browser receives a 404 and the SPA never mounts.m.versionand confirm that
m.route.mode exists.location block, or CDN page rule) for a rule that returns index.html when the requested path does not correspond to a static file.# Apache example
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ /index.html [L]/users/42, and verify that the network request for index.html is made and that Mithril mounts the route without a full reload.Switching to hash‑based routing with m.route.mode('hash') eliminates the need for a rewrite because the fragment after # is not sent to the server. This removes the server‑side dependency but breaks canonical URLs, SEO‑friendly paths, and log visibility.
Confirm whether the production host already has a rewrite rule that serves index.html for non‑file requests; if not, the rewrite is the minimal change required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.