quill-i18n
v0.0.1
Published
A comprehensive i18n module for Quill 2.x, providing translation management, language switching, and automatic UI updates.
Readme
Quill I18n Plugin
A comprehensive i18n module for Quill 2.x, providing translation management, language switching, and automatic UI updates.
Features
- ✅ Core i18n Module - Translation management and language switching
- ✅ Parameterized Translations - Dynamic values in translations
- ✅ Event System - Automatic UI updates on language change
- ✅ Reactive Helpers - Automatic DOM updates for custom UI
- ✅ Toolbar i18n Support - Optional internationalization for Quill's native toolbar
- Prompt internationalization (link, image, video)
- Picker internationalization (header, size, font, align)
Installation
npm install quill-i18nQuick Start
Basic Usage
import Quill from 'quill';
import I18n from 'quill-i18n';
Quill.register('modules/i18n', I18n);
const quill = new Quill('#editor', {
modules: {
i18n: {
locale: 'zh',
messages: {
en: {
mymodule: {
title: 'My Module',
description: 'This is my custom module'
}
},
zh: {
mymodule: {
title: '我的模块',
description: '这是我的自定义模块'
}
}
}
}
}
});
// Use in your custom modules
const i18n = quill.getModule('i18n');
console.log(i18n.t('mymodule.title')); // "我的模块"
// Switch language
i18n.setLocale('en');
console.log(i18n.t('mymodule.title')); // "My Module"With Default Toolbar Picker and link/image/video Tip Update
import Quill from 'quill';
import I18n, { createI18nToolbarHandlers, enableToolbarI18nAutoUpdate } from 'quill-i18n';
Quill.register('modules/i18n', I18n);
const quill = new Quill('#editor', {
modules: {
i18n: {
locale: 'en-US',
messages: {
'en-US': {
toolbar: {
header: {
'': 'Normal',
'1': 'Heading 1',
'2': 'Heading 2',
'3': 'Heading 3',
},
bold: 'Bold Text',
italic: 'Italic Text',
link: {
'': 'Insert Link',
'prompt': 'Enter link URL:',
},
image: {
'': 'Insert Image',
'prompt': 'Enter image URL:',
},
video: {
'': 'Insert Video',
'prompt': 'Enter video URL:',
},
}
}
}
},
toolbar: {
container: [[{ header: [] }, 'bold', 'italic', 'link', 'image', 'video']],
handlers: createI18nToolbarHandlers() // Enable link/image/video i18n prompts
}
}
});
// Enable automatic toolbar picker i18n updates
enableToolbarI18nAutoUpdate(quill);API Reference
Core I18n Module
I18n Class
class I18n {
constructor(quill: Quill, options: I18nOptions);
// Get translated text
t(key: string, params?: Record<string, any>, defaultValue?: string): string;
// Change current locale
setLocale(locale: string): void;
// Add or update messages for a locale
addMessages(locale: string, messages: I18nMessages): void;
// Get current locale
getLocale(): string;
}Options
interface I18nOptions {
locale?: string; // Current locale (default: 'en')
fallbackLocale?: string; // Fallback locale (default: 'en')
messages?: I18nMessages; // Translation messages
}Events
// Emitted when locale changes
quill.on('i18n-locale-change', (event: { locale: string; prevLocale: string }) => {
console.log(`Language changed from ${event.prevLocale} to ${event.locale}`);
});
// Emitted when messages are updated
quill.on('i18n-messages-update', (event: { locale: string }) => {
console.log(`Messages updated for ${event.locale}`);
});Toolbar Helpers
createI18nToolbarHandlers()
Creates toolbar handlers with i18n support for prompts.
import { createI18nToolbarHandlers } from 'quill-i18n';
const quill = new Quill('#editor', {
modules: {
toolbar: {
handlers: createI18nToolbarHandlers()
}
}
});Supported handlers:
link- Link URL promptimage- Image URL promptvideo- Video URL prompt
Translation keys:
toolbar.link.prompttoolbar.image.prompttoolbar.video.prompt
updateToolbarI18n(quill)
Manually update toolbar picker labels (one-time update).
import { updateToolbarI18n } from 'quill-i18n';
const quill = new Quill('#editor', { /* ... */ });
updateToolbarI18n(quill);enableToolbarI18nAutoUpdate(quill)
Enable automatic toolbar picker updates on language change.
import { enableToolbarI18nAutoUpdate } from 'quill-i18n';
const quill = new Quill('#editor', { /* ... */ });
enableToolbarI18nAutoUpdate(quill);
// Now pickers will auto-update when locale changes
const i18n = quill.getModule('i18n');
i18n.setLocale('en'); // Pickers automatically updateSupported pickers:
header- Heading levelssize- Font sizesfont- Font familiesalign- Text alignment
Translation keys:
/* eslint-disable ts/no-unused-expressions */
// Header
toolbar.header.normal;
toolbar.header.h1;
toolbar.header.h2;
toolbar.header.h3;
toolbar.header.h4;
toolbar.header.h5;
toolbar.header.h6;
// Size
toolbar.size.small;
toolbar.size.normal;
toolbar.size.large;
toolbar.size.huge;
// Font
toolbar.font.sans;
toolbar.font.serif;
toolbar.font.monospace;
// Align
toolbar.align.left;
toolbar.align.center;
toolbar.align.right;
toolbar.align.justify;Reactive Helpers
i18n.createReactiveElement()
Create DOM elements that automatically update when translations change.
// Method 1: Via i18n instance (recommended for custom modules)
const i18n = quill.getModule('i18n');
const { element, reactive } = i18n.createReactiveElement(
'button',
'mymodule.button.save',
);
element.classList.add('save-btn');
document.body.appendChild(element);
// Button text will automatically update when locale changes// Method 2: Direct import (also available)
import { createReactiveElement } from 'quill-i18n';
const { element, reactive } = createReactiveElement(
quill,
'button',
'mymodule.button.save'
);i18n.createReactive()
Create a reactive translation instance.
// Method 1: Via i18n instance (recommended for custom modules)
const i18n = quill.getModule('i18n');
const reactive = i18n.createReactive('mymodule.title');
// Get current translation
console.log(reactive.value);
// Update element
const element = document.querySelector('.title');
reactive.updateElement(element);
// Cleanup
reactive.destroy();// Method 2: Direct import (also available)
import { ReactiveTranslation } from 'quill-i18n';
const reactive = new ReactiveTranslation(quill, 'mymodule.title');Custom Modules Integration
Integrate i18n into your custom Quill modules with these patterns.
Basic Usage
Get the i18n module instance and use the t() method:
import type Quill from 'quill';
import { Module } from 'quill';
class MyCustomModule extends Module {
constructor(quill: Quill, options: any) {
super(quill, options);
const i18n = quill.getModule('i18n');
// Get translated text
const title = i18n.t('mymodule.title');
console.log(title); // "My Module" or "我的模块"
// With parameters
const message = i18n.t('mymodule.welcome', { name: 'John' });
console.log(message); // "Welcome, John!" or "欢迎, John!"
}
}
Quill.register('modules/mymodule', MyCustomModule);Using Reactive Translation
For automatic UI updates without manual event handling:
class MyCustomModule extends Module {
private titleTranslation: ReturnType<I18n['createReactive']>;
private countTranslation: ReturnType<I18n['createReactive']>;
constructor(quill: Quill, options: any) {
super(quill, options);
const i18n = quill.getModule('i18n');
// Create reactive translations via i18n instance
this.titleTranslation = i18n.createReactive('mymodule.title');
this.countTranslation = i18n.createReactive('mymodule.count', { count: 0 });
// Bind to elements
const titleEl = document.querySelector('.mymodule-title');
this.titleTranslation.updateElement(titleEl);
const countEl = document.querySelector('.mymodule-count');
this.countTranslation.updateElement(countEl);
}
updateCount(count: number) {
// Update parameters - UI updates automatically
this.countTranslation.setParams({ count });
}
destroy() {
// Cleanup reactive translations
this.titleTranslation.destroy();
this.countTranslation.destroy();
}
}Creating Reactive Elements
Create DOM elements that automatically update when translations change:
class MyCustomModule extends Module {
constructor(quill: Quill, options: any) {
super(quill, options);
const i18n = quill.getModule('i18n');
// Create a reactive button element
const { element, reactive } = i18n.createReactiveElement(
'button',
'mymodule.actions.save',
);
element.classList.add('save-btn');
this.container.appendChild(element);
// Button text will automatically update when locale changes
}
}Adding Messages Dynamically
You can add translations at runtime:
class MyCustomModule extends Module {
constructor(quill: Quill, options: any) {
super(quill, options);
const i18n = quill.getModule('i18n');
// Organize your translations with a module namespace
// Add messages for your module
i18n.addMessages('en-US', {
mymodule: {
title: 'My Module'
}
});
i18n.addMessages('zh-CN', {
mymodule: {
title: '我的模块'
}
});
}
}License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
