← All guides

Build a reminder scheduling UI in React

Convert local time and repeat controls into a cron expression and timezone. Copy an MIT React component into your app.

Choose a local time

Your user chooses weekdays at 09:00 in New York. Send 0 9 * * 1-5 and America/New_York to your backend. Keep the local time and timezone together so you can show and edit the same preference later.

Schedule to send to your backend:

{
  "cron_expression": "0 9 * * 1-5",
  "timezone": "America/New_York"
}

Copy the React component

The MIT schedule picker example contains schedule-picker.tsx and schedule.ts. Copy both files into your app. It supports daily, weekday, and weekly schedules and has no scheduler dependency.

Use it inside a form with an initial schedule. The component calls onChange after a valid edit; keep a Save button in your form so each keystroke does not create a schedule.

"use client";
import { useState } from "react";
import { SchedulePicker } from "./schedule-picker";
import { buildSchedule } from "./schedule";

export function ReminderForm() {
  const [schedule, setSchedule] = useState(() => buildSchedule({
    cadence: "weekdays", time: "09:00", timezone: "America/New_York",
  }));
  return (
    <>
      <SchedulePicker
        defaultTimezone={schedule.timezone}
        onChange={setSchedule}
      />
      <pre>{JSON.stringify(schedule, null, 2)}</pre>
    </>
  );
}

The converter validates the time and timezone. While the user edits an invalid value, the picker shows an error and retains the last valid schedule in the parent. Disable your form's save action while input is invalid, or validate the current fields again on submit.

Save through an authenticated route

Submit the schedule and reminder ID to your backend. Check that the signed-in user owns that reminder, validate the inputs on the server, then create or update its cron. Keep your Cuey API key and callback URL on the server.

import { cuey } from "cuey";

// After authentication, ownership checks, and input validation:
const cron = await cuey.repeat({
  webhook_url: "https://your.app/api/remind",
  method: "POST",
  cron_expression: "0 9 * * 1-5",
  timezone: "America/New_York",
  headers: { Authorization: `Bearer ${process.env.REMINDER_SECRET}` },
  payload: { reminder_id: "reminder_123" },
});
// Save cron.id with the reminder.

Follow the recurring schedule guide for edits, pausing, and deletion. Cuey replaces the cron configuration on update, so include the delivery fields each time.

Check timezone changes

Ask the user whether reminders should follow their home timezone or their current location. Store an IANA name such as Europe/London; a fixed UTC offset loses daylight-saving rules. Decide what your app should do with a skipped or repeated local time, and test that behaviour with your scheduler.

Use the cron preview to inspect upcoming runs. For email delivery, read the Next.js and Resend guide.

Schedule your first request

The first 10,000 events each month are free. Additional events cost $0.0001 each. See pricing or read the API documentation.

Get your API key ↗