rosswang713 downloadsBidirectional Vault Nextcloud sync with smart/force modes, chunked uploads, and built-in exclusion of hidden files and dotfolders (the YANC fork).
[!NOTE] Nextcloud sync YANC is an independent Obsidian plugin, originally based on obsidian-nextcloudsync by Daisuke ITO (MIT). It has been developed independently since 1.2.2: mobile/Android login resilience, a two-stage connection test, sync session history, folder/extension exclusion rules, sync-only folder whitelists, lazy attachment sync, and mass-delete safety breakers.
It publishes under its own plugin id,
nextcloud-sync-yanc, separate from the originalnextcloud-sync. If you installed a copy before 1.1.1 under the oldnextcloud-syncid, uninstall that copy first, or the two will fight over the same folder.Report issues here: yanqingwang/obsidian-nextcloud-sync-yanc
Good news for anyone working across multiple desktops and mobile devices.
The only cost you pay is waiting for the initial Vault index to complete on first install. From that moment on, you get:
Bidirectional sync between your Obsidian Vault and Nextcloud — built specifically for Nextcloud, not just generic WebDAV.
Most "WebDAV sync" plugins treat the server as a dumb file store: they compare modification times, copy files, and hope for the best. Nextcloud Sync instead talks to Nextcloud's own APIs (Capabilities, file IDs, checksums, versions, locking, Login Flow v2) to make syncing safe, fast, and frictionless — while still degrading gracefully to plain WebDAV when those APIs aren't available.
A Japanese translation is available at
README.ja.md.
This plugin is still young and some behaviour can be rough around the edges. Please tell me what you run into — it genuinely helps. Whether something broke, something's missing, or you just have a thought after using it, I'd love to hear from you (impressions especially make my day!):
⚠️ Heads-up: settings are being streamlined. Over the next few days, options with little practical value will be progressively removed so the plugin stays simple and hard to misconfigure. Sensible behaviour is derived automatically instead. If a setting you used to see is gone, that is intentional — the plugin now picks the right value for you.
display() fallback now renders the same rows the declarative API renders, so every setting — including Lazy attachment sync — is visible and editable again; the required Obsidian version drops back to 1.11.4. On Obsidian 1.13+ nothing changes._draft.md-style files and _inbox/-style folders. Both are OFF by default, because underscore names are often real content.js, exe, *.dmg) keeps matching files out of the sync in both directions, with an optional Delete excluded types from server cleanup.For the full version history of every release, see the changelog.
| Concern | Generic WebDAV plugin | Nextcloud Sync |
|---|---|---|
| Change detection | Modification time (clock-skew prone, false re-uploads) | Content hash + Nextcloud sync-token / checksums capability for true differential sync |
| Rename / move | Delete + re-create (loses history, re-downloads everywhere) | File-ID (OC-FileId) tracking — a rename stays a rename on every device, history preserved |
| Deletion safety | Hard delete | Routed through the Nextcloud trashbin — recoverable, never an irreversible DELETE |
| Setup | Manual app-password copy & paste | Login Flow v2 — approve in the browser, credentials are issued and stored automatically |
| Large files | Skipped or fail on a single PUT |
Chunked upload — split, resumable, checksum-verified |
| Concurrent edits | Hope nobody else writes | Optimistic concurrency — every update carries an If-Match precondition, so a remote changed by another device is turned into a conflict (no lost update) without locking round trips |
| Recovery from mistakes | None (your copy is all you have) | Server version history — browse and restore any past revision from inside Obsidian |
| Server unavailable | Cryptic errors / partial writes | Maintenance-mode detection (/status.php) and parsed Nextcloud error messages |
| Capability awareness | None | Capabilities probing (/ocs/.../capabilities) — features light up only when the server supports them (Progressive Enhancement) |
If you point it at a non-Nextcloud WebDAV server, it automatically disables the Nextcloud-only features and falls back to standard recursive WebDAV sync — so it still works, just without the extras.
.trash / permanently delete) rather than forcing one behavior; folders and files outside the Vault's tracked notes (e.g. config-folder files) are handled too..git, and for large media you keep device-local. Matching is a folder-prefix match at a folder boundary, so Attachments excludes Attachments/ and everything under it but not Attachments-old. Add or remove entries under Settings → Excluded folders (type a path or use the folder picker). Dotfolders (.git, the config-folder plugins/, the plugin's own state) are already excluded automatically; this list is an additive layer on top.js, exe, *.dmg keeps matching files out of the sync in both directions (case-insensitive suffix match). Optionally, Delete excluded types from server also removes them from the server so they stop accumulating; local copies are never touched._draft.md-style files and _inbox/-style folders (OFF by default, since underscore names are often real content).0 for manual-only), plus a Sync now command.nextcloud-debug_<device>.txt, written to the vault root and named per device so multiple devices never overwrite one another (another device's log can even sync into this vault for side-by-side comparison). Each line is timestamped and carries the plugin version, and a full settings snapshot is written when logging turns on; every sync operation is recorded. Useful for troubleshooting on mobile where there's no console. Note: Obsidian hides .txt files unless Settings → Files & Links → Detect all file extensions is on, and they never appear in Quick Switcher — you can also open the file from your OS or Nextcloud. Turn logging off and delete the file when finished.reconcile-text / diff3, the default for auto merge files) integrates edits in different regions, including YAML frontmatter when the two sides changed non-overlapping lines. A text conflict is written as conflict markers; a non-text file is left untouched and flagged (never corrupted with markers).#conflict tag search).data.json.maxFileSizeMB cap guards memory in both directions — oversized files are skipped on upload and on download (the download size is taken from the server's PROPFIND, so the body is never fetched).If-Match precondition: a remote changed by another client returns 412, which the engine turns into a conflict (download remote + resolve). This replaces per-file WebDAV LOCK/UNLOCK round trips, so server-side file locking is intentionally never used.Mobile is supported, with a few platform-aware differences (desktop behaviour is unchanged):
0 for unlimited) to avoid out-of-memory crashes; skips are reported.1.11.4 or later. Desktop (Electron) and mobile (iOS / Android) are supported. On Obsidian 1.13.0+ the settings tab uses Obsidian's declarative settings API, which is what makes the plugin's settings findable in Obsidian's own settings search; on older engines (including the HarmonyOS ports, which ship 1.12) a display() fallback renders the same rows — the settings screen is never empty.33) or later is recommended for the Nextcloud-specific features. Older Nextcloud servers are no longer blocked — they still connect and sync, but the settings screen shows a recommendation banner and some features may degrade. Plain WebDAV servers fall back to core sync.Search for Nextcloud sync YANC in Settings → Community plugins → Browse.
main.js, manifest.json, styles.css.<YourVault>/.obsidian/plugins/nextcloud-sync-yanc/.
The folder name must be nextcloud-sync-yanc — it is the manifest id, and Obsidian will not
load a plugin whose folder name does not match.On Android, Obsidian has no "install from zip" option, so copy the three files into the vault's
.obsidian/plugins/nextcloud-sync-yanc/ folder over a file manager or sync client, then restart
Obsidian.
Install BRAT, then add this repository
(yanqingwang/obsidian-nextcloud-sync-yanc) as a beta plugin. BRAT installs from the latest release
and notifies you when a newer one is published.
The original plugin by Daisuke ITO is listed separately as Nextcloud Sync (siosig/obsidian-nextcloudsync). Installing that one gives you upstream 1.0.8, which does not include this fork's Android login resilience or connection test. The two use different plugin ids, so both can be installed at once.
main.js, manifest.json, and styles.css from the latest
GitHub Release.<YourVault>/.obsidian/plugins/nextcloud-sync-yanc/.https://<host>/remote.php/dav/files/<user>/,
not just the host. Entering only https://cloud.example.com fails with HTTP 405. <user> is your
Nextcloud user ID (usually not your email). You may append a subfolder (e.g. .../<user>/Documents) to
sync there instead of at the account root.Your Vault is synced into a folder named after the Vault on the Nextcloud side, keeping multiple Vaults cleanly separated.
The plugin syncs a Vault that is already open in Obsidian — it does not open a Nextcloud folder as a Vault. So a second device does not browse to the remote; it starts with its own Vault that happens to carry the same name:
My Notes and my notes are two separate folders on the server.To confirm both devices agree, compare the read-only Sync target (WebDAV) row in Settings → Nextcloud Sync: it shows the effective remote path (Server URL plus Vault folder). If that line reads identically on both devices, they point at the same place.
On Obsidian mobile, this means Create new vault — not Set up Obsidian Sync, which is Obsidian's own paid service, and not Open folder as vault, which only opens a folder already present in the phone's storage.
If the Vault on the second device is not empty, back it up first. The first sync reconciles both sides, so notes already there are uploaded as well as downloaded.
Can I use a scoped Nextcloud Public Link Share instead of granting full account access?
Yes. If you'd rather not hand the plugin an app password with full account access, you can share a single directory as a Public Link Share with username/password on the Nextcloud side, then point the plugin at it:
https://<host>/public.php/webdav//s/)One point of confusion here: when you click Link… to store the app password, you're asked for an ID and a value. The ID is a local storage key inside Obsidian's encrypted Secret Storage — it is never sent to the server, so it can be anything (e.g. default); it's restricted to lowercase letters/digits/dashes because that's an Obsidian platform constraint, not something this plugin controls. The actual share password goes in the value, which accepts any characters. Put the share token in the Username field, not in the ID field.
Note: version history / restore and chunked upload are optional convenience features layered on top of core sync; they haven't been verified against Public Link Share endpoints and may not work there. Basic upload/download sync is unaffected.
I got HTTP 423 (PUT) or HTTP 423 (DELETE) — what does that mean?
A 423 means the file is locked on the Nextcloud server side, not by this plugin. It can happen either from one of the four force-resolve choices in Sync Status (Use remote / Use local / Latest modified / Biggest size) or during a normal background sync. A common cause is a lock left behind by the Nextcloud Text web editor: opening a file there takes out a lock with no timeout, and if the browser tab or session ends uncleanly the lock can leak and stay in place indefinitely. It can also be a genuine lock held by someone actively editing the same file elsewhere.
When the server reports a lock owner, the plugin's notice and Sync Status result listing now show that owner instead of the previous bare "HTTP 423 (PUT)" message with no explanation.
This plugin does not resolve the lock automatically and has no in-app "unlock" action — releasing a lock without knowing its origin risks overwriting someone else's in-progress edit. To resolve it, close the session or tab holding the lock (e.g. the Nextcloud Text editor tab), or ask a server administrator to clear it if it's genuinely leaked or stuck.
One power feature depends on a server-side Nextcloud app. It only needs to be enabled once by a Nextcloud administrator. The plugin detects it through the capabilities API — if the app is missing, the feature simply stays inactive (no error).
Lost-update safety needs no setting. The plugin always sends an
If-Matchprecondition on upload, so a file changed on the server by another client is turned into a conflict instead of being silently overwritten — there is no File Locking toggle to configure.
Server-side versions come from the built-in Versions app (app ID files_versions), which is enabled by default on a standard Nextcloud install — usually nothing to do.
sudo -u www-data php /var/www/nextcloud/occ app:enable files_versions
versions_retention_obligation in config.php).These are not strictly required, but on self-hosted instances they often need attention for smooth, reliable syncing. All are server-side (admin) settings.
trusted_domains in config.php, otherwise the server rejects requests. Add your domain/IP if needed.overwriteprotocol => 'https', overwritehost, overwrite.cli.url, and trusted_proxies correctly. If these are wrong, the URLs returned by Login Flow v2 (and downloads) can point to the wrong scheme/host and fail. Always use an https:// server URL in the plugin.upload_max_filesize and post_max_size, and the web-server body limit (nginx client_max_body_size, e.g. 0 or a large value). Chunked upload sends small chunks, but the final assembly and very large files still hit these limits.max_execution_time and php-fpm / web-server timeouts (e.g. nginx fastcgi_read_timeout). The plugin uses a fixed 30-second network timeout.auth.bruteforce.protection.enabled/the IP allow-list in config.php.oc:checksums (SHA-256) for change detection and automatically falls back to ETag when they aren't present, so no configuration is required; leaving Nextcloud's default checksum support enabled gives the most accurate detection.The settings screen is intentionally minimal: only Server URL, sign-in, Sync folder, Sync interval, Wi-Fi only, Excluded folders, the config-folder toggles, and an Enable logging switch are shown. Every other option was removed and is now a fixed value or derived automatically from your platform. They are documented here so you always know what the plugin is doing.
These are the options you can change. Most start the same on both platforms; a few differ on first run.
| Setting | Desktop | Mobile |
|---|---|---|
| Server URL / Username / App password | empty | empty |
| Sync interval | 15 min | 15 min (disabled — use Sync now or Sync on startup) |
| Sync on Wi-Fi only | off | on |
| Sync config folder (master) | off | off |
| └ Bookmarks / Other settings | on / on | on / on |
| Auto merge file types | md, txt, cpp, py, c, h, hpp, rs, go, ts, js, java, sh | same |
| Auto merge file strategy | Merge | Merge |
| Other file strategy | Latest modified | Latest modified |
| Enable logging | off | off |
| Excluded folders | empty | empty |
The config-folder category toggles (Bookmarks, Other settings) only take effect once the master Sync config folder is on.
| Setting | Value |
|---|---|
| Network timeout | 30 seconds |
| Startup sync delay | 1 second (0 = no startup sync) |
| Chunk threshold | 50 MB (desktop) / 20 MB (mobile) |
| Chunked upload | on |
| Bulk upload | on |
| File locking | off — If-Match preconditions provide lost-update safety |
| Max conflict regions | 0 (no region-count fallback) |
| Compare with remote | on (desktop and mobile) |
| Log folder | vault root |
| Device name | auto (<platform>-<deviceId>) |
| Setting | Desktop | Mobile |
|---|---|---|
| Sync on file change | on | off |
| Maximum file size | unlimited (0) |
20 MB |
| Network concurrency | auto from RAM (≈ 16 on 8 GB+) | ≈ 3 |
On connect, the plugin probes /status.php (maintenance mode) and /ocs/v1.php/cloud/capabilities to learn the server version and which features (checksums, files locking, …) are available. It then maintains a per-device state database — a snapshot of every file's path, content hash, and remote file ID at the last successful sync. Each sync diffs the current state against that snapshot and the server's sync-token, transferring only what changed. Every Nextcloud-specific behavior is gated behind capability detection, so the same plugin works against a full Nextcloud Hub and a bare WebDAV server alike (Progressive Enhancement).
Sync correctness is guarded by an extensive automated test suite: hundreds of fast pure-logic tests (run on every change) plus live end-to-end suites that drive two devices against a real Nextcloud server, including exhaustive option-combination matrices for conflict resolution and multi-device convergence.
These tests exist specifically to prevent sync-inconsistency states — data loss, endless re-uploading/re-downloading, a remote change that never reaches the local copy, or a local change that never reaches the remote. Even so, no test suite can cover every possible case, and unintended behavior can never be entirely ruled out. If you ever run into such a situation, please don't hesitate to open an issue — it will be addressed as quickly as possible.
data.json.requestUrl API..obsidian/) is excluded from sync by default — only your notes and other vault files are synced. You can opt in to syncing selected parts of it via Sync config folder (see below). Community plugins (.obsidian/plugins/) and the plugin's own sync-state database are never synced, regardless of settings — they hold executable code and device-specific state, which is unsafe to overwrite across devices..obsidian/ config across devices, chosen with two toggles: Bookmarks and Other settings (appearance, themes & snippets, hotkeys, and core-plugin settings). Community plugins and the plugin's own sync-state database are never synced (executable code / device-specific state). A synced change to core-plugin settings may require an Obsidian restart on the other device to take effect.Bug reports and ideas are genuinely welcome. The plugin is still maturing, and most of what has been fixed so far came from someone taking the time to describe what they saw.
Please open an issue or a discussion rather than sending a pull request. A PR that arrives unannounced is read as input and valued as such, but it is unlikely to be merged as it stands. This is a single-maintainer project with a deliberate design policy — user-facing options are kept deliberately few, and behaviour is pinned by a specification that the test suite checks against — so whether a change fits depends on decisions that are not visible from the code alone, and on what is already in flight. Judging that after the code is written is harder than agreeing on the approach beforehand, and it wastes your effort whenever the answer turns out to be no. Describe what you want to change and why; if it fits, the approach can be settled before you write anything.
npm install
npm run dev # watch and rebuild main.js
npm run build # type-check and create the production bundle
npm test # fast pure-logic test suites
Release assets are main.js, manifest.json, and styles.css.
When reporting a problem, please include your Obsidian version, plugin version, and a screenshot or a short description of the expected result.
MIT — originally by Daisuke ITO; maintained as Nextcloud sync YANC by yanqingwang.
Obsidian 与 Nextcloud 之间的双向同步插件,专门为 Nextcloud 打造,而不只是一个通用 WebDAV 客户端。
多数「WebDAV 同步」插件只把服务器当成一个文件仓库:比较修改时间、复制文件,然后祈祷不出问题。本插件会调用 Nextcloud 自己的 API(Capabilities、文件 ID、校验和、版本、锁定、Login Flow v2),让同步更安全、更快、更省心;当服务器不支持这些能力时,会自动降级为标准 WebDAV 同步。
本插件是独立项目,最初基于 Daisuke ITO 的 obsidian-nextcloudsync(MIT)。自 1.2.2 起独立发展,插件 id 为
nextcloud-sync-yanc。如果你在 1.1.1 之前安装过旧 idnextcloud-sync的版本,请先卸载旧版,否则两份插件会争抢同一个目录。
核心同步
js, exe, *.dmg)、仅在指定文件夹同步、按下划线前缀排除(默认关闭)。冲突安全(不丢内容)
If-Match 前置条件:别处改过的远端文件会变成冲突,而不是被静默覆盖。Nextcloud 增强
data.json。1.11.4 或更高版本;支持桌面端(Electron)与移动端(iOS / Android)。在 Obsidian 1.13.0+ 上设置页使用声明式设置 API(这样插件设置才能被 Obsidian 自带的设置搜索检索到);在更老的引擎上(包括搭载 1.12 的鸿蒙移植版),由 display() 回退渲染同样的设置行——设置页不会再空白。33)或更高版本;更老的 Nextcloud 仍可连接并同步,但部分能力会降级。标准 WebDAV 服务器可回退到核心同步。在 设置 → 第三方插件 → 浏览 中搜索 Nextcloud sync YANC。
main.js、manifest.json、styles.css。<你的库>/.obsidian/plugins/nextcloud-sync-yanc/。文件夹名必须是 nextcloud-sync-yanc(即 manifest 的 id),否则 Obsidian 不会加载。Android 没有「从 zip 安装」,用文件管理器或同步客户端把三个文件放入上述目录后重启 Obsidian 即可。
安装 BRAT,把仓库 yanqingwang/obsidian-nextcloud-sync-yanc 添加为 beta 插件。
https://<主机>/remote.php/dav/files/<用户名>/,不能只填主机名(只填 https://cloud.example.com 会报 HTTP 405)。可以追加子文件夹,把同步范围限制在某个目录。库会被同步到 Nextcloud 上以库名命名的文件夹。
可在 设置 → Nextcloud Sync 的 同步目标(WebDAV) 只读行核对两台设备是否指向同一位置。请先备份新设备上已有的内容。
能否用受限的公开链接分享代替完整账号的应用密码?
可以。在 Nextcloud 上把单个目录创建为带用户名/密码的公开链接分享,然后:
https://<主机>/public.php/webdav//s/ 之后的部分)点击 关联… 保存应用密码时填写的「ID」只是 Obsidian 本地密钥库中的键名,永远不会发给服务器,可以随意填写(如 default);真正的分享密码填在「值」里。
出现 HTTP 423 是什么原因?
423 表示文件在 Nextcloud 服务器端被锁定,不是插件加的锁。常见原因是 Nextcloud Text 网页编辑器留下的锁(没有超时,异常关闭标签页后可能一直存在),也可能是别人正在编辑同一文件。插件不会自动解锁(盲目解锁可能覆盖他人正在进行的编辑):请关闭持有锁的会话,或让管理员清理。
设置页刻意保持精简:只显示服务器地址、登录、同步文件夹、同步间隔、仅 Wi-Fi、排除文件夹、配置文件夹开关和日志开关,其余选项为固定值或按平台自动推导。
| 设置 | 桌面端 | 移动端 |
|---|---|---|
| 同步间隔 | 15 分钟 | 15 分钟(禁用,用「立即同步」或「启动时同步」) |
| 仅 Wi-Fi 同步 | 关 | 开 |
| 同步配置文件夹 | 关 | 关 |
| 可自动合并的文件类型 | md, txt, cpp, py, c, h, hpp, rs, go, ts, js, java, sh | 同上 |
| 可自动合并文件策略 | 合并 | 合并 |
| 其他文件策略 | 较新者优先 | 较新者优先 |
| 启用日志 | 关 | 关 |
固定值:网络超时 30 秒、分块阈值 50 MB(桌面)/ 20 MB(移动)、分块上传开启;丢失更新保护由 If-Match 提供,不使用文件锁定。
按平台推导:文件变更时同步(桌面开 / 移动关)、最大文件大小(桌面不限 / 移动 20 MB)、网络并发(按可用内存自动推导,约 16 / 8 / 4 / 3)。
data.json;从不使用也不存储主密码。.obsidian/ 默认不同步;社区插件目录与插件自己的同步状态库永远不同步。npm install
npm run dev # 监听并重新构建 main.js
npm run build # 类型检查并生成生产构建
npm test # 快速纯逻辑测试
发布资源为 main.js、manifest.json 和 styles.css。
反馈问题时,请尽量附上 Obsidian 版本、插件版本,以及截图或预期结果说明。
MIT —— 原始作者 Daisuke ITO,现以 Nextcloud sync YANC 分支由 yanqingwang 维护。