{"id":13657682,"url":"https://github.com/kriasoft/hyperapp-render","last_synced_at":"2025-04-24T08:30:33.256Z","repository":{"id":38451559,"uuid":"117827363","full_name":"kriasoft/hyperapp-render","owner":"kriasoft","description":"Render Hyperapp to an HTML string with SSR and Node.js streaming support.","archived":false,"fork":false,"pushed_at":"2023-07-19T18:04:19.000Z","size":1170,"stargazers_count":103,"open_issues_count":2,"forks_count":15,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-30T00:55:24.479Z","etag":null,"topics":["html","hyperapp","render","server-side-rendering","ssr","stream"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kriasoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-01-17T11:29:44.000Z","updated_at":"2024-02-22T16:50:04.000Z","dependencies_parsed_at":"2023-02-08T07:46:06.435Z","dependency_job_id":null,"html_url":"https://github.com/kriasoft/hyperapp-render","commit_stats":{"total_commits":68,"total_committers":7,"mean_commits":9.714285714285714,"dds":"0.11764705882352944","last_synced_commit":"bcf6b4acd016e2366ff9e9beaf1f23eecdeb7675"},"previous_names":["hyperapp/render"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fhyperapp-render","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fhyperapp-render/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fhyperapp-render/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fhyperapp-render/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kriasoft","download_url":"https://codeload.github.com/kriasoft/hyperapp-render/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248429738,"owners_count":21101888,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","hyperapp","render","server-side-rendering","ssr","stream"],"created_at":"2024-08-02T05:00:48.287Z","updated_at":"2025-04-24T08:30:32.963Z","avatar_url":"https://github.com/kriasoft.png","language":"JavaScript","readme":"# \u003cimg height=\"24\" src=\"https://cdn.rawgit.com/kriasoft/hyperapp-render/master/logo.svg\"\u003e Hyperapp Render\n\n[![npm version](https://img.shields.io/npm/v/hyperapp-render.svg)](https://www.npmjs.com/package/hyperapp-render)\n[![npm downloads](https://img.shields.io/npm/dw/hyperapp-render.svg)](https://www.npmjs.com/package/hyperapp-render)\n[![library size](https://img.shields.io/bundlephobia/minzip/hyperapp-render.svg)](https://bundlephobia.com/result?p=hyperapp-render)\n[![discord chat](https://img.shields.io/discord/804672552348680192)](https://discord.gg/eFvZXzXF9U 'Join us')\n\nThis library is allowing you to render\n[Hyperapp](https://github.com/hyperapp/hyperapp) views to an HTML string.\n\n- **User experience** — Generate HTML on the server and send the markup\n  down on the initial request for faster page loads. Built-in\n  [mounting](https://github.com/hyperapp/hyperapp/tree/1.2.9#mounting)\n  feature in Hyperapp is allowing you to have a very performant first-load experience.\n- **Accessibility** — Allow search engines to crawl your pages for\n  [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization) purposes.\n- **Testability** — [Check HTML validity](https://en.wikipedia.org/wiki/Validator) and use\n  [snapshot testing](https://jestjs.io/docs/en/snapshot-testing.html)\n  to improve quality of your software.\n\n## Getting Started\n\nOur first example is an interactive app from which you can generate an HTML markup.\nGo ahead and [try it online](https://codepen.io/frenzzy/pen/zpmRQY/left/?editors=0010).\n\n```jsx\nimport { h } from 'hyperapp'\nimport { renderToString } from 'hyperapp-render'\n\nconst state = {\n  text: 'Hello'\n}\n\nconst actions = {\n  setText: text =\u003e ({ text })\n}\n\nconst view = (state, actions) =\u003e (\n  \u003cmain\u003e\n    \u003ch1\u003e{state.text.trim() === '' ? '👋' : state.text}\u003c/h1\u003e\n    \u003cinput value={state.text} oninput={e =\u003e actions.setText(e.target.value)} /\u003e\n  \u003c/main\u003e\n)\n\nconst html = renderToString(view(state, actions))\n\nconsole.log(html) // =\u003e \u003cmain\u003e\u003ch1\u003eHello\u003c/h1\u003e\u003cinput value=\"Hello\"/\u003e\u003c/main\u003e\n```\n\nLooking for a boilerplate?\nTry [Hyperapp Starter](https://github.com/kriasoft/hyperapp-starter)\nwith pre-configured server-side rendering and many more.\n\n## Installation\n\nUsing [npm](https://www.npmjs.com/package/hyperapp-render):\n\n```bash\nnpm install hyperapp-render --save\n```\n\nOr using a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network) like\n[unpkg.com](https://unpkg.com/hyperapp-render) or\n[jsDelivr](https://cdn.jsdelivr.net/npm/hyperapp-render)\nwith the following script tag:\n\n```html\n\u003cscript src=\"https://unpkg.com/hyperapp-render\"\u003e\u003c/script\u003e\n```\n\nYou can find the library in `window.hyperappRender`.\n\nWe support all ES5-compliant browsers, including Internet Explorer 9 and above,\nbut depending on your target browsers you may need to include\n[polyfills](\u003chttps://en.wikipedia.org/wiki/Polyfill_(programming)\u003e) for\n[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and\n[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)\nbefore any other code.\n\n## Usage\n\nThe library provides two functions\nwhich you can use depending on your needs or personal preferences:\n\n```jsx\nimport { renderToString, renderToStream } from 'hyperapp-render'\n\nrenderToString(\u003cComponent /\u003e)        // =\u003e \u003cstring\u003e\nrenderToString(view(state, actions)) // =\u003e \u003cstring\u003e\nrenderToString(view, state, actions) // =\u003e \u003cstring\u003e\n\nrenderToStream(\u003cComponent /\u003e)        // =\u003e \u003cstream.Readable\u003e =\u003e \u003cstring\u003e\nrenderToStream(view(state, actions)) // =\u003e \u003cstream.Readable\u003e =\u003e \u003cstring\u003e\nrenderToStream(view, state, actions) // =\u003e \u003cstream.Readable\u003e =\u003e \u003cstring\u003e\n```\n\n**Note:** `renderToStream` is available from\n[Node.js](https://nodejs.org/en/) environment only (v6 or newer).\n\n## Overview\n\nYou can use `renderToString` function to generate HTML on the server\nand send the markup down on the initial request for faster page loads\nand to allow search engines to crawl your pages for\n[SEO](https://en.wikipedia.org/wiki/Search_engine_optimization) purposes.\n\nIf you call [`hyperapp.app()`](https://github.com/hyperapp/hyperapp/tree/1.2.9#mounting)\non a node that already has this server-rendered markup,\nHyperapp will preserve it and only attach event handlers, allowing you\nto have a very performant first-load experience.\n\nThe `renderToStream` function returns a\n[Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams)\nthat outputs an HTML string.\nThe HTML output by this stream is exactly equal to what `renderToString` would return.\nBy using this function you can reduce [TTFB](https://en.wikipedia.org/wiki/Time_to_first_byte)\nand improve user experience even more.\n\n## Caveats\n\nThe library automatically escapes text content and attribute values\nof [virtual DOM nodes](https://github.com/hyperapp/hyperapp/tree/1.2.9#view)\nto protect your application against\n[XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) attacks.\nHowever, it is not safe to allow \"user input\" for node names or attribute keys:\n\n```jsx\nconst Node = 'div onclick=\"alert()\"'\nrenderToString(\u003cNode title=\"XSS\"\u003eHi\u003c/Node\u003e)\n// =\u003e \u003cdiv onclick=\"alert()\" title=\"XSS\"\u003eHi\u003c/div\u003e\n\nconst attributes = { 'onclick=\"alert()\" title': 'XSS' }\nrenderToString(\u003cdiv {...attributes}\u003eHi\u003c/div\u003e)\n// =\u003e \u003cdiv onclick=\"alert()\" title=\"XSS\"\u003eHi\u003c/div\u003e\n\nconst userInput = '\u003cscript\u003ealert()\u003c/script\u003e'\nrenderToString(\u003cdiv title=\"XSS\" innerHTML={userInput}\u003eHi\u003c/div\u003e)\n// =\u003e \u003cdiv title=\"XSS\"\u003e\u003cscript\u003ealert()\u003c/script\u003e\u003c/div\u003e\n```\n\n## License\n\nHyperapp Render is MIT licensed.\nSee [LICENSE](https://github.com/kriasoft/hyperapp-render/blob/master/LICENSE.md).\n","funding_links":[],"categories":["JavaScript","Packages"],"sub_categories":["SSR"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkriasoft%2Fhyperapp-render","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkriasoft%2Fhyperapp-render","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkriasoft%2Fhyperapp-render/lists"}