Skip to content

Add The Archives portfolio page, and make the portfolio findable in image search - #28

Open
qafears wants to merge 2 commits into
mainfrom
claude/wix-images-google-search-ra28nj
Open

Add The Archives portfolio page, and make the portfolio findable in image search#28
qafears wants to merge 2 commits into
mainfrom
claude/wix-images-google-search-ra28nj

Conversation

@qafears

@qafears qafears commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Two related changes: a new portfolio page, and the search-visibility fixes that make its photos findable.

The Archives (/archives)

A dedicated portfolio page with four sections: Celebrity, Editorial, Commercial, Red carpet. Content is a new archives singleton (content/archives.yaml), editable from the Keystatic admin.

Curated to 5 to 10 photos per section, picked for name recognition first and dynamism second:

Section Count Includes
Celebrity 8 Glamour digital-edition cover, Norman Reedus, the printed ball gown, the feather gowns, three menswear looks
Editorial 10 Drawn from both the editorial and menswear editorial sets
Commercial 6 Swim campaign, evening wear, accessories
Red carpet 0 Defined but empty, see below

Duplicate frames were excluded using the crop mapping recorded in docs/gallery-restructure.md.

Red carpet is deliberately empty. The repo holds no red-carpet photography. A section with no images is skipped entirely, so the page shows three sections today and picks up the fourth the moment its photos land, with no empty grid in the meantime.

Implementation notes:

  • Every photo is a real <img> on the page rather than a JSON blob the lightbox expands. That is the point of the page, and it is also the only reliable way image search sees the portfolio.
  • The lightbox is reused unchanged. Each section is emitted as a one-shoot category, which main.js already treats as "open that shoot directly", so a click opens the clicked frame and prev/next walk the section.
  • clients.names names clients in plain page text, and the page's JSON-LD carries them as mentions, so a search for a client's name can reach the site. Alt text alone is a weak signal for a person's name.
  • Work drops its 8-tile archive strip and links here instead. The galleries singleton stays; it still backs the Work case buttons.
  • tools/optimize_images.py now covers assets/img/gallery/, which it previously skipped because its pattern disallowed a slash. Those 32 photos ship responsive AVIF/WebP variants for the first time.

Image search visibility

Most of the portfolio was invisible to crawlers. Gallery photos only entered the DOM when the lightbox built it from JSON, and a crawler never opens a gallery, so only the photos rendered directly on Work were discoverable.

  • public/sitemap.xml is replaced by src/pages/sitemap.xml.ts, which generates the page URLs plus an <image:image> entry for every photo each page shows, walking the same content/*.yaml the pages read so the list cannot drift. 74 image entries, 24 of them on /archives.
  • The old Wix URLs (/celebrity, /editorial, /about-me, ...) 404 while still sitting in Google's index, which is why those photos surface in search with nothing behind them. src/pages/[legacy].astro emits a stub at each of the 13 old URLs declaring the new page canonical and meta-refreshing to it. GitHub Pages cannot serve a 301, and a canonical plus a 0-second refresh is the signal Google honours in its place.
  • tools/seo_check.py detects the meta refresh, skips the page-level SEO layer for stubs, and instead checks that the target resolves, the canonical matches it, and the stub is not noindex.

Validation

npm run build, then both validators, clean:

OK: 20 page(s) validated, 0 unfilled image slot(s).
SEO check passed: 7 pages, 13 redirect stub(s), 9 assets, 0 warning(s).

Lightbox verified in a real browser on the new page: opens on the clicked frame, correct caption and counter, no console errors.


Generated by Claude Code

claude added 2 commits July 28, 2026 22:34
Two gaps kept the photos out of search results.

Most of the portfolio was invisible to crawlers. Gallery photos only enter
the DOM when the lightbox builds it from the JSON in <script
id="gallery-data">, and a crawler never opens a gallery, so only the 13
photos rendered directly on the Work page were discoverable. Replace the
hand-written public/sitemap.xml with src/pages/sitemap.xml.ts, which
generates the same six page URLs plus an <image:image> entry for every photo
each page shows, walking the same content/*.yaml the pages read so the list
cannot drift. That declares all 43 Work-page photos, gallery included.

The old Wix URLs were dead ends. quentinfears.com previously served a Wix
site whose portfolio lived on category pages (/celebrity, /editorial,
/about-me, ...). The domain now points here, so those URLs 404 while still
sitting in Google's index, which is why the old photos surface with nothing
behind them. src/pages/[legacy].astro emits a stub at each one declaring the
new page canonical and meta-refreshing to it; GitHub Pages cannot serve a
301, and a canonical plus a 0-second refresh is the signal Google honours in
its place.

tools/seo_check.py now detects the meta refresh, skips the page-level SEO
layer for stubs, and instead checks the target resolves, the canonical
matches it, and the stub is not noindex. Both validators pass: 6 pages, 13
redirect stubs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZgHsuYFToS5ZAT5VippUt
A new /archives page holds the portfolio in four sections: Celebrity,
Editorial, Commercial, and Red carpet. Content is a new `archives`
singleton (content/archives.yaml) of { key, title, intro, images[] }, so
sections and photos are editable from the Keystatic admin.

Curated to 5 to 10 photos per section, picked for name recognition first
and dynamism second: Celebrity 8 (the Glamour digital-edition cover, Norman
Reedus, the printed ball gown, the feather gowns, three menswear looks),
Editorial 10 (drawn from both the editorial and menswear editorial sets),
Commercial 6 (the swim campaign, evening wear, accessories). Duplicate
frames were excluded using the crop mapping recorded in
docs/gallery-restructure.md.

Red carpet is defined but empty: the site holds no red-carpet photography.
A section with no images is skipped entirely, so the page shows three
sections today and picks up the fourth the moment its photos land.

Every photo is a real <img> on the page rather than a JSON blob the
lightbox expands, which is both the point of the page and the only reliable
way image search can see the portfolio. The lightbox itself is reused
unchanged: each section is emitted as a one-shoot category, which main.js
already treats as "open that shoot directly", so a click opens the clicked
frame and prev/next walk the section.

A `clients.names` line names clients in plain page text, and the page's
JSON-LD carries them as `mentions`, so a search for a client's name can
reach the site. Alt text alone is a weak signal for a person's name.

Also:
- Work drops its 8-tile archive strip and links to The Archives instead.
  The `galleries` singleton stays; it still backs the Work case buttons.
- tools/optimize_images.py now covers assets/img/gallery/, which it
  previously skipped because its pattern disallowed a slash. Those 32
  photos ship responsive AVIF/WebP variants for the first time.
- Archives joins the nav, the footer, and the sitemap (24 image entries).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZgHsuYFToS5ZAT5VippUt
@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for qafearless ready!

Name Link
🔨 Latest commit 04f1f4e
🔍 Latest deploy log https://app.netlify.com/projects/qafearless/deploys/6a6933c148cd5e00080d1a6e
😎 Deploy Preview https://deploy-preview-28--qafearless.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants