Michael Naumov143k downloadsCustomize attachment location with variables($filename, $data, etc) like Typora.
Paste a screenshot into Obsidian and it lands in one shared folder as Pasted image 20250101120000. A year later that folder holds a thousand files whose names say nothing about which note they belong to.
This plugin decides where each attachment is stored and what it is called, from a pattern of tokens such as {{noteFileName}} and {{date:{momentJsFormat:'YYYYMMDD'}}}. Keeping that true as notes are renamed, moved and deleted is the job of its companion, Advanced Rename and Delete Handler, which this plugin requires and installs for you in one click.
The documentation is a demo vault. Every feature has a note that explains what it does and why you would want it, and walks you through it with a file you supply.
Start reading here — it is plain markdown, so it works on GitHub with nothing installed.
A copy of the vault ships with every release. You can access it via any of the following:
Custom Attachment Location: Open demo vault command.obsidian-custom-attachment-location-demo-vault.zip from the Releases. It unzips into a single obsidian-custom-attachment-location-demo-vault-<version> folder.demo-vault/ in this repository.Excalidraw drawing, and move and rename them too. 06 Settingsgit: in a vault kept in git, each collect, delete, move or prune run can be recorded as its own commit, so one revert undoes it. Off by default, desktop only. 06 SettingsAdvanced Rename and Delete Handler. 06 Settings@Plugin sync data (DO NOT REMOVE) folder, which the plugin explains with a README.md and lists in Obsidian's Excluded files. Original name storage covers setup, hidden folders and safe relocation.Moved to 09 Token reference. For what a pattern is, start at 03 Tokens and patterns.
Moved to 04 Custom tokens.
Moved to 06 Settings, under markdownUrlFormat.
| Plugin | Features | How Custom Attachment Location differs |
|---|---|---|
Attachment Location Manager |
Global, folder and note destinations; nearest-match rules; extension exceptions | Same routing goal; one token pattern can read paths and frontmatter |
Attachment Management |
Attachment path/name patterns; collection; follows note renames | Overlaps on naming and collection; delegates note moves/renames to Advanced Rename and Delete Handler |
Attachment Manager |
One attachment folder per note; rename, delete and visibility handling | Overlaps on per-note folders; supports other layouts through patterns |
Attachment Placement |
Routes new attachments by usage and insertion rules | Overlaps on routing; also chooses file names |
Attachment Renamer |
Templated names for new and existing attachments | Overlaps on naming; also chooses the folder |
Attachment Steward |
Templated folders/names; original-name retention; bulk imports | Overlaps on templating; also collects existing attachments and deletes unused ones |
Consistent Attachments and Links (maintained by me) |
Moves attachments with notes; vault-wide link consistency | Complementary: chooses new attachment folders and names |
Foldwise |
Per-folder asset rules; saved-assets page | Same routing goal; token patterns; no assets page |
Image Renamer |
Pasted-image templates; frontmatter-based names and folders | Broader scope: every attachment type |
Note Companion Folder |
Separate attachment folder for each note | Overlaps on per-note folders; supports other pattern-based layouts too |
Paste image rename |
Pasted-image names from a pattern or prompt | Broader scope: every attachment type; folder patterns too |
Unique attachments |
Names derived from content hashes | Overlaps on hash naming; also chooses folders and other name patterns |
Last searched for similar plugins on 2026-10-26.
This plugin publishes an API another plugin can call: attachment folder and path reads, a collect action, its full path resolver and a collect-settings handover. It is declared in api.d.ts, with its contract in api-contract.ts. Plugin API explains how to reach it, with or without @mnaoumov/obsidian-lib, and why vault.getConfig('attachmentFolderPath') is not a seam to read.
The plugin is available in the official Community Plugins repository.
To install the latest beta release of this plugin (regardless if it is available in the official Community Plugins repository or not), follow these steps:
Add plugin button once and wait a few seconds for the plugin to install.By default, debug messages for this plugin (id: obsidian-custom-attachment-location) are hidden.
If you need to enable them refer to the documentation.
In Oct 2021, the plugin was created by RainCat1998.
From July 2024, the plugin is maintained by Michael Naumov.
From December 2025, the project repository is hosted at mnaoumov/obsidian-custom-attachment-location.
The original author's repository is preserved as an archive of issues/PRs/discussions/releases at RainCat1998/obsidian-custom-attachment-location.
All notable changes to this project will be documented in the CHANGELOG.
Contributions are welcome — see CONTRIBUTING to get set up.
Open issues through the issue forms, not as blank issues.
To report a bug from inside Obsidian, run the Custom Attachment Location: Report a bug command. It opens the bug form with the plugin version, the Obsidian version and your operating system already filled in.
Filing from the CLI or the API (gh issue create --body, or an AI agent filing for you) skips the form, and gh issue create --template cannot load an issue form. In that case, open the matching form in .github/ISSUE_TEMPLATE/, copy every field as a ### <label> heading in the form's order, and fill in each one. Always state the plugin version, the Obsidian version and your operating system.
Copyright (c) RainCat1998, Michael Naumov.