Localization
Localization allows users to see information in their preferred language. This guide will show you how to add localization support to your activity.
Why Add Localization?
PreMiD is used by people from all over the world who speak different languages. By adding localization to your activity, you can provide a better experience for users who don't speak English.
Benefits of adding localization:
- Better user experience: Users can see information in their preferred language.
- Wider audience: Your activity can be used by people who don't speak English.
- Community contribution: The PreMiD community can help translate your activity to more languages.
Prerequisites
To use localization in your activity, you must add the language setting to your metadata.json
file. This special setting enables the language selector in the activity settings.
{
"settings": [
{
"id": "lang",
"multiLanguage": true
}
]
}
Without this setting, users won't be able to select their preferred language.
Adding Localization to metadata.json
The first step in adding localization is to provide translations for the description in your metadata.json
file:
{
"description": {
"de": "Example ist eine Website, die etwas Cooles macht.",
"en": "Example is a website that does something cool.",
"es": "Example es un sitio web que hace algo genial.",
"fr": "Example est un site web qui fait quelque chose de cool."
}
}
The keys are language codes, and the values are the descriptions in those languages. You should at least provide an English description. The PreMiD translation team will help with other languages.
Using the getStrings Method
The getStrings
method allows you to get translations for common strings from the PreMiD extension. These translations are maintained by the PreMiD translation team and are available in many languages.
const presence = new Presence({
clientId: 'your_client_id'
})
enum ActivityAssets {
Logo = 'https://example.com/logo.png',
}
presence.on('UpdateData', async () => {
// Get translations
const strings = await presence.getStrings({
play: 'general.playing',
pause: 'general.paused',
browse: 'general.browsing'
})
// Use translations in your presence data
const presenceData: PresenceData = {
largeImageKey: ActivityAssets.Logo
}
const video = document.querySelector('video')
if (video) {
if (video.paused) {
presenceData.details = strings.pause
}
else {
presenceData.details = strings.play
}
}
else {
presenceData.details = strings.browse
}
presence.setActivity(presenceData)
})
The getStrings
method takes an object where the keys are the names you want to use for the strings, and the values are the keys for the strings in the PreMiD translation system.
Available Translation Keys
PreMiD provides a set of common strings in the websites/general.json
file. These strings are prefixed with general.
and can be used in any activity.
Here's how the strings are structured in the general.json file:
{
"general.playing": {
"description": "", // Description for translators
"message": "Playing" // The actual string value
},
"general.paused": {
"description": "",
"message": "Paused"
}
}
Here are some commonly used translation keys:
Key | English Value |
---|---|
general.playing | "Playing" |
general.paused | "Paused" |
general.browsing | "Browsing..." |
general.reading | "Reading..." |
general.watching | "Watching..." |
general.live | "Live" |
general.episode | "Episode" |
general.season | "Season" |
general.chapter | "Chapter" |
general.page | "Page" |
For a complete list of available translation keys, check the websites/general.json
file in the PreMiD Activities repository.
Language Setting
To allow users to select their preferred language for your activity, you can add a special language setting. This is done by adding a setting with the ID lang
and setting the multiLanguage
property to true
:
{
"settings": [
{
"id": "lang",
"multiLanguage": true
}
]
}
This special setting tells PreMiD that your activity supports multiple languages. When this setting is present, PreMiD will automatically add a language selector to your activity's settings page, allowing users to choose which language they want to see in your activity.
Important Notes:
- The
lang
setting is a special case and can only be used once in your activity. - You cannot use
multiLanguage: true
with any other setting ID besideslang
. - When a user selects a language, your activity can retrieve this selection using
presence.getSetting("lang")
and use it to display content in the appropriate language.
Creating Custom Translations
If you need to use strings that are not available in the PreMiD translation system, you can create custom translations for your activity by adding a localization file.
Adding a Localization File
To add custom translations, create a JSON file named after your service in the activity's directory. For example, if your activity is for "Example", create a file named Example.json
.
websites/
├── E/
│ └── Example/
│ ├── metadata.json
│ ├── presence.ts
│ └── Example.json <-- Localization file
The localization file should follow the same structure as the general.json file, but with keys prefixed by your activity's name to avoid conflicts:
{
"example.homepage": {
"description": "Shown when viewing the homepage",
"message": "Homepage"
},
"example.about": {
"description": "Shown when viewing the about page",
"message": "About page"
},
"example.contact": {
"description": "Shown when viewing the contact page",
"message": "Contact page"
}
}
Important: When creating custom strings for your activity, you must always prefix the keys with your activity's name (e.g., example.homepage
) to avoid conflicts with other activities or the general strings. The description
field helps translators understand the context of the string, and the message
field contains the actual text in plain English.
Using Custom Translations
In your presence.ts
file, you can access these translations:
const presence = new Presence({
clientId: 'your_client_id'
})
enum ActivityAssets {
Logo = 'https://example.com/logo.png',
}
presence.on('UpdateData', async () => {
// Get the user's language
const userLanguage = await presence.getSetting<string>('lang') || 'en'
// Get all translations at the top of UpdateData
const strings = await presence.getStrings({
play: 'general.playing',
browse: 'general.browsing',
home: 'example.homepage',
about: 'example.about',
contact: 'example.contact'
})
// Create the presence data
const presenceData: PresenceData = {
largeImageKey: ActivityAssets.Logo,
details: strings.play // From general.json
}
const path = document.location.pathname
// Use the strings based on the current page
if (path === '/') {
presenceData.state = strings.home
}
else if (path.includes('/about')) {
presenceData.state = strings.about
}
else if (path.includes('/contact')) {
presenceData.state = strings.contact
}
presence.setActivity(presenceData)
})
Best Practices
- Use the getStrings method: Use the
getStrings
method for translations. Get all strings at once at the top of your UpdateData event for better performance. - Create a localization file: For custom strings, create a localization file named after your service.
- Provide fallbacks: Always provide fallbacks for languages that are not supported.
- Keep it simple: Use simple, clear language that is easy to translate.
- Be consistent: Use consistent terminology throughout your activity.
- Test with different languages: Test your activity with different languages to ensure it works correctly.
Complete Example
Here's a complete example of an activity with localization support:
metadata.json
{
"author": {
"name": "Your Name",
"id": "your_discord_id"
},
"service": "Example",
"description": {
"de": "Example ist eine Website, die etwas Cooles macht.",
"en": "Example is a website that does something cool.",
"fr": "Example est un site web qui fait quelque chose de cool."
},
"url": "example.com",
"version": "1.0.0",
"logo": "https://example.com/logo.png",
"thumbnail": "https://example.com/thumbnail.png",
"color": "#FF0000",
"category": "other",
"tags": ["example", "multilanguage"],
"settings": [
{
"id": "lang",
"multiLanguage": true
},
{
"id": "showButtons",
"title": "Show Buttons",
"icon": "fas fa-compress-arrows-alt",
"value": true
}
]
}
presence.ts
const presence = new Presence({
clientId: 'your_client_id'
})
const browsingTimestamp = Math.floor(Date.now() / 1000)
enum ActivityAssets {
Logo = 'https://example.com/logo.png',
}
// Use getStrings to access translations from your localization file
presence.on('UpdateData', async () => {
// Get settings
const showButtons = await presence.getSetting<boolean>('showButtons')
const userLanguage = await presence.getSetting<string>('lang') || 'en'
// Get all translations at the top of UpdateData
const strings = await presence.getStrings({
browse: 'general.browsing',
home: 'example.homepage',
about: 'example.about',
contact: 'example.contact'
})
// Create the base presence data
const presenceData: PresenceData = {
largeImageKey: ActivityAssets.Logo,
startTimestamp: browsingTimestamp
}
// Set details based on the current page
const path = document.location.pathname
// Use the translations based on the current page
if (path === '/') {
presenceData.details = strings.home
}
else if (path.includes('/about')) {
presenceData.details = strings.about
}
else if (path.includes('/contact')) {
presenceData.details = strings.contact
}
else {
presenceData.details = strings.browse
}
// Add buttons if enabled
if (showButtons) {
presenceData.buttons = [
{
label: 'Visit Website',
url: document.location.href
}
]
}
// Set the activity
presence.setActivity(presenceData)
})
Example.json
{
"example.homepage": {
"description": "Shown when viewing the homepage",
"message": "Homepage"
},
"example.about": {
"description": "Shown when viewing the about page",
"message": "About page"
},
"example.contact": {
"description": "Shown when viewing the contact page",
"message": "Contact page"
}
}
Note that the keys in the localization file are prefixed with the activity's name (example.
) to avoid conflicts with other activities or general strings. The description
field provides context for translators, and the message
field contains the actual text in plain English.
Next Steps
Now that you understand how to add localization to your activity, you can learn more about:
- Best Practices: Learn best practices for creating activities.