Hello World

ID: 2271https://elysiajs.com/plugins/html.md
Source

HTML Plugin

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

Install with:

bun add @elysiajs/html

Then use it:

import React from 'react'
// ---cut---
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:

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

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

import React from 'react'
// ---cut---
import { Elysia } from 'elysia'
import { html, Html } from '@elysiajs/html' // [!code ++]

new Elysia()
	.use(html()) // [!code ++]
	.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:

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.

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:

bun add @kitajs/ts-html-plugin

Then appends the following tsconfig.json

// 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

// 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.