Elmish.HTML.Boot.Internal
- Package
- purescript-elmish-html
- Repository
- collegevine/purescript-elmish-html
This is an internal module. Do not use directly. Use Elmish.HTML.Boot or
Elmish.HTML.React17.Boot instead.
#BootRecord Source
type BootRecord props = { hydrate :: String -> props -> Effect Unit, mount :: String -> props -> Effect Unit, renderToString :: props -> String }Support for the most common case entry point - mounting an Elmish component
(i.e. ComponentDef' structure) to an HTML DOM element with a known ID,
with support for server-side rendering.
The function boot returns what we call BootRecord - a record of three
functions:
mount- takes HTML element ID and props¹, creates an instance of the component, and mounts it to the HTML element in questionhydrate- same asmount, but expects the HTML element to already contain pre-rendered HTML inside. See React docs for more on server-side rendering: https://react.dev/reference/react-dom/client/hydrateRootrenderToString- meant to be called on the server (e.g. by running the code under NodeJS) to perform the server-side render. Takes props¹ and returns aStringcontaining the resulting HTML.
The idea is that the PureScript code would export such BootRecord for
consumption by bootstrap JavaScript code in the page and/or server-side
NodeJS code (which could be written in PureScript or not). For "plain
React" scenario, the JavaScript code in the page would just call mount.
For "server-side rendering", the server would first call renderToString
and serve the HTML to the client, and then the client-side JavaScript code
would call hydrate.
¹ "props" here is a parameter used to instantiate the component (see example below). It is recommended that this parameter is a JavaScript record (hence the name "props"), because it would likely need to be supplied by some bootstrap JavaScript code.
Example:
-- PureScript:
module Foo(bootRecord) where
import Elmish.HTML.Boot (BootRecord, boot)
type Props = { hello :: String, world :: Int }
component :: Props -> ComponentDef' Aff Message State
component = ...
bootRecord :: BootRecord Props
bootRecord = boot component
// Server-side JavaScript NodeJS code
const foo = require('output/Foo/index.js')
const fooHtml = foo.bootRecord.renderToString({ hello: "Hi!", world: 42 })
serveToClient("<html><body><div id='foo'>" + fooHtml + "</div></body></html>")
// Client-side HTML + JS:
<html>
<body>
<div id='foo'>
... server-side-rendered HTML goes here
</div>
</body>
<script src="foo_bundle.js" />
<script>
Foo.bootRecord.hydrate('foo', { hello: "Hi!", world: 42 })
</script>
</html>
#DomApi Source
type DomApi = { hydrate :: ReactElement -> Element -> Effect Unit, render :: ReactElement -> Element -> Effect Unit, renderToString :: ReactElement -> String }This is an internal record. Do not use directly. Use functions from
Elmish.HTML.Boot or Elmish.HTML.React17.Boot instead.
The common surface between React 17 and React 18+ APIs. The functions below
consume it to implement mounting and SSR logic. The Elmish.HTML.Boot and
Elmish.HTML.React17.Boot modules provide an implementation for React 18+
or React 17 respectively.
#bootWith Source
bootWith :: forall msg state props. DomApi -> (props -> ComponentDef msg state) -> BootRecord propsThis is an internal function. Use Elmish.HTML.Boot.boot or
Elmish.HTML.React17.boot instead.
Creates a boot record that mounts through the given DomApi. See comments
for BootRecord.
#defaultMainWith Source
defaultMainWith :: forall msg state. DomApi -> { def :: ComponentDef msg state, elementId :: String } -> Effect UnitThis is an internal function. Use Elmish.HTML.Boot.defaultMain or
Elmish.HTML.React17.Boot.defaultMain instead.
Mounts the given component to the element with the given ID, through the
given DomApi. See comments for defaultMain in Elmish.HTML.Boot and
Elmish.HTML.React17.Boot.