Opening and Closing Dialogs Without JavaScript Using HTML Invoker Commands

Learn how to use HTML invoker commands to open and close dialogs without writing any JavaScript.

The native <dialog> element was a huge step forward for web developers. It gave us a standardized way to create modal dialogs with built-in backdrop handling, focus management, and keyboard interactions—no more reinventing the wheel with div containers and mountains of JavaScript.

But we still needed JavaScript for one fundamental task: opening the dialog.

The HTML Invoker Commands API changes that. Now you can create fully functional dialogs with just HTML.

The Traditional Approach

Here’s what we typically had to write:

<pre class="astro-code dracula" style="background-color:#282A36;color:#F8F8F2; overflow-x: auto;" tabindex="0" data-language="html"><code><span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#FF79C6">button</span><span style="color:#50FA7B;font-style:italic"> type</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">button</span><span style="color:#E9F284">"</span><span style="color:#50FA7B;font-style:italic"> id</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">openBtn</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">>Open Dialog&#x3C;/</span><span style="color:#FF79C6">button</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#FF79C6">dialog</span><span style="color:#50FA7B;font-style:italic"> id</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#FF79C6">form</span><span style="color:#50FA7B;font-style:italic"> method</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#FF79C6">button</span><span style="color:#50FA7B;font-style:italic"> type</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">submit</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">>Close Dialog&#x3C;/</span><span style="color:#FF79C6">button</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;/</span><span style="color:#FF79C6">form</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#6272A4"> &#x3C;!-- dialog content --></span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;/</span><span style="color:#FF79C6">dialog</span><span style="color:#F8F8F2">></span></span> <span class="line"></span> <span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#FF79C6">script</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#FF79C6"> const</span><span style="color:#F8F8F2"> dialog </span><span style="color:#FF79C6">=</span><span style="color:#F8F8F2"> document.</span><span style="color:#50FA7B">getElementById</span><span style="color:#F8F8F2">(</span><span style="color:#E9F284">'</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">'</span><span style="color:#F8F8F2">);</span></span> <span class="line"><span style="color:#FF79C6"> const</span><span style="color:#F8F8F2"> openBtn </span><span style="color:#FF79C6">=</span><span style="color:#F8F8F2"> document.</span><span style="color:#50FA7B">getElementById</span><span style="color:#F8F8F2">(</span><span style="color:#E9F284">'</span><span style="color:#F1FA8C">openBtn</span><span style="color:#E9F284">'</span><span style="color:#F8F8F2">);</span></span> <span class="line"><span style="color:#F8F8F2"> </span></span> <span class="line"><span style="color:#F8F8F2"> openBtn.</span><span style="color:#50FA7B">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E9F284">'</span><span style="color:#F1FA8C">click</span><span style="color:#E9F284">'</span><span style="color:#F8F8F2">, () </span><span style="color:#FF79C6">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F8F8F2"> dialog.</span><span style="color:#50FA7B">showModal</span><span style="color:#F8F8F2">();</span></span> <span class="line"><span style="color:#F8F8F2"> });</span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;/</span><span style="color:#FF79C6">script</span><span style="color:#F8F8F2">></span></span></code></pre>

You could close the dialog without JavaScript using <form method="dialog">, but you still needed JavaScript to open it.

The Invoker Commands Approach

With Invoker Commands, you add two attributes to your button:

<pre class="astro-code dracula" style="background-color:#282A36;color:#F8F8F2; overflow-x: auto;" tabindex="0" data-language="html"><code><span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#FF79C6">button</span><span style="color:#50FA7B;font-style:italic"> commandFor</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">"</span><span style="color:#50FA7B;font-style:italic"> command</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">show-modal</span><span style="color:#E9F284">"</span><span style="color:#50FA7B;font-style:italic"> type</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">button</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> Open Dialog</span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;/</span><span style="color:#FF79C6">button</span><span style="color:#F8F8F2">></span></span> <span class="line"></span> <span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#FF79C6">dialog</span><span style="color:#50FA7B;font-style:italic"> id</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#FF79C6">button</span><span style="color:#50FA7B;font-style:italic"> commandFor</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">dialog</span><span style="color:#E9F284">"</span><span style="color:#50FA7B;font-style:italic"> command</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">close</span><span style="color:#E9F284">"</span><span style="color:#50FA7B;font-style:italic"> type</span><span style="color:#FF79C6">=</span><span style="color:#E9F284">"</span><span style="color:#F1FA8C">button</span><span style="color:#E9F284">"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> Close Dialog</span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;/</span><span style="color:#FF79C6">button</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#6272A4"> &#x3C;!-- dialog content --></span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;/</span><span style="color:#FF79C6">dialog</span><span style="color:#F8F8F2">></span></span></code></pre>

That’s it. No JavaScript required.

How It Works

The two key attributes are:

For dialogs, you have two command options:

What You Get for Free

When you use command="show-modal", the browser handles:

Browser Support

Invoker Commands are now supported across all modern browsers. This is still a rather new addition to the platform so, you will have to determine whether it is safe to use in your production environment. With that said, there is also a polyfill available by Keith Cirkel.

NOTE: The Invoker Commands API is supported by all modern browsers. See the browser compatibility table on MDN Web Docs for details.

Why This Matters

Invoker Commands represent a broader shift: giving HTML the power to handle common interactive patterns without requiring JavaScript. This means:

The web platform keeps getting better at being the web platform.