Deep linking
Keep the open slide in the URL hash with useLightboxHash.
useLightboxHash keeps the open slide in the URL, as #prefix-3. People can share a link to a photo, and the browser's back button closes the viewer.
It returns the same [index, setIndex] pair as useState(-1), so it drops into the quick start code:
import { Lightbox, useLightboxHash } from "liftbox";
const [index, setIndex] = useLightboxHash("photo", { count: slides.length });
<Lightbox
slides={slides}
open={index >= 0}
index={Math.max(index, 0)}
onIndexChange={setIndex}
onClose={() => setIndex(-1)}
/>;Open a photo below and watch the address bar. Then press the back button.
Live demo. Click a thumbnail to open it.
URLs
| URL | State |
|---|---|
/photos#photo-3 | Open on the third slide. 1-based. |
/photos#photo-harbour, with names | Open on the slide named harbour |
/photos, /photos#contact, /photos#photo-99 | Closed |
History
- Opening adds one history entry. Changing slide replaces it, so history does not fill up.
- Closing goes back to the entry that was there before, which restores the previous URL, hash and scroll position. Back closes the viewer and forward opens it again.
- When the page was loaded with the hash, because someone followed a shared link, closing removes the hash in place instead of leaving the page.
- The state is read from the URL, so the URL and the lightbox cannot drift apart or loop.
- Hashes that do not match the prefix, query strings and paths are never touched.
Options
| Option | Description |
|---|---|
count | Number of slides. Hashes past it read as closed instead of an empty slide. |
names | One unique name per slide, in order. The URL shows the name instead of the number. Sets count for you. |
Use a different prefix for each gallery on a page.
Named slides
A number changes when you reorder or filter the photos, so a link shared last month can open the wrong one. Pass names to put a stable name in the URL instead:
const [index, setIndex] = useLightboxHash("photo", {
names: photos.map((photo) => photo.slug),
});The third slide then lives at #photo-harbour rather than #photo-3. Names are encoded with encodeURIComponent, so spaces and accents are fine, but short slugs make nicer links. Numbered links still open, which keeps links shared before you added names working.
A shared link previews with your page's Open Graph image, not the photo, because sites that build link previews ignore everything after #. To preview the photo itself, give each one a real URL with its own og:image, such as /photos/harbour, and return it from share.url.
Server rendering
On the server and during hydration the hook reads -1. A gallery opened from a shared link opens right after hydration.