Repository navigation
Conversation
… vote revalidateTag(LIKES_CACHE_TAG, "max") only marks the tag stale, so the next /skills load is served the pre-vote snapshot and the voter's like appears lost until a second reload. Expire the tag immediately instead. Fixes projnanda#186.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #186.
Trigger
POST /api/likesinvalidates the likes cache withrevalidateTag(LIKES_CACHE_TAG, "max"). In Next 16,"max"only marks the tag stale: the next read oflistAllLikesCached()returns the old snapshot right away and refreshes it in the background (unstable-cache.js: "we're doing background revalidation - return stale immediately"; see alsonode_modules/next/dist/docs/.../revalidateTag.md)./skillsisforce-dynamicand reads through that cache. So:/skills. The page gets the pre-vote snapshot: the count drops back, the heart is empty, andviewerLikedis false becausesubsis stale too.This matches #186 ("votes are not being reflected in the total score", reported for both Google and GitHub sign-ins). That issue was filed on 2026-07-11, the same day
a138af7added the cached likes read with"max". The comment inlib/likes.tspromises that "like/unlike writes bust the tag, so voters still see counts move at once", and the"max"profile breaks that promise.Fix
{ expire: 0 }is the form the Next docs give for Route Handlers that need immediate expiration. (updateTagworks only in Server Actions.) The next read misses the cache and gets fresh data.Compatibility
revalidatewindow and the cache tag stay the same, so the Neon data-transfer savings froma138af7still hold. The only change is that a like or unlike now forces one fresh read.Verification
npx tsc --noEmit,eslinton the changed file andnpm run buildall pass.next start. It uses the same pattern:unstable_cachewithrevalidate: 30and a tag, aforce-dynamicreader, and a POST route that writes and then callsrevalidateTag. Before each run I cleared.next/cache:I did not test against the live Neon database. The dashboard has no test runner right now, so I haven't added a regression test to the repo.
Related, not in this PR
app/skills/actions.tsandapp/api/skills/route.tscallrevalidateTag(SKILLS_CACHE_TAG, "max")after a submission. That likely means a newly submitted skill doesn't appear on the first/skillsreload, which could explain the duplicate submissions in #203. I can send a separate PR (updateTagin the Server Action,{ expire: 0 }in the route) if you'd like.