Translation of plugins to other languages

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 :slight_smile:

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

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

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

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

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 :

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 ?

This was solved on Discord, right?

Yes!

I created two file :

First : i18next.ts

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

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:

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

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 as a dependency.

Literally within days of externalizing my UI’s strings thanks to i18next , and providing some instructions, 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:

// 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

moved to developers and api