# โ
Nextcloud Tasks for Obsidian
Read, create, edit and complete your **Nextcloud Tasks** right inside a note โ over CalDAV, with no
copy of your data in the vault.
---
## ๐ง The one idea
**There is exactly one copy of every task, and it lives in Nextcloud.**
Other CalDAV plugins mirror markdown checkboxes into your notes and sync them โ two copies, forever
at risk of drifting apart. This one writes nothing to disk, not even a cache: it fetches, shows, and
writes your change straight back.
Plain JavaScript, no dependencies, no native code โ the same build runs on desktop and phone. ๐ฑ
---
## ๐ Install & set up
**From Obsidian:** *Settings โ Community plugins โ Browse*, search **Nextcloud Tasks**, install, enable.
**Manually:** drop `main.js`, `manifest.json` and `styles.css` from the
[latest release](https://github.com/JUNSKIx1/obsidian-nextcloud-tasks/releases/latest) into
`/.obsidian/plugins/nextcloud-tasks/`, then enable it under *Settings โ Community plugins*.
| # | Step | |
| --- | --- | --- |
| 1๏ธโฃ | **Make an app password** in Nextcloud โ *Settings โ Security* | Never your account password. It can be revoked on its own, and it is the only credential stored. |
| 2๏ธโฃ | **Fill in the settings** in Obsidian โ *Nextcloud Tasks* | Address is the base only: `https://cloud.example.com`, **not** `/remote.php/dav`. |
| 3๏ธโฃ | **Press Load** | Every list on your account appears. Tick the ones you want, rename the headings, pick colours, drag them into order. No list yet? **Create list** makes one on the server. |
| 4๏ธโฃ | **Set the refresh interval** | 5 minutes by default, **Never** if you prefer by hand. It only runs while a task list is on screen, so it costs nothing while you write. |
| 5๏ธโฃ | **Stuck? Press Test connection** | It reports every discovery step separately, so a failure points at one line instead of "could not connect". |
> ๐ท๏ธ **Any lists, any names.** No fixed categories, no folder convention. Each list you tick gets a
> heading, a colour and a short **key** โ the key is what a note refers to. Two lists or nine, in
> whatever order you drag them, is all the same to the plugin.
---
## ๐ Show tasks in a note
````markdown
```nextcloud-tasks
all
preview: 3
```
````
Every ticked list gets its own heading, even when empty. Past `preview:` rows, the heading grows an
arrow and the number it is holding back โ click to unfold, click to fold away.
Each list ends in a **blank row**: type a title, press Enter, and the task is on the
server. The two small buttons on that row set a due date and a priority first; Esc clears
it. Nothing you type is lost to a background refresh. โ๏ธ
Every line inside the block is optional:
| Line | What it does |
| --- | --- |
| `all` *(or an empty block)* | ๐ every ticked list, grouped by list โ **the default** |
| `list: errands` | ๐ one list only, by its key (`os:` still works in old notes) |
| `preview: 3` | ๐๏ธ rows per list before the **+n more** line; `preview: 0` shows everything |
| `limit: 8` | โ๏ธ hard ceiling on rows **in total**, applied before lists are split โ a busy list can eat it all, so `preview` is usually what you want |
| `due: today` | ๐
due today โ **overdue is always included**, or it would vanish silently |
| `due: week` | ๐๏ธ due within seven days, overdue included |
| `done: true` | โ๏ธ show completed tasks too |
| `title: Shopping` | ๐ท๏ธ your own heading for the panel |
German values (`due: heute`, `due: woche`, `done: ja`) are accepted, so a note keeps its meaning if
you switch Obsidian's language.
Rows sort the way you would triage them: **overdue first**, then by due date, undated last, ties
falling back to your list order. The panel header carries โ new task, ๐ new list and โป refresh.
---
## ๐ Working with a task
- **โ๏ธ Tick the box** to complete it โ written to the server immediately. The row stays on screen
with a line through it until you leave the note, so you can see what you did and undo a misclick.
- **โ๏ธ Click the title** to edit title, due date and priority. Only what you actually changed is
written, so a repeat rule, reminder, description or subtask the plugin doesn't show stays
untouched. *(Moving a task to another list happens in Nextcloud, not here.)*
- **๐๏ธ Delete** lives in the same dialog, behind one confirmation.
**Commands:** `New task` ยท `Refresh tasks` ยท `Test connection`.
---
## ๐ฑ On your phone
Add a CalDAV account with the same address, username and app password to your phone's built-in
reminders app: notifications and widgets without Obsidian running, and anything you tick there shows
up here on the next refresh. The plugin itself also runs in the Obsidian mobile app.
๐ **Languages:** English and German, following Obsidian's setting (or forced in the plugin settings).
---
## ๐ ๏ธ Development
```bash
npm install
npm run lint # eslint-plugin-obsidianmd โ the rules the directory review runs
npm test # core, render and bundle suites: no install, no network, no credentials
npm run build # bundles src/ into main.js
```
```bash
VAULT="/path/to/your/vault" bash scripts/deploy-to-vault.sh # deploy a local build
NC_URL=https://cloud.example.com NC_USER=alice NC_APP_PASSWORD=xxxxx \
node scripts/live-check.mjs # against a real server
```
`live-check` creates, reads, completes and deletes one test task: it proves the *server* speaks
CalDAV, not that your device passes the verbs through โ that's what **Test connection** is for.
โ ๏ธ `main.js` is generated. Edit `src/`, never the bundle.
๐ Design notes โ things that look like details and are not
- **Nothing is written to disk, not even as a cache.** The fetched list lives in memory for the
session. That is what makes "your tasks live in Nextcloud" literally true, and why there is no
file that can go stale.
- **Completing or editing rewrites the original calendar object line by line**, copying every other
byte through. Regenerating from a parsed model would silently drop `RRULE`, `VALARM`,
`CATEGORIES`, `RELATED-TO` and every `X-` property other clients wrote. The tests assert byte
identity of untouched lines, for both writers.
- **An edit sends only the fields you changed.** Leaving the date alone differs from clearing it:
the first never mentions `DUE`, so a task due at a particular time keeps that time when you fix a
typo in its title. The second removes the line.
- **Completion is judged in the client**, because three clients express it three ways: `STATUS`, a
bare `COMPLETED:`, or `PERCENT-COMPLETE:100`. A server-side filter that gets this wrong hides
tasks, which is worse than showing one too many.
- **Priority follows RFC 5545** โ 1 is most urgent, 0 unset: 1โ4 high, 5 medium, 6โ9 low, each with
a coloured flag. Flagging only the top band is what made an earlier version look broken.
- **Discovery walks the real chain**, `current-user-principal` โ `calendar-home-set` โ the
collections in it, instead of guessing `/remote.php/dav/calendars//`. Fifteen lines, and a
whole class of username-casing bug disappears.
- **XML is read without caring about namespace prefixes.** Nextcloud's `d:` and `cal:` are not
contractual.
- **If `REPORT` is refused**, the client falls back to `PROPFIND` plus one `GET` per object and
remembers that for the session, so a platform blocking the verb still works.
- **Everything goes through `requestUrl`**, which bypasses CORS and works on iOS.
---
๐ MIT โ see [LICENSE](LICENSE).