Skip to content

Feat: feed detail page ssr caching#8

Open
Alessandro100 wants to merge 21 commits intomainfrom
feat/1559-feed-detail-caching
Open

Feat: feed detail page ssr caching#8
Alessandro100 wants to merge 21 commits intomainfrom
feat/1559-feed-detail-caching

Conversation

@Alessandro100
Copy link
Contributor

@Alessandro100 Alessandro100 commented Feb 18, 2026

Summary:

closes: MobilityData/mobility-feed-api#1559

This PR introduces the ability to cache the Feed Detail page to get better performance as well a more efficient use of our server and API.

Plain language explanation

The Feed Detail Page has 2 states: Authenticated and Non Authenticated access, and based on the proxy.ts NextJs will route to the correct page, each with their own caching strategy. Url will stay the same, this is done with rewrite

Non Authenticated State Caching

Since this reponse is consistent with all Non Authenticated users access the Feed detail page, server side caching brings big gains using ISR (Incremental Static Rending). When a users hits a Feed Detail Page, it will check the CDN if it exists, if not, then it will fetch the data as a normal page and cache that in CDN. Now any other Non Authenticated user will be able to hit that CDN for instant page reponse. This will not only save our server from heavy requests, but also our API.
These pages will be cached on the CDN for 2 weeks until one of these conditions happen

  1. There is a new build published
  2. 2 weeks have passed (revalidate time)
  3. The new revalidate endpoint is called, specifying which feeds needs their cache updated.

Authenticated State Caching

Caching is more challenging and less efficient as the response depends on the user who is accessing the page. This means that server side caching for long periods of time would not lead to big benefits and would take up a lot of Vercel Cache. Current implementation: The page is not cached, but the endpoints used to get the feeds data is cached for 10 minutes server side. This is to get some page performance for users who will navigate within their session. If we find that this doesn't work and we need more caching performance, the next step would be to implement client-side caching for this state (extra complexity).

Expected behavior:

Non Authenticated State

First hit of a feed detail page will be standard loading time. After that in any browser, it should be instant.

Authenticated State

First hit of a feed detail page will be standard loading time. After that (within 10 minutes) the page should load quicker but not instant

Testing tips:

Non Authenticated State

NOTE: On the Feed Detail Page a 'generated at' UI element was added to test the caching feature
Go to any Feed Detail Page (Non Authenticated). You will see a loading state.
On any other browser / tab, go to that same feed, it should appear instantly. Check that the 'generated at' value is the same
Extra
Call the revalidate endpoint with the correct field and run the same page, it should show a loading screen with a different 'generated at' value

Authenticated State

NOTE: Only the API call is cached (for 10 minutes) difficult to check
When authenticated, go to a Feed Detail page. You will see a loading state.
Navigate away and go back, there should still be a loading state but much shorter, and the generated at value will be different

Good Info to know

  • Caching does not work on dev build (locally)
  • New Environment variable added REVALIDATE_SECRET

Questions to further improve caching

  • How many feed detail hits happen auth vs not auth
  • Are there certain feed pages that get hit a lot that we can pre-build at build time

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Run the unit tests with yarn test to make sure you didn't break anything
  • Add or update any needed documentation to the repo
  • Format the title like "feat: [new feature short description]". Title must follow the Conventional Commit Specification(https://www.conventionalcommits.org/en/v1.0.0/).
  • Linked all relevant issues
  • Include screenshot(s) showing how this pull request works and fixes the issue(s)

@Alessandro100 Alessandro100 self-assigned this Feb 18, 2026
@vercel
Copy link

vercel bot commented Feb 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mobilitydatabase-web Ready Ready Preview, Comment Feb 18, 2026 8:47pm

Request Review

Copy link
Contributor

Copilot AI left a 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 implements a split feed-detail routing model to enable CDN/ISR caching for unauthenticated users while keeping authenticated views dynamic, with an on-demand revalidation endpoint to bust caches when feeds change.

Changes:

  • Add proxy helpers + proxy logic to rewrite feed-detail requests to either /static (ISR) or /authed (dynamic) routes based on session state.
  • Introduce guest vs authed server data loaders using unstable_cache (14 days public, 10 min per-user), plus a /api/revalidate endpoint and tests.
  • Refactor feed pages/map pages to use the new route structure and pass pre-fetched data into FullMapView; add docs + Cypress e2e coverage.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/setupTests.ts Adds Jest mocks for next/server to support middleware/route testing.
src/proxy.ts Updates proxy routing to handle auth-based rewrites and static route protection.
src/app/utils/proxy-helpers.ts New helper module for feed-detail detection, auth detection, and rewrites.
src/app/utils/proxy-helpers.spec.ts Unit tests for proxy helper behavior.
src/app/utils/auth-server.ts Adds guest token helper + adjusts custom claims for guest/service usage.
src/app/screens/Feed/index.tsx Deletes deprecated Feed component (legacy React Router version).
src/app/screens/Feed/components/FullMapView.tsx Refactors map view to accept server-fetched feed data instead of Redux-driven loading.
src/app/screens/Feed/components/FeedNavigationControls.tsx Converts navigation controls to a client component using useTranslations + router navigation.
src/app/screens/Feed/FeedView.tsx Adds a “Generated at” timestamp to help validate ISR caching behavior.
src/app/interface/RemoteConfig.ts Removes enableGtfsVisualizationMap from remote config shape/defaults.
src/app/components/LogoutConfirmModal.tsx Removes rehydration gating on logout confirmation.
src/app/components/CoveredAreaMap.tsx Removes visualization map feature-flag gating and simplifies related conditions.
src/app/api/revalidate/route.ts Adds authenticated revalidation endpoint using revalidatePath/revalidateTag.
src/app/api/revalidate/route.spec.ts Adds test coverage for revalidation auth and behavior.
src/app/[locale]/feeds/[feedDataType]/[feedId]/static/layout.tsx New ISR layout for guest feed pages (force-static, 14-day revalidate).
src/app/[locale]/feeds/[feedDataType]/[feedId]/static/page.tsx New guest feed detail page using guest cached loader + shared metadata helper.
src/app/[locale]/feeds/[feedDataType]/[feedId]/static/map/page.tsx New guest map page using guest cached loader.
src/app/[locale]/feeds/[feedDataType]/[feedId]/authed/layout.tsx New authed layout (dynamic) that enforces proxy header and pre-fetches per-user cached data.
src/app/[locale]/feeds/[feedDataType]/[feedId]/authed/page.tsx New authed feed detail page using per-user cached loader + shared metadata helper.
src/app/[locale]/feeds/[feedDataType]/[feedId]/authed/map/page.tsx New authed map page using per-user cached loader.
src/app/[locale]/feeds/[feedDataType]/[feedId]/lib/guest-feed-data.ts Adds guest/ISR-safe feed data loader with shared cache tags.
src/app/[locale]/feeds/[feedDataType]/[feedId]/lib/feed-data.ts Adds authenticated per-user feed data loader with 10-minute cache.
src/app/[locale]/feeds/[feedDataType]/[feedId]/lib/feed-data-shared.ts Extracts shared feed/datasets/routes/related-feeds fetch logic used by both loaders.
src/app/[locale]/feeds/[feedDataType]/[feedId]/lib/generate-feed-metadata.ts Adds shared metadata generation helper for authed/static routes.
src/app/[locale]/feeds/[feedDataType]/[feedId]/page.tsx Removes previous single feed page implementation (replaced by authed/static routes).
src/app/[locale]/feeds/[feedDataType]/[feedId]/map/page.tsx Removes previous map page that relied on client-side fetching.
package.json Updates Cypress e2e setup to use next build + next start (needed for ISR).
messages/en.json Removes unused FullMapView “disabled” strings.
messages/fr.json Removes unused FullMapView “disabled” strings.
docs/feed-detail-caching-flow.md Adds mermaid sequence diagram documenting the new caching flow.
cypress/e2e/feed-isr-caching.cy.ts Adds e2e validation for ISR HIT/MISS behavior and revalidation busting.

@github-actions
Copy link

github-actions bot commented Feb 18, 2026

*Lighthouse ran on https://mobilitydatabase-g21en20wh-mobility-data.vercel.app/ * (Desktop)
⚡️ HTML Report Lighthouse report for the changes in this PR:

Performance Accessibility Best Practices SEO
🟢 95 🟢 96 🟢 100 🟢 100

*Lighthouse ran on https://mobilitydatabase-g21en20wh-mobility-data.vercel.app/feeds * (Desktop)
⚡️ HTML Report Lighthouse report for the changes in this PR:

Performance Accessibility Best Practices SEO
🟠 63 🟢 96 🟢 96 🟢 100

*Lighthouse ran on https://mobilitydatabase-g21en20wh-mobility-data.vercel.app/feeds/gtfs/mdb-2126 * (Desktop)
⚡️ HTML Report Lighthouse report for the changes in this PR:

Performance Accessibility Best Practices SEO
🔴 38 🟢 90 🟢 96 🟠 88

*Lighthouse ran on https://mobilitydatabase-g21en20wh-mobility-data.vercel.app/feeds/gtfs_rt/mdb-2585 * (Desktop)
⚡️ HTML Report Lighthouse report for the changes in this PR:

Performance Accessibility Best Practices SEO
🟠 80 🟠 83 🟢 100 🟠 88

*Lighthouse ran on https://mobilitydatabase-g21en20wh-mobility-data.vercel.app/gbfs/gbfs-flamingo_porirua * (Desktop)
⚡️ HTML Report Lighthouse report for the changes in this PR:

Performance Accessibility Best Practices SEO
🟢 100 🟢 96 🟢 96 🟢 100

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

SSR: Caching strategy / implementation for Feed Detail Page

1 participant

Comments