hailan154 downloadsKeep Markdown image links, local mirrors, and S3/R2 objects aligned with directory policies and audits.
Keep Markdown image links, a local mirror inside your vault, and S3-compatible cloud objects aligned.
Chinese guide · Latest release · Report an issue · Architecture changes
This guide describes version 1.8.0. It starts with the safest beginner setup, then explains directory policies, link modes, note moves, deletion safeguards, audits, and troubleshooting.
The cloud-to-local download command now opens a read-only preview, not an immediate overwrite operation. Review missing files, identical files, conflicts and failures, then choose Restore missing files only. Existing files are never overwritten by this command. Switching to Local also requires the exact cloud-key path, including its extension; a same-stem PNG is not a substitute for a missing WebP.
The preview reads full cloud image bodies and hashes actual bytes, even when metadata is absent. This consumes network traffic and may incur provider charges. Restore fetches missing bodies again and refuses them if their content changed since preview. Configuration changes, disabling the plugin, Cancel or closing the window stop further work at checkpoints; a dispatched request/write may finish. Completed files are retained.
Results are paginated (50 per page). Confirmation applies to all missing entries, not only the visible page. Copy full report includes private note paths and status/failure codes, but no configuration, credentials or raw service error responses. This command only restores keys referenced by eligible staging/managed notes; it is not a bucket backup, path repair or conflict overwrite tool. See scope, validation and limitations.
#, literal percent signs, nested parentheses and optional Markdown titles are handled without double decoding.See the implementation, validation and remaining roadmap. The large-vault audit redesign and Excalidraw integration are not included in this patch.
S3 Image Sync Pro manages three related forms of each supported image:
Its central path rule is:
cloud object key
= path relative to the local mirror root
= image path associated with the note
For example, with a local mirror root of 98 cloudflareR2:
Note:
06 Archive/Projects/Example.md
Cloud object key:
06 Archive/Projects/Example/photo.webp
Local mirror:
98 cloudflareR2/06 Archive/Projects/Example/photo.webp
Every successful upload keeps both the cloud object and the exact local mirror, including in Cloud mode. Link mode selects the written link, but also currently controls background adoption: ordinary local images are adopted automatically in Cloud mode, not in Local mode. Paste/drop and manual upload remain separate triggers.
Read these points before using the plugin on an existing vault:
ignore and verify directory modes do not rewrite notes or move objects.getLanguage() API).No separate user account is required by this plugin. It connects directly to the storage service configured by the user.
After the current release is accepted into the community directory:
Open the latest GitHub release.
Download main.js, manifest.json, and styles.css.
Create this folder inside the vault:
<vault>/.obsidian/plugins/s-three-image-sync-pro/
Put the three downloaded files in that folder.
Restart Obsidian and enable S3 Image Sync Pro under Community plugins.
Do not copy data.json between people or publish it. That file can contain storage credentials and private configuration.
data.json.main.js, manifest.json, and styles.css with files from the new release.data.json.Open Settings → S3 Image Sync Pro and configure the following groups.
Choose one of:
Enter the endpoint, region, bucket name, access key ID, and secret access key required by that provider.
Use credentials with only the permissions needed for the chosen features. A typical configuration needs object read, write, head, and list permissions. AWS S3 cleanup additionally needs narrowly scoped delete permission.
The plugin uses S3 credentials for background API operations. Markdown Cloud links, however, are loaded by the preview renderer like ordinary web images.
Configure a public URL prefix or custom domain if you want Cloud links to display directly. If the bucket is private, use Local link mode for display or provide a browser-readable delivery layer that matches your security requirements.
The default is:
98 cloudflareR2
This directory is inside the vault. Do not place it inside a managed note directory. Add an ignore policy for the mirror root so mirror files are not treated as notes to process.
Both modes still create or preserve the cloud object and exact local mirror after a successful upload.
New installations should use Directory policies. Legacy exclusion mode remains available for older configurations.
Add one rule per line:
staging: 01 Inbox
managed: 06 Archive
managed: 07 Work
verify: 04 Wiki
ignore: 03 Backup
ignore: 98 cloudflareR2
The longest matching path wins. Unmatched paths are ignored.
stagingUse this for temporary inboxes and incoming material.
managed can establish the final canonical path.managedUse this for stable, long-lived notes.
verifyUse this for content that should participate in audits without automatic mutation.
ignoreUse this for folders the plugin must not process.
A safe knowledge-management layout is:
01 Inbox -> staging
03 Backup -> ignore
04 Wiki -> verify
06 Archive -> managed
07 Work -> managed
98 cloudflareR2 -> ignore
This arrangement lets temporary content arrive without aggressive path movement. When another plugin, script, or agent moves a finished note into a managed directory, S3 Image Sync Pro can make the cloud and mirror paths follow the note.
For an eligible note, the plugin:
When Cloud mode is active, the plugin can adopt supported ordinary local image links after the note becomes stable. It uploads the image, creates the mirror, and rewrites the link only when the note is eligible under the directory policy.
Files created while Obsidian is closed are handled by the persistent startup catch-up queue when that feature is enabled. Failed items remain queued for a later run instead of being silently forgotten.
Behavior depends on the source and destination policies:
managed establishes the expected note-derived key.Deleting a note is different from moving it.
Keep cloud versioning or an independent backup for important buckets even when these safeguards are enabled.
Select the cloud icon in the left ribbon to access the main operations.
Find supported local or remote images in the active Markdown note and process only candidates allowed by its directory policy.
Switch supported links in the current note or selected scope between Cloud and Local modes. Switching to Cloud first confirms that the cloud object exists or uploads an eligible local source; it does not merely replace text with an unverified URL.
Read supported cloud objects through authenticated S3 GET requests and write them under the exact relative key inside the configured mirror root. This is useful before changing the default display mode to Local.
In 1.8.0, opening this command performs a read-only preview first. Review the paginated results, then select Restore missing files only. Identical files and conflicts are both preserved; there is no overwrite option. Changed cloud content, newly created local files and changed references are not silently accepted after preview. Cancel/close stops subsequent work, and Copy full report exports the result to your clipboard on request. See the safety and traffic notes above.
This is a mutation command for managed notes. It compares each recognized link with the key expected from the current note path, then performs the safe migration sequence.
Run a quick audit first. Do not use re-sync as a generic orphan cleaner.
This read-only check compares:
It reports path mismatches, missing cloud objects, missing mirrors, size mismatches, local-only files, cloud-only objects, protected objects, and entries that cannot be fully verified.
Deep audit adds SHA-256 verification for supported referenced mirrors and cloud objects that carry compatible plugin-written hash metadata. It is slower and downloads more data, so use it periodically or while investigating a discrepancy.
| Result | Meaning | Recommended action |
|---|---|---|
| Path mismatch | A managed note references a recognized key that differs from the key derived from its current path | Inspect the note and both keys, then use re-sync if the target is correct |
| Missing cloud | The note references a recognized cloud key that is not present | Restore from a verified mirror or backup; do not rewrite blindly |
| Missing local | A referenced object exists but the exact mirror is absent | Use the download-to-mirror command |
| Size mismatch | Cloud metadata and mirror size disagree | Run deep audit and compare backups |
| Hash mismatch | Available hashes disagree | Stop automatic replacement and choose the authoritative copy manually |
| Local orphan | A mirror file has no supported note reference | Review before moving or deleting it |
| Cloud orphan | A listed cloud object has no supported note reference | Review external consumers and backups; this is not deletion authorization |
| Protected | A policy or protected prefix excludes the object from mutation | Leave it under the owning workflow |
| Unverified | Available metadata is insufficient for a strong conclusion | Use deep audit or manual inspection |
Some tools store images in the same bucket but own their own paths. Add one object-key prefix per line under Cloud key prefixes excluded from path sync, for example:
mpclipper
external-app/assets
The plugin can still recognize these URLs for display-oriented operations, but it does not move or automatically delete objects under protected prefixes.
WebP conversion is optional.
Test screenshots, diagrams with transparency, and photographs at the chosen quality before enabling conversion for a large workflow.
Check that:
staging or managed;Compare the cloud object key with the path below the local mirror root. They must be identical after URL decoding and path normalization. Run a quick audit to identify missing or mismatched mirrors.
The notice means managed notes contain recognized image keys that differ from their current note-derived paths. It can be caused by older releases, moves performed while the plugin was disabled, or links created by another tool. Run a quick audit first and inspect the listed source and expected keys before re-syncing.
NoSuchKey appears during migrationThe note refers to an old key that is no longer present at that exact location. Do not assume the object is lost: search the audit result, local mirror, historical URL prefixes, and backups for the same filename or content. Restore or copy the verified bytes to the expected key before rewriting the note.
Add that tool's stable object-key prefix to the protected-prefix setting. Do not use a broad prefix that also covers objects owned by this plugin.
The standard scanner handles supported Markdown image references. It does not guarantee support for image references stored inside Excalidraw's internal document data. Track this limitation in the project's GitHub issues before relying on it.
The plugin performs network requests only for user-configured storage operations and user-requested remote image transfers. Depending on the enabled action, this can include S3-compatible PUT, GET, HEAD, LIST, copy, or delete requests and downloads from image URLs already present in notes.
data.json inside the vault configuration directory.data.json to a public issue.Requirements: Node.js 24 or later and npm.
npm ci
npm test
npm run typecheck
npm run lint
npm run verify-release
npm run build
The lint command includes the official eslint-plugin-obsidianmd recommended rules used to catch community-review issues locally. Release validation also checks that:
package.json, package-lock.json, and manifest.json use the same version;versions.json maps that plugin version to the declared minimum app version;GitHub Actions runs tests, type checking, official lint rules, metadata validation, and a production build on pushes and pull requests. A version tag repeats those checks, creates artifact attestations, and publishes main.js, manifest.json, and styles.css.
| Version | Summary |
|---|---|
| 1.8.0 | Read-only mirror download preview, create-only restore, cancellation, paginated reports, configuration/ref checks, and exact-extension local links |
| 1.7.3 | Exact link-span rewrites, special-character/title parsing, durable background retries, validated rule application, and corrected minimum app version (1.8.7) |
| 1.7.2 | Complete English community README with the detailed Chinese manual preserved separately |
| 1.7.1 | Community-review source fixes and official review lint rules in local development and CI |
| 1.7.0 | Directory policies, startup catch-up, signed downloads, transactional path migration, delayed deletion safeguards, and three-way audits |
| 1.6.9 | Local-mirror adoption, exact-key uploads, verified Cloud switching, and background handling of external note writes |
| 1.5.5 | Historical tag and release restored for version-history completeness |
Always install from the latest release. See docs/CHANGES.md for the technical history.
S3 Image Sync Pro is released under the MIT License. It is based on and extends jongchoiyip/s3-image-sync.
For the complete Chinese beginner manual, including detailed Cloudflare R2 examples and the vault workflow used by the maintainer, read README.zh-CN.md.