Viewer.js Product Image Viewer — Free JS Snippet

Viewer.js Product Image Viewer with Toolbar · Media · Plain HTML, CSS & JS · Live preview

What's included

Features

Complete toolbar: zoom, one-to-one, reset, rotate, flip, play and navigation
Full-resolution images loaded from data-original only when opened
Thumbnail navbar and keyboard shortcuts for every action
Toolbar buttons individually shown, hidden or resized
Title callback reporting each image's natural pixel size
viewed callback keeps the page hero and active thumbnail in sync
view(index) API lets any element open the viewer at the right slide
Looping navigation and smooth transitions

About this UI Snippet

Viewer.js Product Image Viewer — HTML, CSS & JavaScript

Screenshot of the Viewer.js Product Image Viewer with Toolbar snippet rendered live

Product pages need more than a lightbox. A shopper deciding whether a bag has good stitching wants to zoom to 100%, pan around, rotate the object and flip back and forth between angles — the tools of an image inspector, not a slideshow. Viewer.js is built for that. Where most lightboxes give you next, previous and close, Viewer.js ships a full toolbar: zoom in and out, one-to-one pixel view, reset, rotate left and right, flip horizontal and vertical, play as a slideshow, plus a navbar of thumbnails and keyboard shortcuts for all of it.

The setup mirrors how a product page is structured. A container element holds thumbnail images, and new Viewer(container, options) indexes them. The performance-minded option is url: 'data-original'. By default the viewer would display the thumbnail's own src, which is small and blurry when zoomed; pointing url at an attribute lets each thumbnail name its full-resolution file, which is fetched only when the viewer is opened. A page with four 240-pixel thumbnails therefore stays light, and the 1800-pixel originals cost nothing until a shopper looks closely.

The toolbar option shows how granular the control is. Each button is set to 1 or 0 — or an object like { show: 1, size: 'large' } to change its size — so a simple product viewer can hide flip and slideshow buttons while a design tool keeps them. The title option takes a function that receives the image element and its data, which is how the caption includes the true natural pixel size of the file being shown: a useful confidence signal that the zoomed image really is high resolution.

The page also keeps its own hero image in sync. The viewed callback fires each time a slide finishes showing, and the snippet uses it to highlight the active thumbnail and update the hero, so closing the viewer leaves the page showing the last angle looked at. Clicking the hero or the Inspect button opens the viewer at that same index with viewer.view(index). Thumbnails and originals are generated on canvases so the snippet is self-contained.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to add a 360-degree spin using a frame sequence, download and share buttons in the toolbar, or a magnifier lens on hover.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a product image inspector with Viewer.js 1.11 loaded from a CDN (script and CSS).

Requirements:
- Create a list of four thumbnail images, each with a data-original attribute pointing to a large image, and construct new Viewer(container, { url: 'data-original', ... }).
- Configure the toolbar with zoomIn, zoomOut, oneToOne, reset, prev, play, next, rotateLeft, rotateRight, flipHorizontal and flipVertical, plus navbar, keyboard, loop and transition.
- Use a title function that shows the image alt text and its natural width and height.
- Use the viewed callback to highlight the active thumbnail and update a hero image on the page.
- Open the viewer at the current index with viewer.view(index) from the hero image and an Inspect button.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="vw-wrap">
  <div class="vw-main">
    <img id="vwHero" alt="" class="vw-hero">
    <button type="button" class="vw-open" id="vwOpen"><span aria-hidden="true">&#x1F50D;</span> Inspect</button>
  </div>
  <div class="vw-info">
    <p class="vw-brand">Northway</p>
    <h3>Trail Pack 28L</h3>
    <p class="vw-desc">A weatherproof daypack. Open the inspector to zoom into stitching, rotate the pack or compare angles.</p>
    <ul class="vw-thumbs" id="vwThumbs"></ul>
    <p class="vw-tip">Keys inside the viewer: <kbd>&larr;</kbd><kbd>&rarr;</kbd> switch, <kbd>+</kbd><kbd>&minus;</kbd> zoom, <kbd>0</kbd> reset, <kbd>Esc</kbd> close.</p>
  </div>
</div>

Step by step

How to Use

  1. 1
    Open the inspectorClick the main image or the Inspect button. The viewer opens with a toolbar and a thumbnail strip.
  2. 2
    Zoom and panUse the + and − buttons, the mouse wheel or 0 to reset, then drag the image to look around.
  3. 3
    Rotate and flipUse the rotate and flip buttons to view the product from a different orientation.
  4. 4
    Switch anglesClick a thumbnail in the navbar or use the arrow keys. The title shows the true pixel size of each image.
  5. 5
    Close and comparePress Escape. The page hero and highlighted thumbnail show the last angle you viewed.

Real-world uses

Common Use Cases

SHOP
Product detail pages
Let shoppers inspect detail and texture. For pinch-and-pan on large diagrams see the Panzoom floor plan.
Photography and design review
Compare angles and inspect pixels with one-to-one zoom.
ADMIN
Image moderation and QA
Rotate and zoom user-submitted images to check them quickly.
Learning lazy full-size loading
A concrete use of data-original to defer heavy assets.

Got questions?

Frequently Asked Questions

Set the url option to an attribute name such as "data-original" and put the full-size file URL in that attribute on each thumbnail.

Pass a toolbar object with each button set to 1 (show) or 0 (hide), or an object like { show: 1, size: "large" }.

Call viewer.view(index) from your handler, using the instance you created.

Use the title option with a function receiving (image, imageData) and returning a string, as this snippet does to show the natural size.

Arrow keys switch images, + and − zoom, 0 resets or toggles the one-to-one view, and Escape closes the viewer.

Yes. Pass inline: true and give it a container to show the viewer embedded in the page.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from Viewer.js, so in a framework project install it with npm install viewerjs instead of the CDN tag, create it in useEffect / onMounted / ngAfterViewInit on the image container, and release it with destroy() when the component unmounts.