💄 Make homepage people cards clickable + fix console errors#4869
💄 Make homepage people cards clickable + fix console errors#4869wicksipedia wants to merge 12 commits into
Conversation
The texture SVGs used useId() to namespace their <defs>, and the server and client generated different ids, so React bailed out of hydrating the block. The texture is already picked deterministically from the card's index, so the id can be derived the same way. A scope distinguishes the mobile-carousel and desktop-grid copies of each card, keeping the ids unique. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking anywhere on a person's card now opens their SSW People profile. The card-wide link is an overlay rather than a wrapper so the LinkedIn, X and SSW People icons stay separately clickable instead of nesting anchors inside one another. Cards without an SSW People URL stay non-clickable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Next 16 only serves qualities listed in images.qualities. The hero and event banners already render at quality 100, which currently logs a warning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
next/image dropped objectFit in v13; it does nothing today and logs a warning on every logo. The equivalent is the object-contain class. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The arbitrary value matched both the core z utility and the zIndexStack plugin's, so Tailwind warned and the class was unreliable. Adding 2 to the zIndex scale lets the hero use the named z-2 instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The wrapper always set background-image, so blocks without one rendered url(null) and the browser fetched /null. That hit the [filename] catch-all and logged "Unable to find record content/pages/null.mdx" on every page load. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The browsers data was 14 months old, so every build logged a browserslist warning. Ran update-browserslist-db, which also deduped caniuse-lite down to a single version and patch-bumped two transitive deps (crelt, uuid). No target browser changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Radix only accepts collapsible when type is "single". With type="multiple" the prop fell through to the DOM, so React logged "Received `true` for a non-boolean attribute `collapsible`" on every page using the block. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Coverage report
Test suite run success13 tests passing in 1 suite. Report generated by 🧪jest coverage report action from 08688e8 |
There was a problem hiding this comment.
Pull request overview
This PR improves the homepage “People” UX by making each person card fully clickable (without nesting anchors) and resolves several console/build warnings uncovered while addressing a hydration issue.
Changes:
- Make person cards clickable via a full-card link overlay while keeping individual social icons separately clickable.
- Fix hydration mismatch in
PersonCardTextureby replacinguseId()with deterministic, scoped SVG<defs>ids. - Remove/guard sources of console/build warnings (e.g.,
url(null)requests, Radixcollapsibleprop leak, deprecatednext/imageprops, Tailwind z-index ambiguity, Next image quality allowlist) and refresh lockfile browserslist data.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tailwind.config.js | Adds zIndex: { 2: 2 } so z-2 is a stable, non-ambiguous utility. |
| pnpm-lock.yaml | Updates browserslist/caniuse-lite and a few transitive deps after update-browserslist-db. |
| next.config.mjs | Adds images.qualities allowlist to support quality={100} usage. |
| components/layout/v2ComponentWrapper.tsx | Guards backgroundImage style to avoid url(null) → /null requests/log spam. |
| components/blocks/v3/peopleCarousel/personCardTexture.tsx | Removes useId() and introduces deterministic, scoped SVG ids to prevent hydration mismatch. |
| components/blocks/v3/peopleCarousel/peopleCarousel.tsx | Adds full-card link overlay and passes texture scope to keep ids unique across render variants. |
| components/blocks/v3/logoCarousel/logoCarousel.tsx | Replaces deprecated objectFit prop with object-contain class. |
| components/blocks/v3/heroBox/heroBox.tsx | Replaces ambiguous z-[2] with z-2. |
| components/blocks/logoCarousel/logoCarousel.tsx | Replaces deprecated objectFit prop with object-contain class (and keeps conditional invert styling). |
| components/blocks/imageComponents/accordionBlock/accordionBlock.tsx | Avoids passing collapsible when type="multiple" to prevent DOM attribute warnings. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The comment read as though the social links were z-10; that's the overlay. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Good catch — the comment read as though the social links were |
Prettier's Tailwind plugin orders z-2 after the positioning utilities; the old z-[2] arbitrary value sorted differently, so swapping to the named class left the line unsorted and failed lint-code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
/deploy |
|
Deployed changes to https://app-sswwebsite-9eb3-pr-4869.azurewebsites.net ℹ️ Staging slots are no longer created automatically - comment |
Wrapping the card meant an overlay anchor sitting under the social icons, with z-index juggling to keep the icons clickable. Linking just the photo and name drops the overlay entirely: the icon row is a plain sibling and each icon links out on its own. The card keeps its hover outline, and a person with no SSW People URL renders a div instead of a link. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
/deploy |
|
Deployed changes to https://app-sswwebsite-9eb3-pr-4869.azurewebsites.net ℹ️ Staging slots are no longer created automatically - comment |
🚀 Lighthouse Report
|
|
/deploy |
|
Deployed changes to https://app-sswwebsite-9eb3-pr-4869.azurewebsites.net ℹ️ Staging slots are no longer created automatically - comment |
🚀 Lighthouse Report
|
|
Border effect still on whole card during hover |
The LinkedIn and X icons are react-icons that inherit the white→sswRed hover from text colour; the SSW People icon was a colour PNG that couldn't. Swapping it for an inline SVG in currentColor makes all three behave identically — white at rest, sswRed on hover — and drops the PNG and the special-case image branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Why
The people cards on the homepage ("We work together to form an amazing collective brain") weren't clickable — you had to hit the small SSW logo icon to reach someone's profile. Making the whole card a link surfaced a pre-existing hydration error that was killing the block, and chasing that turned up a handful of other console/build warnings worth clearing while we were in here.
What changed
Each fix is a separate commit.
The feature
The bug that broke the clicks
personCardTexture.tsxuseduseId()to namespace its SVG<defs>; server and client generated different ids, so React bailed out of hydrating the whole block and the card went dead. The texture is already chosen deterministically from the card's index, so the id is now derived the same way. Ascopekeeps the mobile-carousel and desktop-grid copies unique.Console + build noise
url(null)→GET /null.v2ComponentWrapperalways setbackground-image, so any block without one renderedurl(null). The browser dutifully fetched/null, which hit the[filename]catch-all and loggedUnable to find record content/pages/null.mdxon every page load. One guard, both symptoms gone.collapsibleleaking to the DOM. Radix'sAccordiononly acceptscollapsiblewithtype="single". Withtype="multiple"it fell through to the DOM and React loggedReceived `true` for a non-boolean attribute `collapsible`on every page using the block.objectFitprop on both logo carousels — dropped bynext/imagein v13, so it did nothing and warned on every logo. Replaced withobject-contain.quality={100}, which Next 16 will refuse to serve unless it's listed. Addedimages.qualitiestonext.config.mjs.z-[2]. The arbitrary value matched both the corezutility and thezIndexStackplugin's, so Tailwind warned and the class was unreliable. Added2to thezIndexscale; the hero uses the namedz-2.update-browserslist-db, which also dedupedcaniuse-litefrom three copies to one and patch-bumped two transitive deps (crelt,uuid). No target browser changes.Verification
Driven in a real browser against a dev server:
ssw.com.au/people/adam-cogan/; clicking the LinkedIn icon on the same card navigates tolinkedin.com/in/adamcogan— the overlay and the icons each win their own clicks./nullrequests, no duplicate texture ids in the DOM.collapsibleerror is gone.tsc --noEmitclean.Not fixed (out of scope, flagging them)
/peopleis a separate app served atssw.com.au/peoplein production — nothing in this repo serves that route, so this is expected locally and fine in prod./api/tina/query/with-fallbacks404s on the consulting page. That's Tina's own dev-only endpoint, unrelated to anything here.🤖 Generated with Claude Code