Custom Language
To tailor the default messages on your website for specific languages or preferences, you can define a window.mimeeqCustomMessages
object with your custom translations.
Adding Custom Messages
You can place the translation script anywhere in your HTML document. However, it is best to include it before the mimeeq embed script to ensure that the custom messages are loaded correctly.
Example
Here is an example of how to define custom messages:
<script>
window.mimeeqCustomMessages = {
// Example translations
'header3d.finish': 'Finish',
'historymodule.panelmenufooter.finish': 'Finish',
// ... more translations
};
</script>
Important Note
These custom messages are consumed once when the Mimeeq Embed renders for the first time. Therefore, any changes to the translations will require you to either reload the webpage or unmount the configurator from the DOM and render it once again. For dynamic updates to translations during runtime, refer to the Updating Translations During Runtime section.
Updating Translations During Runtime
By default, custom translations defined in window.mimeeqCustomMessages
are consumed once when the Mimeeq Embed renders for the first time. However, you can now update these translations dynamically during runtime and ensure that the changes are applied across the application.
How to Update Translations
To update translations dynamically and make sure the Mimeeq Embed picks up these changes, follow these steps:
-
Modify
window.mimeeqCustomMessages
: Update thewindow.mimeeqCustomMessages
object with your new translations. This can be done programmatically based on user interactions, changes in preferences, or any other dynamic factors.function updateCustomTranslations() {
// Example: Update translations based on user actions or preferences
const userIsSignedIn = checkUserSignInStatus(); // Replace with your logic
if (userIsSignedIn) {
// Load translations for signed-in users
window.mimeeqCustomMessages = {
...window.mimeeqCustomMessages,
'historymodule.panelmenufooter.addToCart': 'Add to Quote', // Example translation update for signed-in users
};
} else {
// Load translations for public users
window.mimeeqCustomMessages = {
...window.mimeeqCustomMessages,
'historymodule.panelmenufooter.addToCart': 'Add to Basket', // Example translation update for public users
};
}
// Trigger the 'mimeeq-refresh-translations' event to notify the embed of changes
document.dispatchEvent(new Event('mimeeq-refresh-translations'));
} -
Trigger the
mimeeq-refresh-translations
Event:: After updatingwindow.mimeeqCustomMessages
, dispatch themimeeq-refresh-translations
event on the document object. This event notifies the Mimeeq Embed to refresh its translations and apply the updated messages.
function handleUserAction() {
// Logic that updates translations
updateCustomTranslations();
}
Example Use Case
Imagine a scenario where you dynamically change button labels based on user authentication status:
- Public Users: See "Add to Basket" button.
- Signed-in Users: See "Add to Quote" button.
Here's how you can achieve this:
async function loadCustomTranslations() {
// Check user authentication status
const userData = await window.mimeeqApp.authentication.getUserData();
const userIsSignedIn = !!userData; // Check if user data exists to determine sign-in status
if (userIsSignedIn) {
// Load translations for signed-in users
window.mimeeqCustomMessages = {
...window.mimeeqCustomMessages,
'historymodule.panelmenufooter.addToCart': 'Add to Quote',
};
} else {
// Load translations for public users
window.mimeeqCustomMessages = {
...window.mimeeqCustomMessages,
'historymodule.panelmenufooter.addToCart': 'Add to Basket',
};
}
// Trigger the 'mimeeq-refresh-translations' event to notify the embed of changes
document.dispatchEvent(new Event('mimeeq-refresh-translations'));
}
In this example:
loadCustomTranslations()
asynchronously checks the user's authentication status usingwindow.mimeeqApp.authentication.getUserData()
.- Depending on whether the user is signed in (
userIsSignedIn
), it updateswindow.mimeeqCustomMessages
with the appropriate translations for the "Add to Cart" button. - Finally, it triggers the
mimeeq-refresh-translations
event to ensure that the Mimeeq Embed updates its UI with the newly applied translations.
This approach enables dynamic translation updates based on user interactions or changes in authentication status, providing a more personalized experience within your application.
Available Strings for Customization
To customize messages on your website for specific languages or preferences, you can define a window.mimeeqCustomMessages
object with your custom translations. This section outlines how to integrate chunks from different translation files into your customization efforts.
Integration of Translation Chunks
You can integrate specific translation chunks into your window.mimeeqCustomMessages
object based on the features and functionalities you want to customize. Here's how you can include these chunks:
const configuratorTranslations = {
// Content of "configurator.json"
exampleKey: 'Example translation for configurator',
};
const authTranslations = {
// Content of "auth.json"
signIn: 'Sign In',
signOut: 'Sign Out',
};
window.mimeeqCustomMessages = {
...configuratorTranslations,
...authTranslations,
// Include other chunks as needed
};
Full JSON Integration
Alternatively, you can include the entire JSON file directly into window.mimeeqCustomMessages
:
import fullTranslations from './translations-json-file.json';
window.mimeeqCustomMessages = {
...fullTranslations,
};
Available Chunks
Base Files
These files contain strings used in multiple places across different features:
- configurator.json: Contains strings used in the configurator feature, including basic product configurations.
- errors.json: Strings related to network request errors, used across various error handling scenarios.
Feature-Specific Chunks
These chunks are specific to certain functionalities or embed types:
- auth.json: Strings related to authentication, including sign-in and sign-out messages.
- basketEmbed.json: Strings used for the basket functionality, including adding items and managing the basket.
- ar.json: Strings related to Augmented Reality (AR) features, such as AR buttons and modal messages.
- languages.json: Strings related to language selection options available to the user. Requires authentication and user profile management.
- optionPanel.json: Strings related to the options panel, including option selection and configuration.
- favourites.json: Strings related to the favorites functionality, available for signed-in users.
- pdf.json: Strings related to PDF generation for documents. Contains only strings for PDF document generation.
- modular.json: Strings used specifically for modular products, including modular configurations and related messages.
- productList.json: Strings used specifically for product listing, including list view configurations and messages.
Usage Notes
- Integration: Spread the contents of each chunk into the
window.mimeeqCustomMessages
object or include them individually under their respective keys. - Updating Translations: Modify the respective chunk's translations within
window.mimeeqCustomMessages
to reflect changes. Reload the application or re-render components as necessary for changes to take effect.
List of Most Commonly Used Keys
Here are some of the most commonly translated keys across different features for quick reference:
<script>
window.mimeeqCustomMessages = {
// Interface
'header3d.finish': 'Finish', // modular product
'historymodule.panelmenufooter.finish': 'Finish', // 2d/3d product
'historymodule.panelmenufooter.addToCart': 'Add to Cart', // 2d/3d product when basket mode
'summarypanel.addToCart': 'Add to Cart', // when the add to cart button is on the summary screen
'header3d.addToCart': 'Add to Cart', // Add to cart on modular product header
'optiongroupmenu.selectoptions': 'Select Options', // header of Options panel menu
'modular.summary.relatedProducts': 'Related Products', // Tab name of Related Products at Modular summary modal
'relatedproducts.relatedproducts': 'Related Products', // Header over Related Products section at 2d and 3d products
// prices
'pricing.info.amountInfo': 'Total price includes one time extras of {amount}', // info appearing when price contain one time extra
// basket
'addToCart.saving': 'Saving...', // Text on Add to Cart button while loader is visible
'toast.error.required': 'Some required fields are missing', // shown if there is some missing required fields
'toast.basket.adding': 'Please wait until we prepare your product and put it into your cart', // shown while adding to cart
'toast.basket.adding.title': 'Adding to Cart', // title of adding to cart toast
// Sign in modal
'modallogin.header.login': 'Sign in', // modal title
'signinPage.title': 'Log in to your account', // modal subtitle
'signinPage.description': '', // modal description
'signinPage.form.email': 'Email Address', // email field label
'signinPage.form.forgotPassword': 'Forgot?', // forgot password button
'signinPage.form.password': 'Password', // password field label
'signinPage.form.submitBtn': 'Log in', // submit button
'signinPage.form.submitting': 'Submitting...', // info during submitting/logging
// forgot password modal
'modallogin.header.forgot': 'Forgot password', // modal title
'forgotPasswordPage.description':
'Enter your email address and we will send you a code to enter on the next screen', // description above the form
'forgotPasswordPage.form.email': 'Email Address', // email field label
'forgotPasswordPage.form.submitBtn': 'Reset Password', // submit button text
'forgotPasswordPage.form.submitting': 'Submitting...', // submitting text
'forgotPasswordPage.title': 'Forgot password?', // Forgot password modal subtitle
// new password form
NewPasswordRequired: 'New password required', // New password modal subtitle
'newPasswordForgotPage.description': 'An email is sent with a security code to enter below', // description above the form
'newPasswordForgotPage.form.code': 'Code',
'newPasswordForgotPage.form.code.hint': 'Check your email', // New password form hint for code fields
'newPasswordForgotPage.form.username': 'Username',
// resend verification link button
'resendconfirm.modal.close': 'Close',
'resendconfirm.modal.confirmation': 'Your code has been resent. Please check your email',
'signupSuccessPage.resendEmail.link': 'Resend email link', // resend button text
// User Profile Modal
'editprofile.modal.title': 'Profile', // title
'editprofile.modal.form.email': 'Email',
'editprofile.modal.form.firstName': 'First name',
'editprofile.modal.form.lastName': 'Last name',
'editprofile.modal.form.password': 'Password',
'editprofile.modal.form.phoneNumber': 'Phone number',
'editprofile.modal.form.defaultuserlang': 'Default user language',
'editprofile.modal.removeAccount': 'Delete my profile', // remove account button text
'settings.language.symbol': 'Symbol',
'settings.language.symbol.en': 'English',
'settings.language.symbol.pl': 'Polish',
'settings.language.symbol.de': 'Deutsch',
'settings.language.symbol.en-US': 'English US',
'settings.language.symbol.en-us': 'English US',
// Change password form
'changePasswordPage.form.submitBtn': 'Change password',
'changepassword.modal.form.header.currentPassword': 'Current password',
'changepassword.modal.form.header.newPassword': 'New password',
'changepassword.modal.form.password': 'Password',
'changepassword.modal.form.repeatPassword': 'Repeat Password',
'changepassword.modal.save': 'Save',
'changepassword.modal.title': 'Change password',
// delete account modal
'confirmdelete.user.title': 'Are you sure you want to remove your account?', // title
'confirmdelete.user.text1':
'To confirm you want to delete your account, type “DELETE” in the field below and click <b>Delete</b>. To go back, click <b>Cancel.</b> This action cannot be undone.', // subtitle
// Authentication errors
CodeMismatch: 'Invalid verification code provided, please try again.', // displayed when wrong verification code entered at new password form
IncorrectEmail: 'Old password is incorrect',
IncorrectEmailOrPassword: 'Email or password is incorrect',
InvalidCaptcha: 'Invalid captcha',
InvalidPassword: 'Invalid password',
LimitExceeded: 'Attempt limit exceeded, please try after some time.',
NoAccess: 'You have no access',
UsedPassword: 'Password has to be different than 10 previous passwords',
UserIsDisabled: 'Your Account is Blocked, please contact your administrator',
UserNotConfirmed: 'Email is not verified',
UserNotFound: 'User not found',
UsernameExists: 'An account with the given email already exists',
'error.code.forbidden': 'Access denied/forbidden',
// validation errors
'validation.confirmPassword': 'Passwords are different',
'validation.email': 'This is not correct email',
'validation.required': 'Required',
'validator.invalidLength': 'Password should have at least 8 chars',
'validator.invalidPasswordRegex':
'Password should contain 1 lowercase, 1 uppercase, 1 number and 1 special char',
'validator.invalidRegex': 'Invalid regex',
// AR
'ar.button.desktop': 'View in your room',
'ar.button': 'AR',
// AR Desktop modal
'ar.modal.title': 'Scan QR code',
'ar.modal.desktopText': 'It looks like you are using a desktop.',
'ar.modal.desktopScanText':
'Scan the QR code with the camera app on your mobile device to see the product in AR.',
'ar.modal.orCopyCode': 'or copy and enter code manually',
// AR Landing Page
'ar.landingpage.description': 'Click view in room below and see this product come to life',
'ar.landingpage.button.text': 'View in Room',
'ar.landingpage.button.loading.text': 'Loading AR...',
'ar.landingpage.button.generating.text': 'Generating...',
'ar.landingpage.button.createAnother.text': 'Create another',
'ar.landingpage.image.placeholder.text': 'We are generating your AR experience...',
'ar.landingpage.button.text.goBack': 'Go back',
// AR Incompatible Page
'ar.landingpage.header.incompatible': 'Device not AR-Compatible',
'ar.landingpage.description.incompatible':
"We're sorry, it seems that the AR features are not supported on your current device. Check the {devicesSupported} to find compatible models.",
'ar.landingpage.description.devicesSupported': 'list of supported devices',
// AR generation failure view
'ar.landingpage.header.failed': 'AR model generation failed',
'ar.landingpage.description.failed':
'Go back to the product page or try to load the model again. If the issue continues, please contact our support team for help.',
'ar.landingpage.button.text.tryAgain': 'Try again',
// Delivery Info
'summarypanel.delivery':
'<b>Delivery</b>: {valueType, select, number {{type, select, week {{weeks, plural, one {# Week} other {# Weeks}}} month {{months, plural, one {# Month} other {# Months}}} year {{years, plural, one {# Year} other {# Years}}} other {{days, plural, one {# Working Day} other {# Working Days}}} }} other {{days}}}',
// Basket
'basket.panel.header': 'Basket {count, plural, =0 { } other {(#)}}',
'basket.panel.requestQuote': 'Request Quote',
'basket.panel.total': 'Total',
'basket.item.removeTooltip': 'Remove this item',
'basket.item.specification': 'Specification',
'basket.item.subtotal': 'Subtotal',
'basket.item.unitPrice': 'Unit price',
'basket.panel.empty.header': 'Your basket is empty',
'basket.panel.empty.description':
'Add at least one item to a basket for making an order or generation a quotation',
'basket.panel.empty.explore': 'Explore Products',
'basket.panel.contact.header': 'Add Contact Details',
'basket.contact.confirmEmail': 'Confirm Email',
'basket.contact.submit': 'Send Request',
'basket.success.header': '{submissionDisplayName} Sent',
'basket.success.subheader': 'Thank you for submitting your Request!',
'basket.success.reference': 'Your Submission Reference is {referenceCode}.',
'basket.success.email': 'A copy has been sent to the email you submitted for your reference',
'basket.success.explore': 'Browse More Products',
'basket.item.note': 'Note (optional)',
};
</script>
Additional Resources
For more detailed information on ICU Message Format syntax and usage, refer to:
Providing Custom Messages for Multiple Languages
You can define custom messages for multiple languages by specifying different language codes within the window.mimeeqCustomMessages
object. This approach allows you to support a multilingual user base by displaying messages in the user's preferred language.
Example
Below is an example of how to define custom messages for English (en
) and Polish (pl
):
<script>
window.mimeeqCustomMessages = {
en: {
'header3d.finish': 'Next',
'historymodule.panelmenufooter.finish': 'Next',
},
pl: {
'header3d.finish': 'Dalej',
'historymodule.panelmenufooter.finish': 'Dalej',
},
};
</script>
In this example:
- The English version (en) uses "Next" for finishing actions.
- The Polish version (pl) uses "Dalej" for the same actions.
Just like with single-language customizations, these translations are consumed when the embed script loads. Ensure that any changes are followed by a webpage reload to apply the new translations.
Using HTML in Translations
When working with translations, you may occasionally need to apply additional styling or include URLs. To facilitate this, our translation system supports custom HTML/XML tags. This allows you to have more control over how your text is displayed.
Available Tags
<b>TEXT</b>
: Bolds the nested text.<i>TEXT</i>
: Displays the nested text in italics.<c>TEXT</c>
: Displays the nested text in the customer's accent color.<a>URL|LABEL</a>
: Creates a hyperlink. The URL comes first, followed by a|
, and then the link text. If no link text is provided, the URL itself will be used as the link text.
Examples
Here are examples of how to use these tags within your custom messages:
Italic Text
<script>
window.mimeeqCustomMessages = {
en: {
'toast.basket.adding':
'<i>Please wait until we prepare your product and put it into your cart</i>',
},
};
</script>
Link with Custom Text
<script>
window.mimeeqCustomMessages = {
en: {
'toast.basket.adding':
'Please wait until we prepare your product and put it into your <a>https://example.com/cart|cart</a>',
},
};
</script>
Bold Text
<script>
window.mimeeqCustomMessages = {
en: {
'confirmdelete.user.text1':
'To confirm you want to delete your account, type “DELETE” in the field below and click <b>Delete</b>. To go back, click <b>Cancel.</b>. This action cannot be undone.',
},
};
</script>
Text with Accent Color
<script>
window.mimeeqCustomMessages = {
en: {
'pricing.info.amountInfo': 'Total price includes one-time extras of <c>{amount}</c>',
},
};
</script>
ICU Message Syntax
Our translation system uses ICU message syntax, which provides powerful capabilities for handling variables, plurals, and more dynamic text variations. Below are some examples to get you started.
Variables
Variables in ICU messages are denoted by curly braces {}
and should not be translated. They allow dynamic insertion of values into messages.
Example
<script>
window.mimeeqCustomMessages = {
en: {
'pricing.info.amountInfo': 'Total price includes one-time extras of {amount}',
},
};
</script>
Pluralization
ICU supports pluralization based on numeric values. It uses a syntax similar to {variable, plural, ...}
where different cases are specified for different numeric values.
Example
<script>
window.mimeeqCustomMessages = {
en: {
'basket.panel.header': 'Basket {count, plural, =0 { } other {(#)}}',
},
pl: {
'basket.panel.header':
'Koszyk {count, plural, =0 { } one {(#)} few {(#)} many {(#)} other {(#)}}',
},
};
</script>
Select Statements
Select statements allow choosing a message based on the value of a variable, similar to switch-case statements in programming languages.
Example
<script>
window.mimeeqCustomMessages = {
en: {
'summarypanel.delivery':
'<b>Delivery</b>: {valueType, select, number {{type, select, week {{weeks, plural, one {# Week} other {# Weeks}}} month {{months, plural, one {# Month} other {# Months}}} year {{years, plural, one {# Year} other {# Years}}} other {{days, plural, one {# Working Day} other {# Working Days}}} }} other {{days}}}',
},
};
</script>
More Information
For a comprehensive guide on ICU message syntax and its advanced features, refer to the ICU User Guide and formatjs Documentation.
ICU message syntax provides extensive capabilities beyond these examples. Refer to the external resources for detailed information on handling complex scenarios such as nested messages and handling different language structures.