anbing-image-upload

approved

by anbing cui

Upload images to S3-compatible storage - This plugin has not been manually reviewed by Obsidian staff.

48 downloadsUpdated 13d ago0BSD

anbing‑image‑upload

Upload images in Obsidian to S3-compatible storage, GitHub, or GitLab, and replace image links in notes with public-access URLs.

Currently supports AWS S3, Cloudflare R2, Qiniu S3-compatible API, MinIO, GitHub, and GitLab.

GitHub/GitLab storage currently requires a public repository or project. Each image is written through the provider API as a separate commit. Git repositories are not unlimited object storage; consider repository size, history growth, and API rate limits.

Features

‑ Upload the local image under the current cursor position. ‑ Select images from Vault for upload. ‑ Batch‑upload all local images within the current document. ‑ Auto‑upload images to object storage when pasting images. ‑ Convert both Wiki‑links and Markdown image syntax into standard Markdown image format. ‑ Use UUID‑based filenames after successful upload to avoid overwriting remote objects with identical names. ‑ Optional: rename local files to match remote UUID filenames. ‑ Optional: move local files to Obsidian Recycle Bin upon successful upload. ‑ Keep local images by default when upload fails, and display detailed failure reasons. ‑ Show progress statistics and failed‑file details during batch uploads.

Prerequisites

‑ This release supports desktop‑only. ‑ Obsidian version: 1.11.4 or higher. ‑ Object storage must expose S3‑compatible API endpoints. ‑ The bucket, domain or CDN corresponding to the public‑URL prefix must allow public image access. ‑ This plugin will not automatically modify bucket permissions, public‑read access or CORS configurations.

Installation

Manual Installation

Copy the following files into this directory:

Your Vault/.obsidian/plugins/obsidian‑image‑upload/
main.js
manifest.json
styles.css (if present)

Then open Obsidian: Settings → Community plugins → Installed plugins → Obsidian Image Upload Enable the plugin.

Development Build

npm install
npm run build

Development watch mode:

npm run dev

Configuration

Open plugin settings and fill in the options below.

Config ItemDescription
EndpointS3‑compatible API endpoint, NOT the final public image access URL
RegionStorage service region, e.g. us‑east‑1, or auto for R2
BucketBucket / storage‑space name
Public URL PrefixFinal public image access base URL, e.g. https://img.example.com
Object Path PrefixS3 object directory prefix, e.g. obsidian/images
Access key IDS3 access key ID, stored inside Obsidian SecretStorage
Secret access keyS3 secret access key, stored inside Obsidian SecretStorage
Session tokenFor temporary credentials, optional
Max File SizeMaximum allowed bytes for a single image file
Request TimeoutTimeout for each individual network request
Retry CountRetry attempts for network failures, range: 0‑5
Path‑style EndpointEnable for certain S3‑compatible storage providers

GitHub

Select GitHub and configure the owner, repository, branch, path prefix, and a token with repository content write permission. The repository must be public; uploaded links use raw.githubusercontent.com by default. You can optionally set a CDN domain such as https://cdn.jsdelivr.net or https://testingcf.jsdelivr.net to use jsDelivr's GitHub CDN URL format. Leave the CDN domain empty to use raw.githubusercontent.com.

GitLab

Select GitLab and configure the host, project, branch, path prefix, and a token with project write permission. The project accepts a numeric ID or namespace/project and must be public; uploaded links use the GitLab Raw URL.

GitHub and GitLab tokens are stored only in Obsidian SecretStorage. They are not written to data.json or image URLs. Connection tests validate project and branch access without creating a test commit.

Default Policies

‑ Auto‑upload on paste: Disabled ‑ Rename local files after successful upload: Enabled ‑ Delete local files after successful upload: Disabled ‑ Fallback to local files on upload failure: Enabled ‑ Never overwrite remote objects with identical names; use UUID filenames. ‑ Remote images are processed via their public URLs.

Storage‑provider Configuration Samples

AWS S3

Endpoint: https://s3.amazonaws.com
Region: us‑east‑1
Bucket: my‑images
Public URL Prefix: https://cdn.example.com
Path‑style Endpoint: Off

Cloudflare R2

Endpoint: https://<account‑id>.r2.cloudflarestorage.com
Region: auto
Bucket: my‑images
Public URL Prefix: https://img.example.com
Path‑style Endpoint: Usually Off

For R2, use credentials provided by R2 API Token for Access‑key / Secret‑access‑key. Supply the official R2 S3‑API address as Endpoint; do NOT fill in your custom domain.

Qiniu S3‑compatible API

Endpoint: https://<region>.s3.qiniucs.com
Region: Region value from Qiniu console / official docs
Bucket: Qiniu bucket name
Public URL Prefix: https://img.example.com

Qiniu Endpoint is used for uploading; the public‑URL prefix serves Markdown image access. These two values are normally different.

MinIO

Endpoint: https://minio.example.com
Region: us‑east‑1
Bucket: images
Public URL Prefix: https://minio.example.com/images
Path‑style Endpoint: Determined by your MinIO deployment settings

Usage

Editor Commands

Open Command Palette and run the commands below.

Upload current image

Place your cursor on a local‑image reference, then upload and replace its link. Supports Wiki‑link syntax:

![[image.png]]

And standard Markdown syntax:

![Image alt](image.png)

After upload it will be converted into:

![image.png](https://img.example.com/obsidian/images/2026/09/UUID.png)

Upload image file

Open Vault image selector window, pick an image to upload. The remote Markdown‑image markup will be inserted at your cursor position.

Upload all document images

Scan all local images within current document, upload each one and replace links. Progress will show in the top‑right notification, example:

Uploading image 3/8...

After completion, counts for succeeded / failed items will be shown; failed notifications list filenames and root causes.

Editor Right‑click Menu

Right‑click inside Markdown editor:

Image Upload
├─ Upload current image to S3
├─ Select and upload image to S3
└─ Upload all images in current document

Auto‑Upload On Paste

Turn on this toggle inside plugin settings:

Auto‑upload images on paste

When enabled for pasted clipboard images:

  1. Save image file into the same directory as current Markdown note.
  2. Upload file to S3 object storage.
  3. Insert remote Markdown‑image markup at cursor position.

When disabled, the plugin does not intercept paste events, keeping Obsidian native paste behaviour.

Local‑file Handling Policies

Rename Local Files

If Rename local files after successful upload is enabled:

Before upload: photo.png
After upload: 32cb76a3‑b67a‑4649‑8828‑eac3ed1f5120.png

Remote S3 object and local file share the identical UUID filename.

If disabled: local files retain original filenames, but Markdown links will still point to remote public URLs.

Delete Local Files

If Delete local files after successful upload is enabled: Local files are moved to Obsidian Recycle Bin only after upload succeeds and link replacement finishes. Local files remain untouched upon upload failure.

Failure‑handling Behaviours

‑ Invalid configuration, bad file format or oversized file: notes will remain unmodified. ‑ S3 upload failure: local image files are preserved. ‑ Paste‑upload fails and fallback enabled: insert local Markdown‑image markup. ‑ Paste‑upload fails and fallback disabled: delete the locally‑created temporary image file generated during paste. ‑ Batch upload failure: continue processing remaining images; summary lists failed files and reasons at completion.

Redacted detailed error logs print to Obsidian Developer‑tools Console with log prefix:

[obsidian‑image‑upload]

Open developer tools: Ctrl + Shift + I.

Security Notes

‑ Access key, Secret access key and Session token are persisted by Obsidian SecretStorage. ‑ Credentials are NOT written into plain‑text plugin‑setting JSON files. ‑ Any user gaining filesystem access to your Vault or Obsidian configuration may retrieve locally‑saved credentials. ‑ It is recommended to use a dedicated bucket, dedicated object‑path prefix and access keys with minimal‑possible permissions. ‑ This version is built for public‑accessible URLs. Private buckets, signed‑access URLs and pre‑signed uploads are not supported. ‑ Never commit Access‑key / Secret‑access‑key / Session‑token values into Git repositories.

Current Limitations & Roadmap

Current limitations: ‑ Desktop‑only support. ‑ Remote URLs must be publicly accessible. ‑ Private buckets and signed URLs are unsupported. ‑ Vault‑wide bulk image migration is unavailable.

Future roadmap: ‑ Support private buckets and signed URLs. ‑ Pre‑signed uploads and temporary‑credential workflows. ‑ Vault‑wide bulk‑migration feature. ‑ Image compression & format conversion. ‑ Mobile‑platform support.

Validation Scripts

npm run build
npm run lint

The lint step may emit warnings about missing Obsidian 1.13+ setting‑search declarative‑API declarations; such warnings do not block plugin runtime functionality.

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.