Fix /sitemap.xml 500s from request-time cookies() - #7
Merged
Conversation
Stop using the cookie-based Supabase server client in the cached sitemap route. Fetch published mashups with the public anon client, omit invalid dates, and always fall back to static URLs so the response stays valid XML even with zero generations. Co-authored-by: Chinmay Kabi <chinmay@blend.to>
Chinmay-KB
marked this pull request as ready for review
August 13, 2026 13:37
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
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.
TL;DR
/sitemap.xmlused the cookie-based Supabase SSR client (cookies()fromnext/headers) inside a metadata route that is supposed to be cached (revalidate = 3600). That is a request-time API, so the sitemap could not be statically generated,getSupabasePublicEnv()/cookies()throws were uncaught 500s, and anInvalid DatelastModifiedwould crash Next’s XML serializer (toISOString()).This PR fetches published mashups with the same cookie-less anon client as the homepage feed, omits bad dates, and always returns the static marketing URLs so the response stays valid XML even with zero generations.
robots.txtis unchanged.Root cause
src/lib/sitemap-data.tscalledcreateSupabaseServerClient(), which:await cookies()— Next.js 16 treats this as a request-time API. Installed docs: “sitemap.jsis a special Route Handler that is cached by default unless it uses a Request-time API.”getSupabasePublicEnv()throws if public Supabase env is missing (homepage already usestryGetSupabasePublicEnv()).new Date(row.updated_at)aslastModified— Next serializes dates withdate.toISOString(). An invalid date throwsRangeErrorand 500s the entire sitemap.Live probe from this agent (before the fix, production
main):curl https://xbuildsy.com/sitemap.xmloften returned 200 with valid XML (41 URLs: 4 static + 33/g/…+ 4/u/…).x-vercel-cache: MISS— the sitemap was not ISR-cached, consistent withcookies()forcing dynamic rendering.[]; the 500 is an uncaught throw, not an empty list.Local
yarn buildon this branch now reports:i.e. the sitemap is prerendered with the intended 1h revalidate instead of
ƒdynamic.What changed
src/lib/sitemap-data.ts— one publicgenerationsquery viacreatePublicFeedClient()+publicGenerationsQuery(same filters as the feed). Failures return{ generations: [], creators: [] }. Invalid/blank slugs, creator ids, and dates are skipped.lastModifiedis an ISO string or omitted.src/app/sitemap.ts— thin wrapper with a static-URL fallback if anything still throws.src/lib/__tests__/sitemap-data.test.ts— empty catalog, invalid dates, missing client, thrown query.src/app/robots.ts(still points at${base}/sitemap.xml).How to review
src/lib/sitemap-data.ts— confirm we no longer import@/lib/supabase/server.src/app/sitemap.ts— confirm static fallback.src/lib/__tests__/sitemap-data.test.ts.Verification
yarn test— 88 passed (including 10 new sitemap tests)yarn lint— 0 errors (pre-existing warnings only)yarn build(CI placeholder Supabase env) — compiled;/sitemap.xmlis static with 1h revalidate;/robots.txtstill staticPost-merge live checks
Production still serves the old dynamic sitemap until this lands on
main. After deploy:curl -sI https://xbuildsy.com/sitemap.xml— expect 200,content-type: application/xml, and ideallyx-vercel-cache: HIT(orSTALE) on a second request rather than perpetualMISS./,/feed,/generate,/aboutplus/g/{slug}and/u/{id}when mashups exist.https://xbuildsy.com/robots.txtstill hasSitemap: https://xbuildsy.com/sitemap.xml.Other site-health findings (not fixed here)
.github/workflows/site-health.ymlonly runsyarn build/test/lintwith placeholder env. It would not have caught a production/sitemap.xml500./imagesis 404. An older SEO commit advertised/images; the page was later removed. Not in the current sitemap.robots.txtrules (bot Disallows + Content-Signal) above the Next.jsrobots.tsoutput. The NextSitemap:line is still present. Out of scope (no DNS/domain edits).GET /u/not-a-userreturns 200 (soft missing profile) rather than 404 — crawlers may index empty profile URLs listed in the sitemap. Separate issue.if-x-built-y.vercel.app/sitemap.xmlalso 200’d with the same body as the apex domain when probed from this VM.