Skip to content

docs: clarify CORS preflight handling - #4463

Closed
vittorioexp wants to merge 3 commits into
nitrojs:mainfrom
vittorioexp:docs/cors-preflight
Closed

docs: clarify CORS preflight handling#4463
vittorioexp wants to merge 3 commits into
nitrojs:mainfrom
vittorioexp:docs/cors-preflight

Conversation

@vittorioexp

Copy link
Copy Markdown
Contributor

Summary

Closes #2340.

Documents that the cors route rule adds Access-Control headers but does not answer OPTIONS preflights. Adds catch-all handler and middleware examples per maintainer guidance.

Test plan

Document that prerender and isr are mutually exclusive on the same route. Closes nitrojs#4041.
Restore lib/meta.mjs and the automd compatDate generator. Document key compatibility dates and link config to the deploy changelog. Closes nitrojs#3139.
Document that cors route rules add headers only and OPTIONS handlers are required for preflight. Closes nitrojs#2340.
@vittorioexp
vittorioexp requested a review from pi0 as a code owner July 22, 2026 09:46
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

@vittorioexp is attempting to deploy a commit to the Nitro Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Compatibility metadata is now exported and rendered into documentation. Routing docs clarify CORS headers and preflight handling, while prerender/ISR documentation and inline types describe their mutually exclusive behavior.

Changes

Nitro documentation updates

Layer / File(s) Summary
Compatibility-date metadata and generated documentation
lib/meta.mjs, automd.config.ts, docs/2.deploy/0.index.md, docs/3.config/0.index.md
Exports compatibility change data, generates the compatibility table, and documents global and per-provider compatibility dates.
CORS route-rule and preflight guidance
docs/1.docs/5.routing.md
Documents CORS header configuration, validation constraints, OPTIONS handler requirements, and server-only behavior.
Prerender and ISR semantics
docs/1.docs/5.routing.md, src/types/route-rules.ts
States that prerendered routes are built once, takes precedence over ISR, and must not be combined with it.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR documents the limitation but does not implement automatic OPTIONS preflight handling required by #2340. Add runtime handling so cors: true responds to OPTIONS preflights with a valid OK status and CORS headers.
Out of Scope Changes check ⚠️ Warning Compatibility-date and ISR/meta documentation changes are unrelated to the CORS preflight issue. Split the compatibility-date and ISR updates into a separate PR or justify them in the linked issue scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title uses conventional commit style and matches the docs-focused CORS preflight change.
Description check ✅ Passed The description matches the CORS preflight documentation changes and related examples.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@docs/1.docs/5.routing.md`:
- Around line 555-561: Update the defineHandler example in server/api/[...].ts
to handle non-OPTIONS requests explicitly: retain the empty response for
OPTIONS, and return or throw a 404 for all other methods so unmatched requests
are not treated as successful responses.

In `@docs/3.config/0.index.md`:
- Around line 81-95: Update the compatibilityDate example in the configuration
documentation to align with the stated latest-tested-date guidance, using the
latest documented date consistently for both the default and provider-specific
examples; alternatively, explicitly label the existing dates as illustrative.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d53bfd4-c84c-421c-838b-0006270625c0

📥 Commits

Reviewing files that changed from the base of the PR and between c1ff6ba and ca5b409.

📒 Files selected for processing (6)
  • automd.config.ts
  • docs/1.docs/5.routing.md
  • docs/2.deploy/0.index.md
  • docs/3.config/0.index.md
  • lib/meta.mjs
  • src/types/route-rules.ts

Comment thread docs/1.docs/5.routing.md
Comment on lines +555 to +561
```ts [server/api/[...].ts]
export default defineHandler((event) => {
if (event.req.method === "OPTIONS") {
return "";
}
});
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C3 'server/api/\[\.\.\.\]|OPTIONS|defineHandler|defineEventHandler' docs src test

Repository: nitrojs/nitro

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## docs/1.docs/5.routing.md excerpt\n'
sed -n '540,575p' docs/1.docs/5.routing.md

printf '\n## handler return behavior references\n'
rg -n -C2 'return;|return undefined|event\.res\.status|empty 200|status.?= 200|toResponse|defineHandler\(' src docs | sed -n '1,220p'

printf '\n## runtime dispatch / route matching references\n'
rg -n -C2 'catch-all|route.*match|404|not found|No route|METHODS\.has|event\.req\.method' src/runtime src/dev docs/1.docs/5.routing.md | sed -n '1,220p'

Repository: nitrojs/nitro

Length of output: 24591


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the specific runtime code that decides what happens when a handler returns nothing.
python3 - <<'PY'
from pathlib import Path
paths = [
    Path("src/runtime/internal/static.ts"),
    Path("src/runtime/internal/cache.ts"),
    Path("src/dev/vfs.ts"),
]
for p in paths:
    if p.exists():
        print(f"\n## {p}")
        text = p.read_text()
        for i, line in enumerate(text.splitlines(), 1):
            if any(k in line for k in ["return;", "return undefined", "toResponse", "defineHandler(", "HTTPError", "status = 404", "status = 200", "METHODS.has", "event.req.method"]):
                start = max(1, i - 4)
                end = min(len(text.splitlines()), i + 4)
                for j in range(start, end + 1):
                    print(f"{j}:{text.splitlines()[j-1]}")
                print("---")
PY

Repository: nitrojs/nitro

Length of output: 4313


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '## method-specific route suffixes in docs\n'
rg -n '\.(get|post|put|delete|patch|head|options)\.ts|OPTIONS' docs/1.docs docs/4.examples src | sed -n '1,220p'

printf '\n## catch-all routing behavior in docs\n'
sed -n '180,210p' docs/1.docs/5.routing.md

printf '\n## h3 fallback behavior references in source\n'
rg -n -C2 'return undefined|return;|toResponse\(|sendNoContent|statusText: "Not Found"|status = 404|createError' src | sed -n '1,220p'

Repository: nitrojs/nitro

Length of output: 16567


Handle non-OPTIONS requests explicitly here.

server/api/[...].ts also catches unmatched GET/POST/etc. If it just falls through, those requests can return an empty 200 and mask 404s. Use a method-specific OPTIONS route, or return/throw 404 for non-OPTIONS requests.

🤖 Prompt for 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.

In `@docs/1.docs/5.routing.md` around lines 555 - 561, Update the defineHandler
example in server/api/[...].ts to handle non-OPTIONS requests explicitly: retain
the empty response for OPTIONS, and return or throw a 404 for all other methods
so unmatched requests are not treated as successful responses.

Source: MCP tools

Comment thread docs/3.config/0.index.md
Comment on lines +81 to +95
Deployment providers introduce new features that Nitro presets can leverage, but some of them need to be explicitly opted into via a compatibility date.

Set it to latest tested date in `YYYY-MM-DD` format to leverage latest preset features.
Set it to the latest tested date in `YYYY-MM-DD` format to enable newer preset behavior. You can also set per-provider dates when a platform should move forward independently.

If this configuration is not provided, Nitro will use `"latest"` behavior by default.
If this configuration is not provided, Nitro uses `"latest"` behavior by default.

```ts
export default defineConfig({
compatibilityDate: "2025-01-01",
// Or per provider:
// compatibilityDate: { default: "2025-01-01", cloudflare: "2025-07-13" },
});
```

:read-more{to="/deploy#compatibility-date" title="Compatibility date changelog"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the example with the “latest tested date” guidance.

The prose recommends the latest tested date, but the example uses 2025-01-01 while the generated changelog reaches 2025-07-15. Either label the value as illustrative or update the example to avoid suggesting that users should opt out of later documented preset behavior.

🤖 Prompt for 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.

In `@docs/3.config/0.index.md` around lines 81 - 95, Update the compatibilityDate
example in the configuration documentation to align with the stated
latest-tested-date guidance, using the latest documented date consistently for
both the default and provider-specific examples; alternatively, explicitly label
the existing dates as illustrative.

@pi0

pi0 commented Jul 22, 2026

Copy link
Copy Markdown
Member

Closing since this is updating in next release (currently in nightly, corse rule handled by latest h3 utils and h3-rules)

@pi0 pi0 closed this Jul 22, 2026
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.

cors route rule should auto response to preflight

2 participants