-
Notifications
You must be signed in to change notification settings - Fork 0
Revamp: Projects & People UX, Next.js 16 caching, A11y/SEO polish #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Replace `unstable_cache` with new `use cache` API which introduced in Next.js 16. - Switch revalidation to `cacheLife` for following the latest conventions. - Remove `REVALIDATE_TIME` constant from `.env` as it's no longer needed. - Remove all `revalidate`, `dynamicParams`, `runtime` options since not supported with cacheComponents. - Move r2-gc from `/people` to a seperate API route `/api/r2-gc` and work with GitHub Actions for CRON scheduling. - Improved build time API calls by setting up in-process coalescing of concurrent reads for the same table (reduced to only 18 calls at build time). - Default revalidation changed to 12 hours for all cache calls.
π¨ Lint Checkβ Lint: No linting issues found! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR modernizes the DTR website's caching strategy by migrating to Next.js 16's use cache API, enhances UX/accessibility across Projects and People pages with client-side search and improved layouts, and centralizes R2 garbage collection through a secure API endpoint. The changes reduce API load, improve perceived performance, and strengthen semantic HTML and accessibility.
- Replaces legacy
unstable_cachewith Next.js 16use cache+cacheLifepresets and adds in-process request coalescing for Airtable calls - Redesigns Projects page with collapsible SIG cards, client-side search/filters, balanced two-column layout, and dynamic imports for heavy components
- Adds in-page name search to People directory scoped to Active/Alumni tabs with result counts and empty states
- Replaces home carousel with accessible version supporting keyboard navigation, play/pause controls, and reduced-motion preferences
- Migrates daily R2 cleanup from page-load to token-gated API route triggered by GitHub Actions
Reviewed Changes
Copilot reviewed 43 out of 44 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/lib/consts.ts |
Removes REVALIDATE_TIME env constant, replaced by Next.js 16 caching |
src/lib/airtable/airtable.ts |
Migrates to use cache + cacheLife('halfDays') with in-process inflight coalescing |
src/lib/airtable/project.ts |
Adds people parameter to getProjects() to reduce API calls, adds null guards for banner image |
src/lib/airtable/sig.ts |
Passes people to getProjects(), filters null projects |
src/hooks/useSearch.ts |
New hook for debounced search state management |
src/hooks/useCarousel.ts |
New hook for carousel state including keyboard, touch, autoplay, and reduced-motion |
src/components/shared/SearchBar.tsx |
Reusable search input component with clear button |
src/components/shared/MarkdownContents.tsx |
Unified markdown renderer with GFM and limited raw HTML support |
src/components/shared/PopupAnnouncement.tsx |
Fixes Next.js warning by computing date after hydration instead of in render |
src/components/shared/Header/index.tsx |
Replaces Container with inline padding/max-width |
src/components/shared/Header/DesktopNav.tsx |
Increases font size for desktop navigation |
src/components/projects/ProjectsClient/* |
New client-side search, collapsible SIG cards, balanced two-column layout |
src/components/projects/TeamMembers/* |
Refactored into role-grouped layout with alumni badges and sorting |
src/components/projects/ProjectVideo.tsx |
Dynamic import, improved semantic HTML with section/heading structure |
src/components/projects/ProjectPublications.tsx |
Enhanced card-based layout with icons and external link indicators |
src/components/people/PeopleDirectory.tsx |
Adds scoped name search with result counts and empty states |
src/components/people/BioClamp.tsx |
Uses shared MarkdownContents component |
src/components/home/Carousel.tsx |
New accessible carousel with keyboard/touch support and play/pause controls |
src/app/projects/page.tsx |
Simplified to delegate to ProjectsClient, improved metadata and SEO |
src/app/projects/loading.tsx |
Skeleton loading matching new two-column layout with yellow accents |
src/app/projects/[id]/page.tsx |
Adds JSON-LD structured data, back link, dynamic imports, improved metadata |
src/app/people/page.tsx |
Removes page-load R2 GC call |
src/app/layout.tsx |
Removes Container wrapper, uses inline max-width and padding |
src/app/globals.css |
Hides WebKit search cancel button globally for consistent styling |
src/app/api/r2-gc/route.ts |
New token-gated API endpoint for R2 garbage collection |
next.config.ts |
Adds cacheComponents and custom cacheLife presets (halfDays, days) |
.github/workflows/r2-gc.yml |
Daily scheduled workflow to trigger R2 cleanup API |
package.json |
Adds clsx, remark-gfm, rehype-raw dependencies |
README.md |
Updates caching documentation to reference Next.js 16 use cache |
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
π¨ Lint Checkβ Lint: No linting issues found! |
β¨ Features Updates && π Code Refactor
π Description
A broad upgrade that modernizes caching, moves the daily R2 garbage-collection workflow from
\peopleto a separate api, replaces the home page slider with an accessible carousel, and significantly refactors the Projects and People experiences (search, layout, loading states, and semantics). Also includes small fixes for a Next.js warning and general code quality.This PR:
use cache+cacheLifeand adds an in-process concurrency coalescer for Airtable requests.These changes reduce Airtable/API load, improve time-to-interactive and perceived performance, and make navigation clearer and more accessible.
π Feature Changes
New component or page
src/components/home/Carousel.tsx(accessible carousel with keyboard/swipe, play/pause)src/app/api/r2-gc/route.ts(token-gated R2 GC)src/components/shared/SearchBar.tsx,src/hooks/useSearch.ts(reusable search)src/components/shared/MarkdownContents.tsx(remark-gfm + rehype-raw)src/components/projects/ProjectsClient/*(client search, collapsible SIG cards, layout balance)src/components/projects/TeamMembers/*(role grouping, alumni badge, sorting)API update
POST /api/r2-gcwithx-cron-token(or?token=) and JSON body controlling prefix, age, cadence, and delete caps.UI/UX improvement
Other:
r2-gc.yml(scheduled daily 08:00 UTC) to ping the R2 cleanup endpoint.π Refactor Changes
Code optimization
server-onlymodule +use cache/cacheLife('halfDays')and in-process inflight coalescing to prevent thundering herds.Improve maintainability
ProjectsClient).Remove unnecessary code
Containerwrapper, oldSlidescomponent, scatteredrevalidateexports, andREVALIDATE_TIMEenv usage.Other:
next.config.tswithcacheComponentsand namedcacheLifebuckets (halfDays,days).π Bug Fixes
Fixed issue: Next.js warerroring βused
new Date()in a Client Component without a Suspense boundaryβPopupAnnouncement: computetodayafter hydration and store in state; removeuseMemo(new Date())in render path; ensure SSR/CSR parity.Improved error handling
POST /api/r2-gcreturns401for invalid/missing token; robust JSON parsing with safe defaults.getProjects: null/empty-array guards; safe banner/OG image handling.Performance fix
fillwith responsivesizes, skeleton loading, column balancing to reduce layout shifts.Add
peopleparameter togetProjects()for reducing api call.Other:
HomeIntro/MediaBanneruse<a>withrel="noopener noreferrer".β Checklist
π Dependency Changes
π¬ Additional Notes
Caching migration (important):
unstable_cache/revalidatewith Next 16use cache+cacheLife('halfDays')and per-table inflight coalescing (src/lib/airtable/airtable.ts).REVALIDATE_TIMEusage and the env var; delete it from deployments.cacheLifepresets innext.config.tsfor clear βhalf-daysβ and βdaysβ buckets.R2 GC automation:
New workflow:
.github/workflows/r2-gc.ymlruns 08:00 UTC daily and via manual dispatch.Requires
R2_CRON_SECRETGitHub secret. The action POSTs JSON to/api/r2-gcwith configurable:{ "prefix":"images/", "maxAgeDays":60, "minIntervalHours":24, "maxDeletePerRun":250 }The page-load-time GC in
people/page.tsxwas removed; cleanup is now centralized and throttled server-side.Projects UI/UX:
ProjectsClient) provides debounced search, collapsible SIGs, and balanced two-column stacking using estimated collapsed heights to avoid jarring shifts./projects/[id]): JSON-LD (CreativeWork), robust OG/Twitter metadata, dynamic imports for video/publications.People experience:
BioClampand markdown blocks now pipe throughMarkdownContents.A11y & polish:
Minor UI changes:
Containerin favor of consistentmax-w-7xlandpx-4on layout/main.Files of Interest (high-level)
.github/workflows/r2-gc.yml,src/app/api/r2-gc/route.tssrc/lib/airtable/airtable.ts,next.config.ts,README.md,src/lib/consts.ts(removedrevalidateTime)src/app/projects/page.tsx,src/app/projects/[id]/page.tsx,src/app/projects/loading.tsx,src/components/projects/ProjectsClient/*,src/components/projects/TeamMembers/*,src/components/projects/ProjectVideo.tsx,src/components/projects/ProjectPublications.tsxsrc/components/people/PeopleDirectory.tsx,src/components/people/BioClamp.tsxsrc/components/home/Carousel.tsx(+ removedSlides.tsx)src/components/shared/MarkdownContents.tsx,src/components/shared/SearchBar.tsx,src/components/shared/Header/*,src/app/layout.tsx,src/app/globals.csssrc/components/shared/PopupAnnouncement.tsx(Next.js runtime error resolved)