Skip to content

guillaumejay/pairs2web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pairs2web

Static site that displays a gallery of before / after image pairs with an interactive draggable slider. Drop folders in pairs/, push, done. Deployable as-is on Vercel or Cloudflare Pages.

Deploy with Vercel Deploy to Cloudflare

One click to clone the repo into your GitHub account and deploy it on either platform.

The deploy buttons above create a new, standalone repo on your GitHub account (not a GitHub fork — no upstream link, no "Sync fork" button). If you want to keep pulling future improvements from this repo, use the Fork button at the top of the GitHub page instead, then connect that fork to Vercel/Cloudflare manually.

How it works

  1. On every git push, the platform (Vercel or Cloudflare) spins up a Linux container
  2. The build.sh script scans the pairs/ directory, copies every image into public/pairs/, and generates a public/pairs.json manifest
  3. The public/ directory (with index.html + the JSON + the images) is served on the CDN
  4. The home page loads pairs.json and renders one interactive before/after slider per pair

No framework, no bundler, no Node, no npm install — just bash, a static HTML file, and your images.

Adding a pair

Create a sub-folder in pairs/ and drop two images named before.* and after.* (any of .jpg, .jpeg, .png, .webp, .avif, .gif):

pairs/
└── my-renovation/
    ├── before.jpg
    └── after.jpg

Push the commit. That's it — the build picks it up automatically.

Optional metadata

Add a meta.txt file in the folder to set a title, description, date, and custom labels:

title: Living room renovation
description: Repainted, refloored, and decluttered over a long weekend.
date: 2025-09-14
before_label: Before
after_label: After

All fields are optional. If title is missing, the folder name is used (de-slugified). Default labels are "Before" and "After". date is omitted from the manifest (and from the page) when not set.

Site intro (optional)

Drop a pairs/intro.html file to display an introduction block at the top of the gallery (above the first pair). Its content is embedded as-is into pairs.json and rendered as raw HTML, so you can use links, paragraphs, lists, etc.:

<p>A small selection of recent restorations and reworks.</p>
<p>Drag the slider on each image to compare. <a href="https://example.com">More on my site →</a></p>

Since the HTML is injected via innerHTML, only put content you trust there (it's your own build, so this is normally fine — just don't accept untrusted PRs that touch this file without reviewing).

Ordering

Pairs are listed in alphabetical order of folder name. The simplest convention is a numeric prefix:

pairs/
├── 01-kitchen/
├── 02-bathroom/
└── 03-garden/

Usage

1. Clone and customize

git clone <this-repo> my-gallery
cd my-gallery
# Drop your pairs in pairs/ — keep or delete the demo folders

2. Deploy on Vercel

  • Go to vercel.com/new
  • Import the repo
  • Vercel reads vercel.json automatically — nothing to configure
  • Click Deploy

3. Deploy on Cloudflare Pages

  • Go to dash.cloudflare.com → Workers & Pages → Create → Pages → Connect to Git
  • Select the repo
  • Configure:
    • Build command: bash build.sh
    • Build output directory: public
  • Click Save and Deploy

The same repo can be deployed to both platforms in parallel without conflict.

Local testing

The build script only depends on bash, sed, grep, and cp — all standard. No installation needed:

bash build.sh
python3 -m http.server -d public 8000
# Open http://localhost:8000

Or use the npm script if you prefer:

npm run build
npm run serve

Structure

.
├── pairs/              # ← drop your pairs here (this is the only thing you edit)
│   ├── intro.html      # optional site-level intro (HTML)
│   ├── 01-demo-paris/
│   │   ├── before.jpg
│   │   ├── after.jpg
│   │   └── meta.txt
│   └── 02-demo-portrait/
│       ├── before.jpg
│       ├── after.jpg
│       └── meta.txt
├── public/
│   ├── index.html      # gallery page (loads pairs.json at runtime)
│   ├── _headers        # Cloudflare cache rules
│   ├── pairs.json      # ← generated by build.sh (gitignored)
│   └── pairs/          # ← generated by build.sh (gitignored)
├── build.sh            # the whole build, in bash
├── vercel.json         # Vercel config
├── wrangler.toml       # Cloudflare config
├── package.json        # convenience scripts
└── README.md

Customization

  • Page styling: edit the <style> block in public/index.html. The CSS uses custom properties at the top (:root) for colors, fonts, and spacing — tweak those first.
  • Slider behavior: the JS at the bottom of index.html is ~120 lines of vanilla JS, no dependencies. Easy to fork.
  • Site title and brand: change the <title> and the <h1 class="brand"> in public/index.html.
  • Default labels: change the defaults in build.sh (search for before_label="Before").

Image tips

  • Both images of a pair should have the same aspect ratio — the slider crops them to match the natural size of the before image.
  • Keep image dimensions reasonable: 1600–2400px on the long edge is plenty for the web.
  • The build doesn't re-encode or resize images — what you commit is what gets served. Optimize beforehand if needed (e.g. with Squoosh or cwebp).

Caching

The build output ships with cache headers configured for both platforms (vercel.json for Vercel, public/_headers for Cloudflare):

  • pairs/** (the actual images): max-age=31536000, immutable — they're served from the CDN forever
  • pairs.json: max-age=0, must-revalidate — always check for the latest manifest

This means new pairs appear immediately after a deploy, without waiting for cache TTLs.

Why no Node / framework?

The whole point is to stay close to typst2web in spirit: a single bash script, no node_modules, no framework lock-in, easy to read end-to-end in 10 minutes. If you need a richer site (pagination, filters, tags, search), it's still a good starting point — fork it and add what you need.

License

MIT.

About

Static site template that displays before/after image pairs as interactive sliders — drop folders in pairs/ and deploy in one click on Vercel or Cloudflare Pages.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors