Tutorials

How to Build a Retool Image Gallery Component

OTC Team··4 min read

If you've gone looking for a native Retool image gallery component, you already know it doesn't exist — at least not out of the box. Whether you're building a customer support tool where agents need to browse product images, or an internal CMS where teams review uploaded photos, you'll need to wire this together yourself. The good news: it's very doable, and this guide walks you through exactly how.

What You're Actually Trying to Build

Most people searching for a Retool image gallery want the same core feature set:

  • A grid of image thumbnails — typically 3–4 per row
  • Clicking a thumbnail opens a larger view in a modal or lightbox
  • Optionally, left/right arrow navigation to cycle through images while the modal is open
  • Support for multiple galleries grouped by category or entity

None of Retool's built-in components do all of this natively. But combining a Custom Component with a Modal gets you 90% of the way there with clean UX.

Approach 1: Custom Component + Retool Modal (Recommended)

This is the most flexible approach and the one that produces the best result. Here's how it works at a high level: your Custom Component renders the image grid using a library like material-ui GridList or CSS Grid, and a Retool-native Modal component handles the lightbox. Keeping the modal outside the iframe is critical — if you open a modal inside the Custom Component, it renders within the iframe boundaries, not full-screen.

Step-by-Step: Building the Image Grid

  • Step 1 — Set up your Custom Component. In your Retool app, drag in a Custom Component. This will render your thumbnail grid inside an iframe using HTML, CSS, and JavaScript you control directly.
  • Step 2 — Pass image data as a model prop. Use the Custom Component's model to pass in your image array from a query — something like {{ getProductImages.data }}. Each image object should include a URL and any metadata you want to display.
  • Step 3 — Render the grid in your component code. Inside the component, use CSS Grid or a library like material-ui GridList to render thumbnails. A simple CSS approach: display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;. This gives you a clean 4-column layout.
  • Step 4 — Wire up click events to trigger a Retool Modal. When a user clicks a thumbnail, use Retool.modelUpdate() to push the selected image URL (and index) back to Retool. Then set a JS query to fire on model change and call openModal1() — or whatever your modal is named.
  • Step 5 — Configure the Retool Modal. Inside the modal, use an Image component bound to the selected image URL stored in state or a variable. Add left/right Button components that run a JS query to increment or decrement the selected image index.
  • Step 6 — Handle navigation logic. Write a small JS query that updates the current image index, clamped to the array length. Something like: const next = (currentIndex + 1) % images.length; — then update your state variable and the image component rerenders automatically.

Approach 2: ListView Component (Simpler, Less Flexible)

If you want to avoid a Custom Component entirely, Retool's ListView can work as a lightweight alternative. You can render one image per row with a click handler that opens a modal. The limitation: ListView is inherently vertical, so you lose the grid layout. You can simulate columns by placing multiple ListView components side by side — one per column — but nesting a ListView inside another ListView row gets messy fast and is hard to maintain. Use this approach only if your image count is small and layout precision doesn't matter.

What About a Carousel Instead?

If a full image gallery grid is more than you need and a sequential image viewer would do the job, a Retool image carousel is a simpler build. The community has documented a working carousel pattern using a Custom Component with a lightweight carousel library. The same modal + index navigation logic described above applies — you're just changing the UI chrome around it. Check the Retool community thread on image carousel components for a full walkthrough.

Known Limitations to Plan Around

  • Retool does not have a native image gallery or carousel component as of this writing — always check the original feature request thread for updates.
  • Modals opened inside a Custom Component iframe are scoped to the iframe — they won't go full-screen. Always open modals at the Retool app level.
  • Passing large base64-encoded images through the model prop can cause performance issues. Pass URLs and load images directly in the browser instead.
  • If you need multiple galleries (e.g., one per product category), render multiple Custom Component instances bound to filtered query data rather than trying to nest ListView components.

When Retool Ships a Native Solution

Retool's team has acknowledged this gap and indicated they're tracking it. Until a native image gallery or grid component ships, the Custom Component approach above is your most production-ready option. It's not zero effort, but it's a one-time build you can turn into a reusable module across apps. If your team is building internal tools where image review is a core workflow — think customer support, QA, asset management — the investment is worth it.

Ready to build?

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

Ready to ship your first tool?