hyperapp-render
Version:
Render Hyperapp to an HTML string with SSR and Node.js streaming support
145 lines (108 loc) • 5.61 kB
Markdown
[](https://www.npmjs.com/package/hyperapp-render)
[](https://www.npmjs.com/package/hyperapp-render)
[](https://bundlephobia.com/result?p=hyperapp-render)
[](https://discord.gg/eFvZXzXF9U 'Join us')
This library is allowing you to render
[](https://github.com/hyperapp/hyperapp) views to an HTML string.
- **User experience** — Generate HTML on the server and send the markup
down on the initial request for faster page loads. Built-in
[](https://github.com/hyperapp/hyperapp/tree/1.2.9#mounting)
feature in Hyperapp is allowing you to have a very performant first-load experience.
- **Accessibility** — Allow search engines to crawl your pages for
[](https://en.wikipedia.org/wiki/Search_engine_optimization) purposes.
- **Testability** — [Check HTML validity](https://en.wikipedia.org/wiki/Validator) and use
[](https://jestjs.io/docs/en/snapshot-testing.html)
to improve quality of your software.
Our first example is an interactive app from which you can generate an HTML markup.
Go ahead and [try it online](https://codepen.io/frenzzy/pen/zpmRQY/left/?editors=0010).
```jsx
import { h } from 'hyperapp'
import { renderToString } from 'hyperapp-render'
const state = {
text: 'Hello'
}
const actions = {
setText: text => ({ text })
}
const view = (state, actions) => (
<main>
<h1>{state.text.trim() === '' ? '👋' : state.text}</h1>
<input value={state.text} oninput={e => actions.setText(e.target.value)} />
</main>
)
const html = renderToString(view(state, actions))
console.log(html) // => <main><h1>Hello</h1><input value="Hello"/></main>
```
Looking for a boilerplate?
Try [Hyperapp Starter](https://github.com/kriasoft/hyperapp-starter)
with pre-configured server-side rendering and many more.
Using [npm](https://www.npmjs.com/package/hyperapp-render):
```bash
npm install hyperapp-render --save
```
Or using a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network) like
[](https://unpkg.com/hyperapp-render) or
[](https://cdn.jsdelivr.net/npm/hyperapp-render)
with the following script tag:
```html
<script src="https://unpkg.com/hyperapp-render"></script>
```
You can find the library in `window.hyperappRender`.
We support all ES5-compliant browsers, including Internet Explorer 9 and above,
but depending on your target browsers you may need to include
[](<https://en.wikipedia.org/wiki/Polyfill_(programming)>) for
[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and
[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
before any other code.
The library provides two functions
which you can use depending on your needs or personal preferences:
```jsx
import { renderToString, renderToStream } from 'hyperapp-render'
renderToString(<Component />) // => <string>
renderToString(view(state, actions)) // => <string>
renderToString(view, state, actions) // => <string>
renderToStream(<Component />) // => <stream.Readable> => <string>
renderToStream(view(state, actions)) // => <stream.Readable> => <string>
renderToStream(view, state, actions) // => <stream.Readable> => <string>
```
**Note:** `renderToStream` is available from
[](https://nodejs.org/en/) environment only (v6 or newer).
You can use `renderToString` function to generate HTML on the server
and send the markup down on the initial request for faster page loads
and to allow search engines to crawl your pages for
[](https://en.wikipedia.org/wiki/Search_engine_optimization) purposes.
If you call [`hyperapp.app()`](https://github.com/hyperapp/hyperapp/tree/1.2.9#mounting)
on a node that already has this server-rendered markup,
Hyperapp will preserve it and only attach event handlers, allowing you
to have a very performant first-load experience.
The `renderToStream` function returns a
[](https://nodejs.org/api/stream.html#stream_readable_streams)
that outputs an HTML string.
The HTML output by this stream is exactly equal to what `renderToString` would return.
By using this function you can reduce [TTFB](https://en.wikipedia.org/wiki/Time_to_first_byte)
and improve user experience even more.
The library automatically escapes text content and attribute values
of [virtual DOM nodes](https://github.com/hyperapp/hyperapp/tree/1.2.9#view)
to protect your application against
[](https://en.wikipedia.org/wiki/Cross-site_scripting) attacks.
However, it is not safe to allow "user input" for node names or attribute keys:
```jsx
const Node = 'div onclick="alert()"'
renderToString(<Node title="XSS">Hi</Node>)
// => <div onclick="alert()" title="XSS">Hi</div>
const attributes = { 'onclick="alert()" title': 'XSS' }
renderToString(<div {...attributes}>Hi</div>)
// => <div onclick="alert()" title="XSS">Hi</div>
const userInput = '<script>alert()</script>'
renderToString(<div title="XSS" innerHTML={userInput}>Hi</div>)
// => <div title="XSS"><script>alert()</script></div>
```
Hyperapp Render is MIT licensed.
See [LICENSE](https://github.com/kriasoft/hyperapp-render/blob/master/LICENSE.md).