Skip to content

Fix skill.stack-auth.com CDN serving HTML to curl#1452

Merged
mantrakp04 merged 1 commit into
devfrom
fix/skill-endpoint-cdn-vary
May 20, 2026
Merged

Fix skill.stack-auth.com CDN serving HTML to curl#1452
mantrakp04 merged 1 commit into
devfrom
fix/skill-endpoint-cdn-vary

Conversation

@mantrakp04
Copy link
Copy Markdown
Collaborator

@mantrakp04 mantrakp04 commented May 20, 2026

Summary

  • Adds Vary: Sec-Fetch-Mode, Sec-Fetch-Dest on the skills app root route so the CDN caches markdown and HTML responses separately.
  • Fixes production behavior where curl https://skill.stack-auth.com/ could return the browser HTML landing page (cached from a Sec-Fetch-Mode: navigate request) instead of the canonical SKILL.md body.

Context

The route already content-negotiates: browsers with Sec-Fetch-Mode: navigate get HTML; curl and agents get markdown. Without Vary, Vercel served a single cached variant to all clients.

Test plan

  • Deploy or preview the skills app
  • curl -sSL https://skill.stack-auth.com/ | head -3 returns markdown (--- frontmatter), not <!doctype html>
  • Open https://skill.stack-auth.com/ in a browser — still shows the HTML landing page
  • Purge Vercel cache if stale HTML persists after deploy

Made with Cursor

Summary by CodeRabbit

  • Chores
    • Improved CDN caching configuration to optimize content delivery and response handling across different content formats.

Review Change Stack

Add Vary: Sec-Fetch-Mode, Sec-Fetch-Dest so Vercel caches the markdown
response (agents/curl) separately from the HTML landing page (browsers).

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings May 20, 2026 18:48
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

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

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-auth-mcp Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-auth-skills Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-backend Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-dashboard Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-demo Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-docs Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-preview-backend Ready Ready Preview, Comment May 20, 2026 6:54pm
stack-preview-dashboard Ready Ready Preview, Comment May 20, 2026 6:54pm

Copy link
Copy Markdown
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 fixes incorrect CDN caching behavior on skill.stack-auth.com by ensuring the route’s HTML-vs-markdown content negotiation is reflected in the CDN cache key.

Changes:

  • Adds a Vary: Sec-Fetch-Mode, Sec-Fetch-Dest response header so CDN caches the HTML (browser navigation) and markdown (curl/agents) variants separately.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 20, 2026

Greptile Summary

This PR adds Vary: Sec-Fetch-Mode, Sec-Fetch-Dest to the shared COMMON_HEADERS constant in the skills app root route so the CDN caches markdown and HTML responses under separate cache keys.

  • The existing wantsHtml() function already content-negotiates between HTML (for browsers sending Sec-Fetch-Mode: navigate or Sec-Fetch-Dest: document) and markdown (for curl and agent clients). Without this Vary header the CDN was serving a single cached variant — whichever was populated first — to all clients.
  • The two header names in Vary exactly mirror the two conditions in wantsHtml(), so the cache partitioning is logically consistent with the negotiation logic.

Confidence Score: 4/5

Safe to merge — the change is a one-line header addition that correctly reflects the existing content-negotiation logic.

The two header names in Vary exactly mirror the two conditions checked in wantsHtml(), so the cache partitioning is logically consistent. The only open question is whether Vercel's CDN edge actually uses Sec-Fetch-* request headers as cache-key discriminators; some CDN layers strip browser-metadata headers before consulting the cache. If they are stripped, the Vary would be present in responses but have no effect on CDN behavior, leaving the original problem unresolved.

apps/skills/src/app/route.ts — worth verifying that Vercel's edge cache honours Sec-Fetch-* as Vary dimensions after deploy.

Important Files Changed

Filename Overview
apps/skills/src/app/route.ts Adds Vary: Sec-Fetch-Mode, Sec-Fetch-Dest to COMMON_HEADERS; the two header names correctly mirror the two conditions in wantsHtml(), fixing CDN cache pollution between HTML and markdown responses.

Sequence Diagram

sequenceDiagram
    participant B as Browser
    participant C as curl/Agent
    participant CDN as Vercel CDN
    participant O as Origin

    B->>CDN: GET / with Sec-Fetch-Mode navigate
    CDN->>O: Cache miss — forward
    O-->>CDN: 200 HTML + Vary Sec-Fetch-Mode Sec-Fetch-Dest
    CDN-->>B: HTML cached under navigate key

    C->>CDN: GET / no Sec-Fetch headers
    CDN->>O: Cache miss different Vary key
    O-->>CDN: 200 Markdown + Vary Sec-Fetch-Mode Sec-Fetch-Dest
    CDN-->>C: Markdown cached under absent key

    B->>CDN: GET / with Sec-Fetch-Mode navigate
    CDN-->>B: HTML from cache

    C->>CDN: GET / no Sec-Fetch headers
    CDN-->>C: Markdown from cache
Loading

Reviews (1): Last reviewed commit: "Fix skill.stack-auth.com CDN serving HTM..." | Re-trigger Greptile

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

Added a Vary response header to cache configuration directing CDN intermediaries to cache markdown and HTML content variants separately based on Sec-Fetch-Mode and Sec-Fetch-Dest fetch request attributes.

Changes

Cache Header Configuration

Layer / File(s) Summary
Vary header for content variants
apps/skills/src/app/route.ts
Vary: Sec-Fetch-Mode, Sec-Fetch-Dest header added to COMMON_HEADERS with a note that CDN caching must treat markdown and HTML response variants separately based on fetch context.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Poem

🐰 A header so tiny, yet mighty and fine,
Tells CDNs which markdown, which HTML shine,
No cache collision, each variant clean,
Two bytes of config, a caching machine!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: adding Vary headers to resolve CDN caching issues on skill.stack-auth.com when curl requests receive HTML instead of markdown.
Description check ✅ Passed The description is well-structured with Summary, Context, and Test Plan sections that thoroughly explain the problem, solution, and verification steps, though it doesn't strictly follow the minimal template provided.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/skill-endpoint-cdn-vary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/skills/src/app/route.ts`:
- Around line 213-214: Remove the manually-set "Vary" header (the "Vary":
"Sec-Fetch-Mode, Sec-Fetch-Dest" entry) from the route handler in
apps/skills/src/app/route.ts because Next.js 16 will overwrite it; instead
either add segment-level caching (e.g., export const revalidate = <seconds>) to
let Next.js manage cache variants, or move variant caching to your
CDN/infrastructure (Cloudflare/Nginx) as described in the review comment; also
remove any manual Cache-Control headers in this handler so Next.js can control
caching via segment exports and cache-tag mechanisms.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74552292-4ab6-48d3-a226-d81d00fd1ece

📥 Commits

Reviewing files that changed from the base of the PR and between 3df4ca5 and 3076651.

📒 Files selected for processing (1)
  • apps/skills/src/app/route.ts

Comment thread apps/skills/src/app/route.ts
@mantrakp04 mantrakp04 merged commit f170e3f into dev May 20, 2026
32 of 41 checks passed
@mantrakp04 mantrakp04 deleted the fix/skill-endpoint-cdn-vary branch May 20, 2026 19:27
mantrakp04 added a commit that referenced this pull request May 20, 2026
## Summary

Follow-up to #1452. `Sec-Fetch-Mode` / `Sec-Fetch-Dest` didn't reliably
split HTML vs. markdown at the CDN edge, so curl could still get the
HTML landing page. Switch to the `Accept` header:

- Browsers send `Accept: text/html,...` on top-level navigations.
- `curl`, `fetch()`, and agent fetchers send `*/*` or omit `Accept`.
- Serve HTML only when `text/html` is explicitly listed; everything else
gets `SKILL.md`.
- `Vary` updated to `Accept` to match.

## Test plan

- [ ] Deploy preview
- [ ] `curl -sSL https://skill.stack-auth.com/ | head -3` returns
markdown frontmatter
- [ ] Browser load of `https://skill.stack-auth.com/` still shows the
HTML landing page
- [ ] Purge Vercel cache if stale variants persist

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved content format negotiation for skill resources to correctly
serve HTML or markdown based on client requests.

* **Chores**
* Optimized caching behavior for edge and CDN services to enhance global
content distribution efficiency.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1454?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

2 participants