io.display.html

Your own HTML, sanitized first.

io.display.html shows HTML markup in a page or in a step of an action. It is made for things like a preview of an email before it goes out. Scripts, event handlers and other active content are removed before it is shown. It only displays and returns nothing.

The simplest one

The whole action file, and roughly what your team sees when it runs.

src/actions/emails/previewEmailAction.ts
import { app } from '../../app';
import { renderTrialEndingEmail } from '../../emails';
export const previewEmailAction = app.defineAction({
name: 'Preview email',
handler: async ({ io }) => {
const email = await renderTrialEndingEmail();
await io.display.html('Email preview', {
html: email.html,
});
},
});
The code. One call in an action, the whole file.
tools.example.com/actions/emails/preview_email

Preview email

Email preview
Your trial ends soonHi Ana,the trial of Northwind ends on Nov 3, 2026. Pick a plan to keep your store open.Choose a plan
Continue
In the browser. Roughly what your team sees. Your theme decides the details.

What you can set

The settings you will reach for most, each with the line of code that turns it on.

html: email.html

The email as it goes out. Pass the HTML your email template renders. The person sees it before anyone gets it.

'<img src=x onerror=alert(1)>'

Active content removed. Scripts, event handlers such as onerror and javascript: links are removed. The markup can carry data from users.

'<h2>Trial ends</h2><p>Hi</p>'

Styled like markdown. What stays gets the same text styles as io.display.markdown. It looks like the rest of the app.

io.display.html(null, { html })

A heading or none. The label is the heading above the markup. Pass null to show the markup alone.

preview: io.display.html(null, { html }),

Next to a question. In io.group it sits next to inputs, such as the email right above the question whether to send it.

io.display.markdown('Hi **Ana**')

Markdown for your own text. HTML is for markup you already have. For text you write yourself, io.display.markdown is usually simpler.

Write your first tool today.

An async function, a few await calls, and the form is in the browser.

AwaitIO is free for small teams, made possible by companies and people who sponsor it.