# Translation of plugins to other languages

**URL:** <https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715>\
**Category:** Devs: Plugins & API\
**Tags:** valuable, ui-ux\
**Created:** [April 1, 2021, 10:05am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715 "2021-04-01T10:05:52Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![henrikfalk](https://forum.obsidian.md/user_avatar/forum.obsidian.md/henrikfalk/32/10493_2.png) [@henrikfalk](https://forum.obsidian.md/u/henrikfalk)\
**Post date:** [April 1, 2021, 10:05am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/1 "2021-04-01T10:05:52Z")

</div>

I asked Liam the “Calendar” plugin developer to support other languages and he replied:  
“I would love to see settings and dialogs get translated! I’ll check with the Obsidian devs to see there’s anything they can expose via the API to help with plugin localization.”

I think this would be a valuable feature.

/Henrik 🙂

---

<div class="post-metadata">

**Author:** ![Moonbase59](https://forum.obsidian.md/user_avatar/forum.obsidian.md/moonbase59/32/13648_2.png) [@Moonbase59](https://forum.obsidian.md/u/Moonbase59)\
**Post date:** [April 2, 2021, 7:27am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/2 "2021-04-02T07:27:51Z")

</div>

Yup, a standardized way to do this would be great.

---

<div class="post-metadata">

**Author:** ![Kir](https://forum.obsidian.md/user_avatar/forum.obsidian.md/kir/32/3511_2.png) [@Kir](https://forum.obsidian.md/u/Kir)\
**Post date:** [May 30, 2021, 10:20am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/3 "2021-05-30T10:20:52Z")

</div>

Adding a couple of modal windows to my plugin and also decided to look for plugins i18n support. Found this topic. Agree, would be nice to have a standardized way

---

<div class="post-metadata">

**Author:** ![HaujetZhao](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/h/67e7ee/32.png) [@HaujetZhao](https://forum.obsidian.md/u/HaujetZhao)\
**Post date:** [June 15, 2021, 2:02am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/4 "2021-06-15T02:02:40Z")

</div>

Yes, that would greatly improve the comfort for users across the world

---

<div class="post-metadata">

**Author:** ![aidenlx](https://forum.obsidian.md/user_avatar/forum.obsidian.md/aidenlx/32/13115_2.png) [@aidenlx](https://forum.obsidian.md/u/aidenlx)\
**Post date:** [October 22, 2021, 2:37am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/5 "2021-10-22T02:37:00Z")

</div>

I would recommend building a public platform to host and maintain all translations, both core and plugins, and pontoon may be a good project to start with: [GitHub - mozilla/pontoon: Mozilla's Localization Platform](https://github.com/mozilla/pontoon)

---

<div class="post-metadata">

**Author:** ![Mara-Li](https://forum.obsidian.md/user_avatar/forum.obsidian.md/mara-li/32/12591_2.png) [@Mara-Li](https://forum.obsidian.md/u/Mara-Li)\
**Post date:** [February 21, 2023, 9:03pm UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/6 "2023-02-21T21:03:57Z")

</div>

Hello!

For Obsidian Github Publisher, i wanted to update the translation file to using i18next, because some autocompletion will help me a lot during update.

I tryed to do it, but get `undefined` everywhere, without error in console.

I created the file `i18next.ts` in `plugin/i18n` and each translation file is in `json`  
My i18next.ts file :

```ts
import i18next from 'i18next';
import {moment} from "obsidian";
import * as en from './locales/en.json';
import * as de from './locales/de.json';
//import fr from "./locales/fr.json";

//detect language
const locale = moment.locale();
export const translationLanguage = locale ? moment.locale() : "en";

console.log("Init i18next")

i18next.init({
    lng:locale,
    fallbackLng: "en",
    resources: {
        en: {
            translation: en,
        },
        de: {
            translation: de,
        }
    },
});

```

I call the i18next like that : `i18next.t('somethings')`

Maybe Obsidian Plugin can’t use json file ?

---

<div class="post-metadata">

**Author:** ![derammo\_on\_github](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/d/58956e/32.png) [@derammo\_on\_github](https://forum.obsidian.md/u/derammo_on_github)\
**Post date:** [February 22, 2023, 4:07pm UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/7 "2023-02-22T16:07:36Z")

</div>

This was solved on Discord, right?

---

<div class="post-metadata">

**Author:** ![Mara-Li](https://forum.obsidian.md/user_avatar/forum.obsidian.md/mara-li/32/12591_2.png) [@Mara-Li](https://forum.obsidian.md/u/Mara-Li)\
**Post date:** [February 23, 2023, 9:19am UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/8 "2023-02-23T09:19:17Z")

</div>

Yes!

I created two file :

First : `i18next.ts`

```auto
import {moment} from "obsidian";
import * as en from "./locales/en.json";
import * as fr from "./locales/fr.json";

export const ressources = {
	en: { translation: en },
	fr: { translation: fr },
} as const;

export const translationLanguage = Object.keys(ressources).find(i => i==moment.locale()) ? moment.locale() : "en";

```

Second : `i18next.d.ts`

```auto
import { ressources } from "./i18next";

declare module "i18next" {
    interface CustomTypeOptions {
        readonly resources: typeof ressources["en"];
        readonly returnNull: false
    }
}

```

After, in my `main.ts` I added the init in the start:

```auto
i18next.init({
			lng: translationLanguage,
			fallbackLng: "en",
			resources: ressources,
		});

```

---

<div class="post-metadata">

**Author:** ![cheznine](https://forum.obsidian.md/user_avatar/forum.obsidian.md/cheznine/32/63979_2.png) [@cheznine](https://forum.obsidian.md/u/cheznine)\
**Post date:** [October 4, 2024, 2:09pm UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/9 "2024-10-04T14:09:13Z")

</div>

### Use case or problem

There are some common libraries that Obsidian uses that would be great if plugin developers had access to as well. It was mentioned that `moment` is available, but there’s these that spring to mind (would love to hear more in the comments):

- `i18next`: For localization of plugin UI text.
- whatever lib Obsidian uses for drag-and-drop UI, if there is one (`SortableJS` ?)

Has there been thinking on exposing other libraries aside from `moment` that Obsidian uses, that plugin devs could make use of?

### Proposed solution

Allow `i18next` (and other libraries) to be importable from Obsidian.

### Current workaround (optional)

- `i18next`: I amended Obsidian’s types to expose this object. (Example in comment below.)
- drag-and-drop UI: I’ve added [`SortableJS`](https://github.com/SortableJS/Sortable) as a dependency.

---

<div class="post-metadata">

**Author:** ![cheznine](https://forum.obsidian.md/user_avatar/forum.obsidian.md/cheznine/32/63979_2.png) [@cheznine](https://forum.obsidian.md/u/cheznine)\
**Post date:** [October 4, 2024, 2:10pm UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/10 "2024-10-04T14:10:06Z")

</div>

Literally within _days_ of externalizing my UI’s strings thanks to `i18next` , and providing [some instructions](https://github.com/chrisgurney/obsidian-note-toolbar/wiki/Help-translate-Note-Toolbar-%F0%9F%8C%90), I had _three_ contributors translate my plugin to Chinese (Simplified), German, and Ukrainian.

Here’s how easy it was to **add localization to my plugin’s UI** :

```typescript
// in types.d.ts
declare global {
  // provides access to Obsidian's translation framework
  var i18next: any;
}

...

// in my plugin onload()
i18next.addResourceBundle('en', 'plugin-note-toolbar', {
    hello: 'Hello!'
});
i18next.addResourceBundle('es', 'plugin-note-toolbar', {
    hello: 'Hola!'
});

...

// in my settings UI
const t = i18next.getFixedT(null, 'plugin-note-toolbar', null);

console.log(t('hello')); 
// prints "Hello!" if language is set to English, or "Hola!" if language is set to Español
// falls back to English if other language strings aren't set

```

---

<div class="post-metadata">

**Author:** ![WhiteNoise](https://forum.obsidian.md/user_avatar/forum.obsidian.md/whitenoise/32/11_2.png) [@WhiteNoise](https://forum.obsidian.md/u/WhiteNoise)\
**Post date:** [October 4, 2024, 3:15pm UTC](https://forum.obsidian.md/t/translation-of-plugins-to-other-languages/15715/11 "2024-10-04T15:15:20Z")

</div>

moved to developers and api
