miso

Platform

Development & debugging

When developing interactively it is possible to append styles and scripts to the <head> of the page when a component mounts. This is a convenience meant only for development — guard it behind a flag.

main :: IO ()
main = startApp defaultEvents app
 where
   app = counter
#ifdef INTERACTIVE
     { scripts = [ Src "https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js" (False :: CacheBust) ]
     , styles  = [ Href "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" (False :: CacheBust) ]
     }
#endif

Live reloading

The WASM backend ships a browser-mode GHCi. Run make watch in the sample app: ghciwatch reloads on save and calls :main, and Miso.Reload.live (used instead of startApp under the INTERACTIVE flag) clears the page and remounts. liveWithContext does the same for apps that seed a context; when a component's model can be recovered by key it is preserved across reloads.

$ make watch
# ghciwatch --after-startup-ghci :main --after-reload-ghci :main --watch *.hs \
#   --command 'wasm32-wasi-cabal repl app -finteractive --repl-options="-fghci-browser -fghci-browser-port=8080"'

Debugging

Sometimes things go wrong. Using onClick without listening for the click event is a common error that cannot be caught statically. Enable DebugAll to detect these; currently debugging event delegation and page hydration is supported.

DebugHydrate
warn if the structure or properties of the DOM and the virtual DOM differ during prerendering
DebugEvents
warn if an event cannot be routed to the handler that raised it, or a handler is used for an event nobody listens for
DebugAll
both of the above
counter { logLevel = DebugAll }