Nitro (and thus Nuxt) has experimental support for scheduled tasks. However, if you're deploying to Netlify, you'll quickly discover that Nitro's scheduledTasks
feature doesn't work yet. Don't worry though - there's a workaround that's actually quite elegant!
Nitro's experimental tasks feature allows you to define scheduled jobs directly in your Nuxt application:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
experimental: {
tasks: true,
},
scheduledTasks: {
"0 0 * * *": ["daily:cleanup"], // This won't work on Netlify
},
},
});
While this works great locally and on some platforms, Netlify doesn't support Nitro's scheduled tasks... yet.
The workaround is surprisingly simple and follows good architectural principles:
This approach has several benefits:
First, let's create an API endpoint that will handle our scheduled task:
// server/api/tasks/example-task.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
// Validate the secret key
const secretKey = useRuntimeConfig().taskSecret;
if (!secretKey) {
throw createError({
statusCode: 500,
statusMessage: "Secret must be set",
});
}
if (body.secret !== secretKey) {
throw createError({
statusCode: 401,
statusMessage: "Unauthorized",
});
}
// Your actual task logic here
const now = Date.now();
console.log("Running example record task: ", now);
// Example: Store something in KV storage
const storage = useStorage("example:record");
await storage.setItem(String(now), now);
return {
success: true,
timestamp: now,
message: "Task completed successfully",
};
});
Create a Netlify function that will call your API endpoint:
// netlify/functions/example-task.mts
import type { Config } from "@netlify/functions";
import { $fetch } from "ofetch";
export default async (req: Request) => {
const { next_run } = await req.json();
console.log("Scheduled function triggered. Next run:", next_run);
try {
// Call your Nuxt API endpoint
const response = await $fetch(`${process.env.URL}/api/tasks/example-task`, {
method: "POST",
body: {
secret: process.env.NUXT_TASK_SECRET,
},
});
if (!response.success) {
throw new Error("Task failed", { cause: response });
}
console.log("Task completed:", response);
} catch (error) {
console.error("Task failed:", {
cause: error,
});
}
};
// Run every hour
export const config: Config = {
schedule: "@hourly",
};
Add the required environment variables to your Netlify site:
NUXT_TASK_SECRET
- A secure random string to authenticate task requestsURL
- Your site URL (Netlify automatically provides this)You can set these in your Netlify dashboard under Site Settings > Environment Variables, or use the Netlify CLI:
# Generate a secure random string and set it as an environment variable in Netlify
netlify env:set NUXT_TASK_SECRET $(openssl rand -base64 25)
Update your Nuxt config to include the runtime config:
// nuxt.config.ts
export default defineNuxtConfig({
compatibilityDate: "2025-07-15",
devtools: { enabled: true },
runtimeConfig: {
taskSecret: null, // this will be set to the environment variable NUXT_TASK_SECRET under the hood
},
});
You can also configure your scheduled function in netlify.toml
(instead of in the scheduled function):
# netlify.toml
[functions."example-task"]
schedule = "@hourly"
Use curl to test the API endpoint directly:
curl -X POST <http://localhost:3000/api/tasks/example-task> \\
-H "Content-Type: application/json" \\
-d '{"secret":"your-secret-key"}'
or use the Nuxt Devtools:
screenshot of making the api request in the nuxt devtools
npx netlify dev
npx netlify functions:invoke example-task
Once deployed, you can view the scheduled function runs from the logs.
Here are some common cron expressions you can use:
// Every minute (for testing)
schedule: "* * * * *";
// Every hour
schedule: "@hourly";
// Every day at midnight UTC
schedule: "@daily";
// Every Monday at 9 AM UTC
schedule: "0 9 * * 1";
// Every first day of the month at 2 AM UTC
schedule: "0 2 1 * *";
Use crontab.guru to easily generate and test cron expressions.
You can view logs for your scheduled functions in the Netlify dashboard under Functions > [Your Function] > Function log.
Your Nuxt API endpoint logs will appear in your site's function logs (function name is usually server handler
) since Nuxt runs as a Netlify function.
When Netlify eventually supports Nitro's scheduled tasks, migration will be straightforward:
nuxt.config.ts
to use only Nitro's scheduledTasks
While we wait for native Nitro scheduled task support on Netlify, this workaround provides a robust solution that's actually quite elegant. It follows good separation of concerns, is easy to test, and provides a clear migration path for the future.
The combination of Netlify's scheduled functions with Nuxt API endpoints gives you all the power you need for automated tasks, with the added benefit of being able to manually trigger tasks through your API if needed.
If you’d like to learn more about running a robust Nuxt app, checkout the complete course Mastering Nuxt.
This workaround was tested with Nuxt 4.0.1 and Netlify Functions. As both platforms evolve, some details may change. Always refer to the official documentation for the latest information.
Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.
More than 200.000 users have already joined us. You are welcome too!
© All rights reserved. Made with ❤️ by BitterBrains, Inc.