Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions en/Plugins/Releasing/Plugin guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,61 @@ async function AsyncTest(): Promise<string | null> {
}
}
```

## Language

### English-first

Write the following in English by default:

- `manifest.json`
- `id`
- `name`
- `description`
- `README.md`

It is not recommended but if you really need it, you may include translations (except for `id`), but the English version must appear first.

### UI localization

Set English as the default language for your plugin UI whenever possible.

Do not mix multiple languages within the same UI.

If your plugin offers localized UI strings, ensure it respects [`getLanguage()`](https://docs.obsidian.md/Reference/TypeScript+API/getLanguage) (requires `minAppVersion` to be at least `1.8.7`).

Don't add a custom language setting to your plugin; rely on Obsidian's built-in language setting instead.

If your plugin ships without English support, call this out explicitly in both the `description` property in `manifest.json` and the `README.md`.

### Internationalization (i18n) frameworks

If your plugin supports multiple UI languages, consider using frameworks like [i18next](https://www.i18next.com/), or hand-written one, e.g.:

```ts
// locales/en.ts
export const en = {
'some.key': 'Some value'
};

// i18n.ts
import en from './locales/en.ts';
import zhCN from './locales/zh_CN.ts'
import { getLanguage } from 'obsidian';

const localeMap: { [locale: string]: Partial<typeof en> } = {
en: en
zh: zhCN
};

const userLocale = localeMap[getLanguage()];

export function t(key: keyof typeof en): string {
return userLocale?.[key] ?? en[key] ?? key;
}

// main.ts
import { t } from './i18n.ts';

new Notice(t('some.key'));
```