Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Custom Attachment Location

Michael NaumovMichael Naumov113k downloads

Customize attachment location with variables($filename, $data, etc) like Typora.

Add to Obsidian
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
Custom Attachment Location screenshot
  • Overview
  • Scorecard
  • Updates44

Paste a screenshot into Obsidian and it lands in one shared attachment folder under a name like Pasted image 20250101120000. A year later that folder holds a thousand files whose names say nothing about which note they belong to, and moving or renaming a note leaves its attachments behind. This plugin lets you decide where each attachment is stored and what it is called, from a pattern built out of tokens — ${noteFileName}, ${date:{momentJsFormat:'YYYYMMDD'}}, and about twenty more — and then keeps that arrangement true as notes are renamed, moved and deleted. The renaming and deleting half is handled by its companion plugin, Advanced Rename and Delete Handler, which this plugin requires: it does nothing until that plugin is installed, and installs it for you in one click.

Every pasted screenshot in one heap, named after the clock

More screenshots
With the plugin: a folder of its own, beside the note And named after the note it belongs to, not the clock Rename the note and its attachments move with it The embed still resolves — nothing is left pointing nowhere Every pasted screenshot in one heap, named after the clock With the plugin: a folder of its own, beside the note And named after the note it belongs to, not the clock Rename the note and its attachments move with it The embed still resolves — nothing is left pointing nowhere

Demo vault

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:

  1. Running the Custom Attachment Location: Open demo vault command.
  2. Downloading obsidian-custom-attachment-location-demo-vault.zip from the Releases. It unzips into a single obsidian-custom-attachment-location-demo-vault-<version> folder.
  3. Browsing its source in demo-vault/ in this repository.

What it does

  • Choose the folder each new attachment goes into, per note or per anything else a pattern can express — one folder beside every note, a folder per note, a folder per year. Or leave shouldFollowObsidianAttachmentLocation on, as a fresh install has it, and let Obsidian's own Default location for new attachments decide, keeping everything else this plugin does. Installing the plugin therefore moves nothing: attachments land where they always did until you switch that off and pick a pattern. While the plugin's pattern is in charge, Obsidian's own settings page says so instead of showing a value that is not in effect. 01 Attachment folder location
  • Choose the file name, so an attachment is called something that says where it came from instead of Pasted image 20250101120000. 02 Attachment file naming
  • Patterns and tokens — the vocabulary both of those are written in, including asking you for a value at paste time, reading one from the note's frontmatter, and defining your own tokens in JavaScript. 03 Tokens and patterns · 04 Custom tokens · 09 Token reference
  • Catch attachments other plugins create — some plugins write an attachment into the vault under a name of their own instead of asking Obsidian where it belongs. Set renameAttachmentsCreatedByOtherPluginsMode and those files are moved and renamed too, just after they appear — for every plugin, or only for the ones you name, or for every plugin except the ones you name. Off by default. 06 Settings
  • Collect attachments — take the attachments a note already has and move them into the folder your settings say they belong in, for one note, one folder, or the whole vault. 05 Collect attachments
  • Delete unused attachments — move an attachment no note references any more to the trash, after a confirmation dialog. A folder you have designated as one attachment is judged whole: it goes only when nothing outside it references anything inside it, and otherwise stays intact. Set orphanAttachmentScanMode and the whole-vault sweep also reaches attachment folders whose note has been deleted, which nothing leads to any more. Off by default. 08 Delete unused attachments
  • Keep it true over time — attachments follow their note when it is renamed or moved, and can be deleted with it. Since 12.0.0 that half is done by Advanced Rename and Delete Handler, which this plugin requires — it loads nothing without it, explains why, and installs it in one click — and hands its old settings to. Installing it changes nothing on its own: its defaults do nothing until you turn renames or deletions on. Two plugins handling one rename corrupt links and move attachments twice, so exactly one owns it. 06 Settings
  • Link display text — give an inserted attachment link the attachment's own name as its text, which plugins that render captions can then use. 07 Link display text
  • Jump between a note and its attachments — reveal the folder a note's attachments are saved into, and go from an attachment back to the note that owns it. 10 Navigation

Tokens

Moved to 09 Token reference — every token, its format schema and worked examples. For what a pattern is and the tokens most people use, start at 03 Tokens and patterns.

This heading stays so that the See available tokens links inside the plugin's own settings tab keep resolving, including from versions already installed.

Custom tokens

Moved to 04 Custom tokens.

Markdown URL format

Moved to 06 Settings, under markdownUrlFormat.

For plugin developers

Everything this plugin offers another plugin is declared in one hand-written file — api.d.ts at the repository root. It imports from obsidian and nothing else, so you can copy it into your own code or reference it where it sits, with no build-time dependency on this repository.

The API is published through the obsidian-dev-utils plugin registry under the plugin id obsidian-custom-attachment-location, so you get version negotiation, a handle that is revoked when this plugin unloads, and a wait that ends when it loads rather than a lookup that returns undefined because it ran first:

const apiRef = watchPluginApi<CustomAttachmentLocationApi>({
  apiVersionRange: '^1',
  app,
  component: this,
  pluginId: 'obsidian-custom-attachment-location'
});

const folder = await apiRef.value?.getAttachmentFolderPath({ notePath: 'Notes/Alpha.md' });
const properPath = await apiRef.value?.getProperAttachmentPath({ attachmentPathOrFile: 'image.png', notePath: 'Notes/Alpha.md' });

Do not read vault.getConfig('attachmentFolderPath')

This plugin patches that call, which makes it look like the seam you want. It is not one. The patch answers with this plugin's value only while a note is open, and the value it answers with is the open note's — computed once when the file was opened. A plugin looping over every note in the vault therefore gets the active note's attachment folder for all of them, silently, with no error and nothing to distinguish it from a correct answer. The patch is a write-path override for Obsidian's own attachment creation, not a readable configuration.

getAttachmentFolderPath is the read, asked once per note. It answers null when this plugin leaves that note alone entirely, which is your cue to fall back to Obsidian's own attachmentFolderPath — a different answer from this plugin not being installed, and deliberately so.

Both reads arrived in contract version 1.0.0, and both are asynchronous: an attachment folder is the result of evaluating a user-written template whose tokens can read the note's frontmatter and the attachment's bytes, so there is no synchronous answer to hand back. Neither ever asks the user anything, so a whole-vault audit raises no dialogs.

Handing collect settings over

A plugin that used to collect attachments itself hands its settings over through migrateSettings, added in contract version 1.1.0, so ask for '^1.1.0'. It proposes the values it held, and this plugin shows the user each one that would change next to the value it holds now. Nothing is written unless the user approves, and isApplied: false means they cancelled, so keep the proposal pending. api.d.ts lists the settings that can be proposed. The shape matches obsidian-dev-utils' SettingsMigrationApi, so its SettingsMigrationComponent can run the whole offer:

this.addChild(new SettingsMigrationComponent<MigratableCollectSettings>({
  apiVersionRange: '^1.1.0',
  app,
  getProposedSettings: () => settingsComponent.settings.proposedCollectSettings,
  pluginSettingsComponent: settingsComponent,
  providerPluginId: 'obsidian-custom-attachment-location',
  retireProposedSettings: () => settingsComponent.editAndSave((settings) => {
    settings.proposedCollectSettings = null;
  }),
  sourcePluginId: this.manifest.id
}));

Installation

The plugin is available in the official Community Plugins repository.

Beta versions

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:

  1. Ensure you have the BRAT plugin installed and enabled.
  2. Click Install via BRAT.
  3. An Obsidian pop-up window should appear. In the window, click the Add plugin button once and wait a few seconds for the plugin to install.

Debugging

By default, debug messages for this plugin are hidden.

To show them, run the following command in the DevTools Console:

window.DEBUG.enable('obsidian-custom-attachment-location');

For more details, refer to the documentation.

Attributions

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.

Changelog

All notable changes to this project will be documented in the CHANGELOG.

Contributing

Contributions are welcome — see CONTRIBUTING to get set up.

Support

My other Obsidian resources

See my other Obsidian resources.

License

Copyright (c) RainCat1998, Michael Naumov.

HealthExcellent
ReviewSatisfactory
About
Customize attachment save paths and filenames using tokens (like ${noteFileName} and date formats). Rename pasted files, collect attachments from notes into configured folders, and control how links to attachments are inserted into Markdown.
AttachmentsFilesLinks
Details
Current version
12.0.1
Last updated
2 weeks ago
Created
5 years ago
Updates
44 releases
Downloads
113k
Compatible with
Obsidian 1.13.7+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Sponsor
Buy Me a Coffee
Author
Michael NaumovMichael Naumovmnaoumov
mnaoumov.dev
GitHubmnaoumov
Xmnaoumov
  1. Community
  2. Plugins
  3. Attachments
  4. Custom Attachment Location

Related plugins

Advanced URI

Control everything with URI.

Find orphaned files and broken links

Find files that are not linked anywhere and would otherwise be lost in your vault. In other words: files with no backlinks.

Consistent Attachments and Links

Move note attachments and update links automatically.

Pixel Perfect Image

Pixel perfect 100% image resizing, copy to clipboard, show image in Finder/Explorer, and much more.

Note Refactor

Extract note content into new notes and split notes.

Notebook Navigator

A better file browser and calendar inspired by Apple Notes, Bear, Evernote and Day One.

Excalidraw

Visual PKM powerhouse. Create and edit Excalidraw drawings.

Claudian

Embeds Claude Code/Codex and other local Agents as AI collaborators in your vault.

Smart Connections

Find related notes and excerpts while writing. Your AI link building copilot displays relevant content in graph + list view. A local embedding model powers semantic search. Zero setup. No API key.

Breadcrumbs

Visualise the hierarchy of your vault using a breadcrumb trail or matrix view.