Skip to content

presets(vercel): support vercel cron#4308

Open
RihanArfan wants to merge 3 commits into
v2from
backport-vercel-cron
Open

presets(vercel): support vercel cron#4308
RihanArfan wants to merge 3 commits into
v2from
backport-vercel-cron

Conversation

@RihanArfan

Copy link
Copy Markdown
Member

🔗 Linked issue

Backport of #4030

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme, or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Support Vercel Cron within Nitro Tasks. Automatically creates Vercel Cron configuration based on Nitro scheduled tasks, so fully zero-config when deploying to Vercel.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
nitro.build Ready Ready Preview, Comment Jun 9, 2026 1:36pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds native Vercel Cron Jobs support to Nitro. Users can define scheduled tasks in nitro.config.ts, which are converted to Vercel cron configuration at build time with an auto-generated HTTP handler that validates optional secrets and invokes the tasks.

Changes

Vercel Cron Tasks Integration

Layer / File(s) Summary
Cron handler configuration contract
src/presets/vercel/types.ts
VercelOptions now includes optional cronHandlerRoute?: string (default /_vercel/cron) to customize the endpoint path for Vercel's cron triggers.
Cron request handler implementation
src/presets/vercel/runtime/cron-handler.ts
New HTTP handler validates optional CRON_SECRET using constant-time comparison, requires x-vercel-cron-schedule header, invokes runCronTasks with schedule and scheduledTime payload, and returns success.
Preset initialization and handler registration
src/presets/vercel/preset.ts
Vercel preset imports fileURLToPath, sets default cronHandlerRoute, and extends rollup:before hook to conditionally register the lazy cron handler when experimental tasks are enabled and scheduled tasks exist.
Build-time Vercel cron config generation
src/presets/vercel/utils.ts
generateBuildConfig conditionally injects config.crons entries from scheduledTasks, using the configured cron handler route and merging with existing entries.
Documentation and test snapshots
docs/1.guide/10.tasks.md, docs/2.deploy/20.providers/vercel.md, test/presets/vercel.test.ts
Platform support guidance corrected for Cloudflare and Vercel; new Vercel section documents build-time cron conversion and CRON_SECRET security pattern; test snapshots updated for cron config, routes, and handler function.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Possibly related PRs

  • nitrojs/nitro#4030: Implements the same Vercel scheduled-tasks integration with matching cron handler and build-config generation changes.
  • nitrojs/nitro#4032: Also modifies src/presets/vercel/utils.ts in the generateBuildConfig function, so shares the build-config generation code path.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description is directly related to the changeset, clearly explaining the addition of Vercel Cron support within Nitro Tasks with zero-config deployment.
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.
Title check ✅ Passed The pull request title follows the conventional commits format with a scope (vercel) and a descriptive subject about adding Vercel cron support.

✏️ 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 backport-vercel-cron

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.

@pkg-pr-new

pkg-pr-new Bot commented Jun 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/nitropack@4308

commit: 8308dfc

@RihanArfan

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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

🧹 Nitpick comments (1)
test/presets/vercel.test.ts (1)

21-33: 🏗️ Heavy lift

Add runtime coverage for the new cron handler contract.

These snapshot updates prove that the cron artifacts are emitted, but they never exercise src/presets/vercel/runtime/cron-handler.ts. Regressions in CRON_SECRET validation, missing x-vercel-cron-schedule handling, or runCronTasks invocation would still ship unnoticed.

Also applies to: 469-560

🤖 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 `@test/presets/vercel.test.ts` around lines 21 - 33, Add a runtime test that
actually imports and invokes the cron request handler to exercise CRON_SECRET
validation, x-vercel-cron-schedule handling, and runCronTasks invocation: in the
existing test suite (the "should add route rules to config" area) add new tests
that (1) set process.env.CRON_SECRET and call the exported cron handler function
with/without the x-vercel-cron-schedule header to assert it accepts valid
secrets and rejects missing/invalid ones, (2) mock/spy the runCronTasks function
to verify it is called with the expected schedule from the header (and not
called on auth failure), and (3) assert the handler returns the correct HTTP
responses; reference the cron handler export name and runCronTasks symbol when
locating code to call/mock.
🤖 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 `@src/presets/vercel/types.ts`:
- Around line 131-141: The cronHandlerRoute option is consumed verbatim (used in
preset.ts and utils.ts) which allows invalid values like "api/cron"; normalize
or validate it at the API boundary: in the code that reads the option (the
config parsing/merge path that references cronHandlerRoute in preset.ts and
utils.ts) call withLeadingSlash(cronHandlerRoute) to ensure it starts with "/"
or throw a clear config error if the value is not an absolute path (include the
user value in the error message and mention expected format like
"/_vercel/cron"); ensure downstream uses use the normalized value so generated
Vercel cron paths and Nitro handler routes are always valid.

In `@src/presets/vercel/utils.ts`:
- Around line 235-242: Generated cron entries (cronEntries) are blindly merged
into config.crons causing duplicate {path, schedule} entries; update the merge
to deduplicate by comparing path and schedule pairs from
nitro.options.scheduledTasks (cronPath and schedule) before assigning to
config.crons. Locate the block building cronEntries and change the logic to
filter out any entry whose {path, schedule} already exists in config.crons (or
vice versa), e.g., build a Set keying on `${path}|${schedule}` or use
Array.prototype.find to skip duplicates, then assign the combined unique list
back to config.crons.

---

Nitpick comments:
In `@test/presets/vercel.test.ts`:
- Around line 21-33: Add a runtime test that actually imports and invokes the
cron request handler to exercise CRON_SECRET validation, x-vercel-cron-schedule
handling, and runCronTasks invocation: in the existing test suite (the "should
add route rules to config" area) add new tests that (1) set
process.env.CRON_SECRET and call the exported cron handler function with/without
the x-vercel-cron-schedule header to assert it accepts valid secrets and rejects
missing/invalid ones, (2) mock/spy the runCronTasks function to verify it is
called with the expected schedule from the header (and not called on auth
failure), and (3) assert the handler returns the correct HTTP responses;
reference the cron handler export name and runCronTasks symbol when locating
code to call/mock.
🪄 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: 8f5f8fc4-6c37-46c5-b006-94ccb6eb4bcd

📥 Commits

Reviewing files that changed from the base of the PR and between f3a5773 and 8308dfc.

📒 Files selected for processing (7)
  • docs/1.guide/10.tasks.md
  • docs/2.deploy/20.providers/vercel.md
  • src/presets/vercel/preset.ts
  • src/presets/vercel/runtime/cron-handler.ts
  • src/presets/vercel/types.ts
  • src/presets/vercel/utils.ts
  • test/presets/vercel.test.ts

Comment on lines +131 to +141
/**
* The route path for the Vercel cron handler endpoint.
*
* When `experimental.tasks` and `scheduledTasks` are configured,
* Nitro registers a cron handler at this path that Vercel invokes
* on each scheduled cron trigger.
*
* @default "/_vercel/cron"
* @see https://vercel.com/docs/cron-jobs
*/
cronHandlerRoute?: string;

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize or validate cronHandlerRoute at the API boundary.

This new public option is consumed verbatim in both preset.ts and utils.ts. A value like "api/cron" will generate an invalid Vercel cron path and a mismatched Nitro handler route instead of failing fast. Please normalize with withLeadingSlash() or throw an explicit config error when the value is not an absolute path.

As per coding guidelines: "Prefer explicit errors over silent failures in error handling" and "Include actionable context in error messages".

🤖 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 `@src/presets/vercel/types.ts` around lines 131 - 141, The cronHandlerRoute
option is consumed verbatim (used in preset.ts and utils.ts) which allows
invalid values like "api/cron"; normalize or validate it at the API boundary: in
the code that reads the option (the config parsing/merge path that references
cronHandlerRoute in preset.ts and utils.ts) call
withLeadingSlash(cronHandlerRoute) to ensure it starts with "/" or throw a clear
config error if the value is not an absolute path (include the user value in the
error message and mention expected format like "/_vercel/cron"); ensure
downstream uses use the normalized value so generated Vercel cron paths and
Nitro handler routes are always valid.

Comment thread src/presets/vercel/utils.ts Outdated
@RihanArfan RihanArfan marked this pull request as ready for review June 8, 2026 15:16
@RihanArfan RihanArfan requested a review from pi0 as a code owner June 8, 2026 15:16
@pi0 pi0 added the v2 label Jun 8, 2026
export default eventHandler(async (event) => {
// Validate CRON_SECRET if set - https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs
const cronSecret = process.env.CRON_SECRET;
if (cronSecret) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We shuld make it required as part of backport (there had been security reports)

@pi0 pi0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM when we made secret required

@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.

🧹 Nitpick comments (1)
src/presets/vercel/runtime/cron-handler.ts (1)

6-6: ⚡ Quick win

Remove the inline explanatory comment at Line 6.

This comment narrates what the next lines do; please drop it to match source style for src/**/*.{ts,js}.

As per coding guidelines, "Do not add comments explaining what the line does unless prompted."

🤖 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 `@src/presets/vercel/runtime/cron-handler.ts` at line 6, Remove the inline
explanatory comment that reads "Require and validate CRON_SECRET -
https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs" from the
top of the cron-handler module so the code only contains the actual CRON_SECRET
validation logic (look for references to CRON_SECRET in cron-handler/cron
handling code). Ensure no other formatting or logic changes are made.

Source: Coding guidelines

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

Nitpick comments:
In `@src/presets/vercel/runtime/cron-handler.ts`:
- Line 6: Remove the inline explanatory comment that reads "Require and validate
CRON_SECRET -
https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs" from the
top of the cron-handler module so the code only contains the actual CRON_SECRET
validation logic (look for references to CRON_SECRET in cron-handler/cron
handling code). Ensure no other formatting or logic changes are made.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0de51920-e1a7-4432-b84c-9c423a5fd281

📥 Commits

Reviewing files that changed from the base of the PR and between 8308dfc and e460586.

📒 Files selected for processing (2)
  • src/presets/vercel/runtime/cron-handler.ts
  • src/presets/vercel/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/presets/vercel/utils.ts


:read-more{title="Securing cron jobs" to="https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs"}

To prevent unauthorized access to the cron handler, set a `CRON_SECRET` environment variable in your Vercel project settings. When `CRON_SECRET` is set, Nitro validates the `Authorization` header on every cron invocation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Docs are outdated, it is an essential step now

@pi0 pi0 changed the title preset(vercel): support vercel cron presets(vercel): support vercel cron Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants