Skip to content

HTML Plugin

Allows you to use JSX and HTML with proper headers and support.

Install with:

bash
bun add @elysiajs/html

Then use it:

tsx
import { 
Elysia
} from 'elysia'
import {
html
,
Html
} from '@elysiajs/html'
new
Elysia
()
.
use
(
html
())
.
get
(
'/html', () => ` <html lang='en'> <head> <title>Hello World</title> </head> <body> <h1>Hello World</h1> </body> </html>` ) .
get
('/jsx', () => (
<
html
lang
="en">
<
head
>
<
title
>Hello World</
title
>
</
head
>
<
body
>
<
h1
>Hello World</
h1
>
</
body
>
</
html
>
)) .
listen
(3000)

This plugin will automatically add Content-Type: text/html; charset=utf8 header to the response, add <!doctype html>, and convert it into a Response object.

JSX

Elysia HTML is based on @kitajs/html allowing us to define JSX to string in compile time to achieve high performance.

Name your file that needs to use JSX to end with affix "x":

  • .js -> .jsx
  • .ts -> .tsx

To register the TypeScript type, please append the following to tsconfig.json:

jsonc
// tsconfig.json
{
	"compilerOptions": {
		"jsx": "react",
		"jsxFactory": "Html.createElement",
		"jsxFragmentFactory": "Html.Fragment"
	}
}

That's it, now you can use JSX as your template engine:

tsx
import { 
Elysia
} from 'elysia'
import {
html
,
Html
} from '@elysiajs/html'
new
Elysia
()
.
use
(
html
())
.
get
('/', () => (
<
html
lang
="en">
<
head
>
<
title
>Hello World</
title
>
</
head
>
<
body
>
<
h1
>Hello World</
h1
>
</
body
>
</
html
>
)) .
listen
(3000)

If the error Cannot find name 'Html'. Did you mean 'html'? occurs, this import must be added to the JSX template:

tsx
import { Html } from '@elysiajs/html'

It is important that it is written in uppercase.

XSS

Elysia HTML is based use of the Kita HTML plugin to detect possible XSS attacks in compile time.

You can use a dedicated safe attribute to sanitize user value to prevent XSS vulnerability.

tsx
import { Elysia, t } from 'elysia'
import { html, Html } from '@elysiajs/html'

new Elysia()
	.use(html())
	.post(
		'/',
		({ body }) => (
			<html lang="en">
				<head>
					<title>Hello World</title>
				</head>
				<body>
					<h1 safe>{body}</h1>
				</body>
			</html>
		),
		{
			body: t.String()
		}
	)
	.listen(3000)

However, when are building a large-scale app, it's best to have a type reminder to detect possible XSS vulnerabilities in your codebase.

To add a type-safe reminder, please install:

sh
bun add @kitajs/ts-html-plugin

Then appends the following tsconfig.json

jsonc
// tsconfig.json
{
	"compilerOptions": {
		"jsx": "react",
		"jsxFactory": "Html.createElement",
		"jsxFragmentFactory": "Html.Fragment",
		"plugins": [{ "name": "@kitajs/ts-html-plugin" }]
	}
}

Options

contentType

  • Type: string
  • Default: 'text/html; charset=utf8'

The content-type of the response.

autoDetect

  • Type: boolean
  • Default: true

Whether to automatically detect HTML content and set the content-type.

autoDoctype

  • Type: boolean | 'full'
  • Default: true

Whether to automatically add <!doctype html> to a response starting with <html>, if not found.

Use full to also automatically add doctypes on responses returned without this plugin

ts
// without the plugin
app.get('/', () => '<html></html>')

// With the plugin
app.get('/', ({ html }) => html('<html></html>'))

isHtml

  • Type: (value: string) => boolean
  • Default: isHtml (exported function)

The function is used to detect if a string is a html or not. Default implementation if length is greater than 7, starts with < and ends with >.

Keep in mind there's no real way to validate HTML, so the default implementation is a best guess.