Nuxt Calendar Template with Drag and Drop Events

Create a Nuxt UI calendar with date-based views, drag-and-drop scheduling, event editing, optimistic updates, and offline changes.

Nuxt Calendar Template is a Nuxt application template that builds an Apple-inspired calendar with day, week, and month views. It includes the calendar screens, event interactions, state management, and Nitro endpoints needed for scheduling apps, planning tools, and calendar-based dashboards.

Events can be created directly on the grid, moved between dates, resized in 15-minute increments, and edited from an anchored popover. Multiple calendars, keyboard controls, infinite month scrolling, optimistic updates, offline mutation replay, light and dark themes, and responsive views are already part of the application.

Features

  • Switches between date-based day, week, and month calendar views.
  • Moves events between dates and resizes timed events in 15-minute increments.
  • Creates timed or all-day events directly from the calendar grid.
  • Loads additional six-week ranges during continuous month scrolling.
  • Applies event edits immediately and rolls failed server mutations back.
  • Queues event mutations during network failures and replays them after reconnection.
  • Stores visibility choices for multiple color-coded calendars in a cookie.
  • Adds keyboard navigation, dark mode, a three-day mobile layout, and a sidebar slideover.

Use Cases

  • Build a team planning calendar where meetings and project events move directly between dates and time slots.
  • Add appointment management to an internal tool that needs day and week scheduling screens.
  • Create a personal productivity app with independent work, personal, and project calendars.
  • Use date-specific URLs in scheduling dashboards where users need bookmarkable day, week, and month states.

How To Use It

Create a New Project

Nuxt exposes the calendar through its template option:

npm create nuxt@latest -- -t ui/calendar

Clone the Repository

Use the repository directly when you want to inspect or modify the complete template source first:

git clone https://github.com/nuxt-ui-templates/calendar.git
cd calendar
pnpm install

Start the development server:

pnpm dev

The local app runs at http://localhost:3000.

For a production build:

pnpm build
pnpm preview

Calendar Views and URLs

Each calendar view has its own date-based URL:

/day/2026-08-21
/week/2026-08-21
/month/2026-08-21

The dynamic app/pages/[view]/[date].vue page accepts day, week, or month and validates the date parameter. Invalid view names and dates return a 404.

The month screen keeps a continuous scrolling calendar. As new month ranges move into view, the URL and document title follow the visible date.

Keyboard shortcuts provide another navigation path:

KeyAction
tGo to today
dOpen day view
wOpen week view
mOpen month view
nCreate a new event
Arrow keysNavigate calendar dates

Creating and Editing Events

Double-click a calendar position or drag across the time grid to create a timed event. Dragging across dates creates an all-day event. The event form opens in a popover anchored to the new event.

Existing events use the same editor. Drag an event to another date or time to reschedule it. Drag its bottom edge to change its duration. Timed drag operations snap to 15-minute intervals.

The shared event contract contains the fields used by the calendar components and Nitro handlers:

FieldTypeRequired
idstringYes
calendarIdstringYes
titlestringYes
descriptionstringNo
startstringYes
endstringYes
allDaybooleanNo

The Calendar type stores an id, name, and Nuxt UI color value.

Event API

The application already has Nitro endpoints for reading and changing calendar data:

MethodEndpointTask
GET/api/calendarsRead available calendars
GET/api/events?start=...&end=...Read events overlapping a date range
POST/api/eventsCreate an event
PATCH/api/events/:idCreate or update an event by ID
DELETE/api/events/:idDelete an event

GET /api/events validates the local datetime values and rejects ranges longer than 90 days.

The PATCH endpoint uses upsert behavior and DELETE is idempotent. Keep those request semantics when retaining the template’s offline replay logic.

Replace the Demo Event Store

The demo API stores events in server memory. Seed data is generated around the current week, and each visitor receives an editable session after the first mutation.

This storage model is intended for the public demo. Connect a persistent data store before using the template for real accounts, shared calendars, appointments, or project events.

The main server-side replacement point is:

server/utils/store.ts

Keep the existing event contract when you want the current calendar components and mutation logic to continue using the same payload shape.

A database implementation needs to handle these application operations:

  1. Return calendars available to the current account or workspace.
  2. Return events overlapping the requested start and end values.
  3. Create events with stable IDs.
  4. Update an existing event or accept the template’s PATCH upsert behavior.
  5. Process repeated DELETE requests safely when offline replay remains active.

Authentication and calendar ownership belong in the replacement server layer when calendar data is user-specific.

Optimistic Updates and Offline Changes

Create, update, and delete actions first modify a local event overlay. Successful server requests leave the optimistic result in place. Failed requests restore the affected event and trigger an error toast.

Network failures enter an in-memory mutation queue. The app checks connectivity and probes /api/calendars every five seconds after a transport failure. Queued requests replay in order after the server becomes reachable again.

The queue uses Nuxt state and does not create durable browser storage. Use persistent client storage when queued edits must survive a full page reload or browser restart.

Event Loading and Infinite Month Scrolling

Visible date ranges use keyed useFetch requests. Day and week navigation warms the previous and next ranges in the background.

Month view loads additional ranges while scrolling and reuses the same event range keys. The calendar merges those responses with optimistic local changes before rendering events.

This model maps naturally to APIs that query events by visible date range. Keep the /api/events response focused on events that overlap the requested window.

Alternatives and Related Resources

Nuxt UI Templates

Nuxt UI Templates

Ship faster with official Nuxt UI templates.

Leave a Reply

Your email address will not be published. Required fields are marked *