Tutorials

How to Open a Retool Modal Without a Button

OTC Team··5 min read
How to Open a Retool Modal Without a Button

If you've ever needed to open a Retool modal without a button, you've probably run into the same frustrating workaround: drop a modal component on the canvas, hide the button, and trigger it indirectly. It works, but it leaves your workspace littered with invisible components that are hard to manage and even harder to explain to a teammate. This guide covers the cleanest approaches available today and how to structure your app so modals fire exactly when you need them — not when a user clicks a dedicated button.

Why Retool Developers Want to Trigger Modals Without a Button

The most common use case is action-based apps where the modal should open as a consequence of something the user already did — selecting a row in a table, submitting a form, or completing a query. In these flows, a separate modal button is redundant. The user shouldn't need to click twice. You want the modal to appear automatically after a specific event or after a query returns data.

A second common scenario, raised repeatedly in the Retool community, involves query chaining for data readiness. If you open a modal at the same time you fire a query, the modal renders before the data is ready — giving users a blank or broken popup. The correct pattern is to fire the query first, then open the modal in the query's onSuccess handler. But that requires triggering the modal from a query, not a button.

The Current Retool Limitation

As of now, Retool requires a Modal component to exist on the canvas in order to display a modal. There is no way to instantiate a modal purely from JavaScript or an event handler without first placing the component. The button that comes bundled with the modal component is the default trigger — but it does not have to be the only trigger, and it does not have to be visible.

This is a known limitation and a long-standing feature request in the Retool community. The ideal solution — creating a modal entirely from an event handler with no canvas component required — is not yet supported. What follows are the best patterns to work around this cleanly.

How to Open a Retool Modal from an Event Handler

The cleanest supported approach is to hide the modal's default button and call modal1.open() from any event handler elsewhere in your app. Here's how to set it up step by step:

  • Step 1: Add a Modal component to your canvas. Retool will place the modal along with its default trigger button.
  • Step 2: Select the modal's button, open its properties panel, and set Hidden to true. The button disappears from the canvas but the modal component remains available.
  • Step 3: Go to the component or query you actually want to trigger the modal. Open its event handlers.
  • Step 4: Add an event handler (e.g. onClick for a table row, onSuccess for a query). Choose the action type Control Component, select your modal, and set the method to Open Modal.
  • Step 5: Test the flow. The modal will now open in response to that event, with no visible button required.

You can also trigger this via a JavaScript query using modal1.open() inline. This is useful when the trigger logic is conditional or needs to happen mid-query chain.

How to Chain a Query and a Modal (The Right Way)

If you need to display query results inside a modal, sequence matters. Here's the pattern that prevents the modal from opening before the data is ready:

  • Step 1: Create your data-fetching query — for example, getRecordDetails.
  • Step 2: In the query's Event Handlers, add an onSuccess handler.
  • Step 3: Set the action to Control Component → Open Modal, targeting your modal component.
  • Step 4: Inside the modal, reference the query's result using {{ getRecordDetails.data }} as you normally would.
  • Step 5: Trigger getRecordDetails from whatever user action starts the flow — a button click, a table row selection, or another query's success handler.

This guarantees the modal only opens after the query has completed successfully, so users never see a blank or loading popup.

Triggering Modals from Table Row Clicks

Another popular pattern is opening a modal when a user clicks a row in a Table component. To do this, go to your table's event handlers, add an onRowClick handler, and set it to open your modal. You can then populate the modal's contents using {{ table1.selectedRow.data }} to display row-specific details. No dedicated modal button needed anywhere in the UI.

Keeping Your Canvas Clean

Even with hidden buttons, a canvas full of modal components can get messy. A few practices help:

  • Name every modal descriptively — confirmDeleteModal, editRecordModal — so event handler references are self-documenting.
  • Group modal components together in a dedicated area of the canvas (e.g. the bottom) so they're easy to find and don't visually interfere with the working UI.
  • Leave a short comment in the modal's description field explaining what triggers it, since the trigger is no longer visually obvious.

What's Still Missing and What to Do About It

The ability to create and open a modal entirely from an event handler — without placing any component on the canvas — remains an open feature request. If this workflow matters to your team, the most effective action is to upvote or comment on the relevant thread in the Retool community forum. Feature prioritization at Retool is influenced by community demand, and the more concrete use cases that are documented there, the faster these gaps tend to close.

In the meantime, the hidden-button pattern combined with onSuccess query chaining covers the vast majority of real-world use cases — and once it's set up correctly, it's a reliable, maintainable pattern that scales well across complex Retool apps.

Ready to build?

We scope, design, and ship your Retool app — fast.

Ready to ship your first tool?