Skip to content

Calendar

github-actions[bot] edited this page Oct 9, 2026 · 14 revisions

Calendar

The /calendar page — month and week views of your family's calendar, synced from Google + any local events you add by hand.

Calendar — month view with per-person color-coded events

TODO: week view variant

Sources of events

The calendar surface unifies events from:

  1. Google Calendar (two-way sync) — any calendar you've enabled in Settings → Google Calendar. Events created or edited in Kinboard are pushed back to Google; edits made on the Google side flow down at the next sync interval. Subject to Google's per-calendar permissions: a read-only subscribed calendar (holidays, sports schedules, etc.) stays read-only in Kinboard too.
  2. CalDAV (two-way sync) — any calendar connected in Settings → Calendar → CalDAV. Nextcloud, Radicale, Baïkal, Fastmail, iCloud and friends: username + password, events written back on save. The recommended option if you're not in the Google ecosystem.
  3. iCalendar (.ics) feeds (read-only) — any feed subscribed in Settings → ICS. iCloud Family Sharing, a school's published calendar, a club fixture list. Pulled on a schedule and never written back, because a published .ics URL is a snapshot, not an API.
  4. Local events — added directly in the Kinboard UI without selecting a Google, CalDAV or ICS calendar. Lives in public.events with no external link and never round-trips anywhere.
  5. Holidays — calendars marked with the "holidays" badge get rendered with the 🎉 indicator and slightly different styling.
  6. Waste-pickup calendars — calendars marked with the "waste pickup" badge are hidden from the calendar view and show up only on the waste widget. Avoids cluttering month view with weekly bin reminders.

Month view

The default. 35-42 cells, one per day in the month. Each day shows:

  • The day number (today highlighted with the monthly theme color)
  • Up to 3 event chips, color-coded per person
  • Holiday indicator if applicable
  • Birthday indicator if applicable

Tap a day → day-detail panel slides in showing all events + birthdays + holidays for that date.

Week view

7-column hourly grid for the active week, like a typical calendar app. Useful for time-bound planning. Time-of-day events show as colored blocks; all-day events float at the top.

Events happening at the same time split the day's width between them and sit side by side, widening again as soon as nothing is beside them. When a slot is split, the block shows just the title — hover (or tap) for the full time and location. The grid normally runs 6:00–22:00 and stretches automatically when the week contains anything earlier or later, so no event is ever hidden off-grid.

Per-person colors

Each event is color-coded by the person it's assigned to. This works the same for every provider — Google, CalDAV and .ics feeds all run through the same assignment, so a household with no Google account gets per-person colors exactly like one with. Assignment happens in three ways:

  1. Whole calendar → one person — set per calendar in Settings → Google Calendar, in Settings → CalDAV (pencil icon on the calendar) or in Settings → ICS when you add or edit a feed. Right when a calendar belongs to one person: a partner's iPhone calendar, a child's school feed.
  2. Per-event mapping rule — contains "Emma" / starts_with "Mama:" → assign to Emma. Right when one calendar carries several people's events. One set of rules applies to all providers, not just Google.
  3. Manual override — edit a local event and pick the person directly

The first two are checked in that order: a calendar assigned to a person stays assigned to them, and rules are only consulted for calendars left unassigned.

If no rule matches, the event is "family-wide" (gray accent).

Adding an event

The blue "+ New event" button opens a dialog:

  • Title (required)
  • All-day toggle
  • Start + end (date picker)
  • Person assignment (or "family")
  • Calendar — pick any of your Google calendars (event will round-trip to Google) or "Local only" (stays inside Kinboard)
  • Location (optional) — type three letters or more for place and address suggestions from OpenStreetMap, through Photon: shops, schools, doctors and landmarks as well as streets. Places near your weather location come first, and well-known places elsewhere still show, so "Eiffel Tower" finds Paris. With no weather location, suggestions come from the country of your holiday region, or the whole world when none is picked. Names come in the app's language (English, German or French; other languages get each place's local name), and each address is written the way its country writes it, led by the place's name when it has one. Kinboard makes the searches from its own server and keeps answers for a day, so a repeated search stays on your network
  • Notes

Events show up immediately for everyone in the family. If you picked a Google calendar, the event lands on Google within a few seconds and the next sync round-trip cements it. Edits and deletes also propagate.

Tap any existing event → edit dialog with the same fields. Delete via the trash icon — a confirmation dialog guards it, and an "Undo" toast appears afterward to restore the event exactly as it was.

Day-detail panel

Tapping any day in month view (or any block in week view) opens a side panel with:

  • Date + day name
  • Holiday card if applicable
  • Event list for that day, grouped by all-day → timed → ended
  • Birthday cards for anyone celebrating that day
  • Add-event quick action

The day panel is the main "interaction" surface — month/week views are glance surfaces.

Quick patterns

  • "What's on this week" → tap any day in the current week, then arrow through
  • "Find an event" → use the search field in the calendar's control row — see Event search & links below
  • "Add a recurring event" → not directly supported in the local-event editor. Add as a recurring event in Google Calendar and it'll sync in.

Event search & links

The control row above the month/week grid has a search field: type 2+ characters and it matches against every event's title, location, and description (case-insensitive), searching across your full event history — not just the visible month. Tap a result to jump straight to it.

Every event also has a shareable link that deep-links to its date and opens it directly (?event=<id>&date=<date>) — useful for pasting into a family chat ("here's the appointment"). Opening the link jumps the calendar to that date and opens the event dialog automatically; the back button closes the dialog instead of leaving the calendar.

Publish your calendar (ICS feed)

Settings → Data & backup has a Calendar feed (ICS) card. Tap Create feed link to generate a secret, read-only ICS URL for your family's events, then paste it into Google Calendar ("From URL"), Apple Calendar, or Outlook to subscribe — external calendar apps pull your Kinboard events on their own refresh schedule from there.

The link is a shared secret: anyone who has it can read your family's events (title, time, location), so treat it like a password. If it leaks, tap Rotate link on the same card — that invalidates the old URL and issues a new one, and you'll need to re-subscribe every calendar app that was using it.

Holidays

Public holidays follow the country and state picked under Settings → Holidays (or in the setup wizard's first step): 38 countries, with every German Land, Austrian Bundesland and Swiss canton, from the maintained date-holidays data. Holidays that apply to only part of a state or canton (Augsburg's Peace Festival, a Swiss commune's own days) aren't included; add them as school holidays, or mark a calendar that has them as holidays. School holidays live on the same page: your own entries, any calendar marked as holidays, and — where OpenHolidays covers the country — school holidays fetched for your region.

School holidays from OpenHolidays

Once someone picks where the family lives, in a country the OpenHolidays API covers (every offered country except the UK and the US), Kinboard fetches that region's school holidays about once a week, and Refresh now fetches them straight away. The request goes to openholidaysapi.org and carries only the country, the region and the school type, never anything about the family. The switch on the same page turns it off for your family and removes the fetched holidays; your own entries and holiday calendars are never touched by the sync, on or off. The data is from OpenHolidays under the ODbL. Region, school-type and holiday names come in the family's language, so they match what the household reads on the calendar, whichever language a device's interface is in. That is the language last picked under Settings → Language; until someone picks one, it is the language of the holiday country: German for Germany, Austria, Liechtenstein and Switzerland (Switzerland's majority language, so a family in Geneva picks French there), French for France, Monaco, Luxembourg and Belgium, and English for everywhere else. Public-holiday names in the schedule, the family summary and for assistants follow the same rule.

The weekly fetch is a job of the scheduler (the cron container, ofelia), which reads its jobs from the webapp container's labels only when it starts. After upgrading to the release that brought the sync, recreate the scheduler as well as the webapp — docker compose up -d --no-deps --force-recreate cron with the -f files you normally use, or ./start.sh restart — or the weekly refresh never runs. The Diun self-update and ./start.sh up do this themselves from that release on. The job runs every 24 hours counted from the scheduler's start, so the first run comes up to a day later.

Self-hosters can turn the sync off for the whole install with SCHOOL_HOLIDAY_SYNC=off in webapp/docker/.env (then docker compose up -d webapp). Nothing is fetched after that and the switch and region controls disappear, but school holidays fetched before it stay and keep counting as no school: they are still correct, and a failed fetch keeps them the same way. Settings → Holidays still lists them, with OpenHolidays' attribution, and offers to remove them; they also go when the family picks a different region.

Known gaps in OpenHolidays' data, not Kinboard's: Zürich (CH-ZH) has no Sportferien, and the Graubünden Region Maloja (CH-GR-ML) has only its autumn and Christmas breaks. Add the missing weeks as your own school holidays.

Calendar mapping rule editor

Hidden under Settings → Google Calendar. Useful when:

  • One shared family calendar, want each person's events colored differently → use rules to auto-assign by title pattern
  • Subscribed to a calendar that mixes events for multiple people (school, sports club) → rules split it

The rules are family-wide and are applied to Google, CalDAV and .ics events alike — the editor lives on the Google page for historical reasons, not because the rules are a Google feature.

Known limitation. That editor is only rendered once a Google account is connected, so a household using only CalDAV or .ics feeds currently has no way to create or edit rules, even though rules it already has are still applied at sync time. Until that is fixed, assign the whole calendar to a person instead (option 1 above), which works everywhere.

Full match-type reference and the Test button: see Google-Calendar → Mapping rules.

iCalendar (.ics) feeds

Read-only .ics feeds shipped in v1.0.19 and live alongside Google Calendar. The two providers can coexist — a typical setup is "Google for the family's main shared calendar (read/write) plus iCloud Family Sharing as an .ics feed for the partner's iPhone calendar (read-only)".

Add a feed at /settings/ics:

  1. Paste the feed URL. webcal:// links from iCloud and Google's "secret iCal address" are auto-rewritten to https://.
  2. Click Test — Kinboard fetches the feed and reports the event count + the first event's title so you can sanity-check before saving.
  3. Set a name, color, and (optionally) the family member it represents.
  4. Click Sync now any time to refresh; otherwise the feed re-syncs every 30 minutes via cron. ETag conditional GETs mean a 304 from the upstream is a no-op (no re-parse).

Recurring events are expanded server-side and capped at 200 instances per calendar. The sync window is −30 days to +60 days from "now" so multi-year feeds don't bloat the events table. Events present in a previous fetch but absent from the current one are removed.

ICS sources Kinboard handles cleanly today: iCloud Family Sharing, Google's "secret iCal address", Outlook/Office 365 calendar publishing, most CalDAV providers (via their published .ics URL), school district calendars, sports league schedules.

If the calendar you want is served over CalDAV, prefer CalDAV over its published .ics URL — you get authentication and write access instead of an anonymous read-only snapshot.

CalDAV

Full two-way sync with any CalDAV server: Nextcloud, Radicale, Baïkal, SOGo, Synology, Fastmail, iCloud. Connect once with a username and password, pick which calendars to sync, and events created or edited in Kinboard are written straight back to the server. Conflicting edits are caught with ETag preconditions rather than silently overwritten.

See CalDAV for setup, provider URLs and troubleshooting.

What's not supported

  • Attendees / invites. Google events show their attendees in the day panel as read-only text; you can't RSVP or invite people from Kinboard, and CalDAV writes carry no ATTENDEE lines.
  • Editing read-only subscribed calendars — if the provider itself marks the calendar as read-only (someone else's calendar shared with you, public holiday calendars, etc.), Kinboard can't write to it either. CalDAV calendars in that state get a "Read-only" badge.
  • Writing to ICS feeds. ICS support is read-only by design — feeds are published-only URLs with no write semantics. Use CalDAV or Google Calendar for editable family events.
  • Editing one occurrence of a repeating event. A series is a single resource on the server; Kinboard edits whole events, so it declines the edit rather than rewriting every occurrence. Change it in your calendar app instead.

Related

  • Google-Calendar — connect Google + per-event mapping rules
  • Birthdays — birthdays appear in the calendar; managed separately
  • Themes — date formatting per locale + the holiday country picker
  • Self-hosting — the JSON export vs. the ICS feed, and when to use each

Clone this wiki locally