{"id":13475286,"url":"https://github.com/choojs/nanohtml","last_synced_at":"2025-03-26T23:30:41.648Z","repository":{"id":4291834,"uuid":"52651469","full_name":"choojs/nanohtml","owner":"choojs","description":":dragon: HTML template strings for the Browser with support for Server Side Rendering in Node.","archived":false,"fork":false,"pushed_at":"2022-10-12T07:02:48.000Z","size":261,"stargazers_count":687,"open_issues_count":27,"forks_count":49,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-10-30T08:51:33.627Z","etag":null,"topics":["dom","element","frontend"],"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/choojs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-27T05:18:55.000Z","updated_at":"2024-09-25T08:39:48.000Z","dependencies_parsed_at":"2022-08-06T16:00:48.028Z","dependency_job_id":null,"html_url":"https://github.com/choojs/nanohtml","commit_stats":null,"previous_names":["shama/bel"],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/choojs%2Fnanohtml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/choojs%2Fnanohtml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/choojs%2Fnanohtml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/choojs%2Fnanohtml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/choojs","download_url":"https://codeload.github.com/choojs/nanohtml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245753835,"owners_count":20666822,"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":["dom","element","frontend"],"created_at":"2024-07-31T16:01:19.061Z","updated_at":"2025-03-26T23:30:41.256Z","avatar_url":"https://github.com/choojs.png","language":"JavaScript","readme":"# nanohtml\n[![npm version][2]][3] [![build status][4]][5]\n[![downloads][8]][9] [![js-standard-style][10]][11]\n\nHTML template strings for the Browser with support for Server Side\nRendering in Node.\n\n## Installation\n```sh\n$ npm install nanohtml\n```\n\n## Usage\n### Browser\n```js\nvar html = require('nanohtml')\n\nvar el = html`\n  \u003cbody\u003e\n    \u003ch1\u003eHello planet\u003c/h1\u003e\n  \u003c/body\u003e\n`\n\ndocument.body.appendChild(el)\n```\n\n### Node\nNode doesn't have a DOM available. So in order to render HTML we use string\nconcatenation instead. This has the fun benefit of being quite efficient, which\nin turn means it's great for server rendering!\n\n```js\nvar html = require('nanohtml')\n\nvar el = html`\n  \u003cbody\u003e\n    \u003ch1\u003eHello planet\u003c/h1\u003e\n  \u003c/body\u003e\n`\n\nconsole.log(el.toString())\n```\n\n### Node with custom DOM\nModules like [`jsdom`](https://github.com/jsdom/jsdom) implement (parts of)\nthe DOM in pure JavaScript. If you don't really need the performance of\nstring concatenation, or use nanohtml components that modify the raw DOM, use\n`nanohtml/dom` to give nanohtml a custom Document.\n\n```js\nvar JSDOM = require('jsdom').JSDOM\nvar nanohtml = require('nanohtml/dom')\nvar jsdom = new JSDOM()\n\nvar html = nanohtml(jsdom.window.document)\nvar el = html`\n  \u003cbody\u003e\n    \u003ch1\u003eHello planet\u003c/h1\u003e\n  \u003c/body\u003e\n`\nel.appendChild(html`\u003cp\u003eA paragraph\u003c/p\u003e`)\n\nel.outerHTML === '\u003cbody\u003e\u003ch1\u003eHello planet\u003c/h1\u003e\u003cp\u003eA paragraph\u003c/p\u003e\u003c/body\u003e'\n```\n\n### Interpolating unescaped HTML\nBy default all content inside template strings is escaped. This is great for\nstrings, but not ideal if you want to insert HTML that's been returned from\nanother function (for example: a markdown renderer). Use `nanohtml/raw` for\nto interpolate HTML directly.\n\n```js\nvar raw = require('nanohtml/raw')\nvar html = require('nanohtml')\n\nvar string = '\u003ch1\u003eThis a regular string.\u003c/h1\u003e'\nvar el = html`\n  \u003cbody\u003e\n    ${raw(string)}\n  \u003c/body\u003e\n`\n\ndocument.body.appendChild(el)\n```\n\n### Attaching event listeners\n```js\nvar html = require('nanohtml')\n\nvar el = html`\n  \u003cbody\u003e\n    \u003cbutton onclick=${onclick}\u003e\n      Click Me\n    \u003c/button\u003e\n  \u003c/body\u003e\n`\n\ndocument.body.appendChild(el)\n\nfunction onclick (e) {\n  console.log(`${e.target} was clicked`)\n}\n```\n\n### Multiple root elements\n\nIf you have more than one root element they will be combined with a [DocumentFragment](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment).\n\n```js\nvar html = require('nanohtml')\n\nvar el = html`\n  \u003cli\u003eChashu\u003c/li\u003e\n  \u003cli\u003eNori\u003c/li\u003e\n`\n\ndocument.querySelector('ul').appendChild(el)\n```\n\n### Conditional attributes\n\nUse a javascript object to conditionally add HTML attributes.\n\n```js\nvar html = require('nanohtml')\n\nvar customAttr = isFuzzy ? { 'data-hand-feel': 'super-fuzzy' } : {}\nvar el = html`\n  \u003cdiv ${ customAttr }\u003e\u003c/div\u003e\n`\n```\n\n## Static optimizations\nParsing HTML has significant overhead. Being able to parse HTML statically,\nahead of time can speed up rendering to be about twice as fast.\n\n### Browserify\n\n#### From the command line\n```sh\n$ browserify -t nanohtml index.js \u003e bundle.js\n```\n\n#### Programmatically\n```js\nvar browserify = require('browserify')\nvar nanohtml = require('nanohtml')\nvar path = require('path')\n\nvar b = browserify(path.join(__dirname, 'index.js'))\n  .transform(nanohtml)\n\nb.bundle().pipe(process.stdout)\n```\n\n#### In package.json\n```json\n{\n  \"name\": \"my-app\",\n  \"private\": true,\n  \"browserify\": {\n    \"transform\": [\n      \"nanohtml\"\n    ]\n  },\n  \"dependencies\": {\n    \"nanohtml\": \"^1.0.0\"\n  }\n}\n```\n\n## Bundling\n\n### Webpack\nAt the time of writing there's no Webpack loader yet. We'd love a contribution!\n\n### Babel / Parcel\n\nAdd nanohtml to your `.babelrc` config.\n\nWithout options:\n\n```js\n{\n  \"plugins\": [\n    \"nanohtml\"\n  ]\n}\n```\n\nWith options:\n\n```js\n{\n  \"plugins\": [\n    [\"nanohtml\", {\n      \"useImport\": true\n    }]\n  ]\n}\n```\n\n#### Options\n\n - `useImport` - Set to true to use `import` statements for injected modules.\n    By default, `require` is used.\n - `appendChildModule` - Import path to a module that contains an `appendChild`\n    function. Defaults to `\"nanohtml/lib/append-child\"`.\n\n### Rollup\n\nUse the [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/master/packages/commonjs#using-with-rollupplugin-node-resolve) plugin with [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve). Explicitly import the browser or server entrypoint in your application. E.g.:\n\n```\nimport html from 'nanohtml/lib/browser';\n```\n\n## Attributions\nShout out to [Shama](https://github.com/shama) and\n[Shuhei](https://github.com/shuhei) for their contributions to\n[Bel](https://github.com/shama/bel),\n[yo-yoify](https://github.com/shama/yo-yoify) and\n[pelo](https://github.com/shuhei/pelo). This module is based on their work, and\nwouldn't have been possible otherwise!\n\n## See Also\n- [choojs/nanomorph](https://github.com/choojs/nanomorph)\n\n## License\n[MIT](./LICENSE)\n\n[0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square\n[1]: https://nodejs.org/api/documentation.html#documentation_stability_index\n[2]: https://img.shields.io/npm/v/nanohtml.svg?style=flat-square\n[3]: https://npmjs.org/package/nanohtml\n[4]: https://img.shields.io/travis/choojs/nanohtml/master.svg?style=flat-square\n[5]: https://travis-ci.org/choojs/nanohtml\n[6]: https://img.shields.io/codecov/c/github/choojs/nanohtml/master.svg?style=flat-square\n[7]: https://codecov.io/github/choojs/nanohtml\n[8]: http://img.shields.io/npm/dt/nanohtml.svg?style=flat-square\n[9]: https://npmjs.org/package/nanohtml\n[10]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square\n[11]: https://github.com/feross/standard\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchoojs%2Fnanohtml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchoojs%2Fnanohtml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchoojs%2Fnanohtml/lists"}