You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Any function that deals with querying vault's frontmatter, default to using Datacore API first, then write fallback where you use `plugin.app.vault.getMarkdownFiles()` to iterate through each file's frontmatter
35
+
36
+
## Plugin Store Guidelines
37
+
38
+
These rules must be followed for the plugin to be accepted into the Obsidian community plugin store.
39
+
40
+
### Security
41
+
42
+
- Never use `innerHTML`, `outerHTML`, or `insertAdjacentHTML` with user-controlled content
43
+
- Use Obsidian DOM helpers instead: `createEl()`, `createDiv()`, `createSpan()`
44
+
45
+
### App instance
46
+
47
+
- Always use `this.app` — never the global `app` object
48
+
49
+
### Event listeners
50
+
51
+
- Register all event listeners via `this.registerEvent()` so they are automatically cleaned up on plugin unload
52
+
53
+
### UI text
54
+
55
+
- Use sentence case in settings headings and labels (not title case)
56
+
- Prefer `setHeading()` over raw HTML heading elements (`<h1>`, `<h2>`, etc.)
57
+
58
+
### Commands
59
+
60
+
- Do not set default hotkeys — they conflict with other plugins
61
+
- Use the correct callback type: `callback` for always-available commands, `checkCallback` when the command is conditionally available, or the editor variants for editor-scoped commands
62
+
- Do not manually prepend the plugin ID to command IDs — Obsidian adds it automatically
63
+
64
+
### Workspace
65
+
66
+
- Do not store references to custom views — look them up fresh each time they are needed
67
+
Don't do this:
68
+
`this.registerView(MY_VIEW_TYPE, () => this.view = new MyCustomView());`
69
+
Do this instead:
70
+
`this.registerView(MY_VIEW_TYPE, () => new MyCustomView());`
71
+
To access the view from your plugin, use `Workspace.getActiveLeavesOfType():`
72
+
73
+
```
74
+
for (let leaf of app.workspace.getActiveLeavesOfType(MY_VIEW_TYPE)) {
75
+
let view = leaf.view;
76
+
if (view instanceof MyCustomView) {
77
+
// ...
78
+
}
79
+
}
80
+
```
81
+
82
+
- Do not detach leaves during plugin unload
83
+
84
+
### Editor
85
+
86
+
- Prefer the Editor API over `Vault.modify()` when the note is currently open in the editor
87
+
- Prefer `Vault.process()` instead of `Vault.modify()` to modify a file in the background
88
+
89
+
### Mobile compatibility
90
+
91
+
- Node.js and Electron APIs (`fs`, `crypto`, `os`) are unavailable on mobile
92
+
- If the plugin targets mobile, use web API equivalents: `SubtleCrypto` instead of `crypto`, `navigator.clipboard` for clipboard access
93
+
- Regex lookbehind assertions are not supported on some mobile — avoid them if possible
94
+
95
+
### Code quality
96
+
97
+
- Use `const`/`let` — never `var`
98
+
- Prefer `async`/`await` over `.then()` chains
99
+
- Minimize `console.log` — remove debug logs before shipping
100
+
- Do not hardcode styles inline — use CSS classes and Obsidian's CSS variables
0 commit comments