# Theme Localization Learn about how FusionAuth Themes work with localization. > For the index of this section of the site, see [llms.txt](https://4002.18-224-161-104.sslip.io/docs/llms.txt) The FusionAuth theme can be localized to better server your end users. In each theme you may specify one to many language-specific message bundles to translate text rendered in a theme into a user's preferred language. If you're just looking into localizing your theme, take a look at our [community provided and maintained message bundles](https://github.com/FusionAuth/fusionauth-localization). You may also want to review our [localization and internationalization documentation](https://4002.18-224-161-104.sslip.io/docs/get-started/core-concepts/localization-and-internationalization.md). ## Messages In the Messages tab of your theme editor you may specify one to many languages. Once you have specified a key and value the key may be used in any template to display a localized string. Consider the following message bundle and theme usage example with English and German messages defined. English ```properties greeting=Good day ``` German ```properties greeting=Guten Tag optional-greeting=Mitmensch ``` Template ```html
${theme.message('greeting')} ${theme.optionalMessage('optional-greeting')}
``` If I have selected German as my locale, I will be greeted with `Guten Tag Mitmensch` rendered on the page. If I have English selected I will instead find the greeting `Good day optional-greeting`. Note Prior to version `1.53.0`, the behavior of `theme.message` and `theme.optionalMessage` differed in that an exception would be thrown if you used `theme.message` and the message key could not be found. While a missing key should be a development time issue, returning the key should provide a better development experience than throwing an exception. Beginning in version `1.53.0` there is no difference in behavior between these two methods and you should prefer `theme.message`. The following example that demonstrates the difference in behavior between `theme.message` and `theme.optionalMessage` only pertains to versions of FusionAuth prior to `1.53.0.` The behavior differs between `theme.message` and `theme.optionalMessage` only when the key doesn't exist in any of the messages files, including the default one. When there is no suitable key found and `theme.message` is used, an exception is thrown and the template fails to completely render. When there is no suitable key found and `theme.optionalMessage` is used, the key value is returned: `optional-message` in the example above. Here's an example of a template that will render for a user with a German locale but fail for a user with an English locale, because `message` fails when there is no key found: Template Which Will Fail For Users With an English Locale ```html${theme.message('optional-greeting')}
``` Here's a Freemarker function which returns an empty string when there is no value found for an optional message: Freemarker Function to Return the Empty String When No Value is Found ```ftl [#function getOptionalMessage key=""] [#if "${theme.optionalMessage(key)}" == "${key}"] [#return "" /] [/#if] [#return theme.optionalMessage(key) /] [/#function] ``` If you add this to your `_helpers.ftl` file, you can call it like this: Calling getOptionalMessage ```ftl [@helpers.getOptionalMessage key="optional-greeting" /] ``` ## Locale The locale is determined by the [locale](https://4002.18-224-161-104.sslip.io/docs/reference/data-types.md#locales) value. The locale is resolved on each request using the following precedence: 1. The `locale` request parameter, if present, on the HTTP request (e.g. `locale=fr`). This is useful if you already know the user's preferred locale prior to redirecting them to FusionAuth to complete authentication. 2. The user selects a language during login using the locale selector or there is a `fusionauth.locale` cookie present. 3. The HTTP `Accept-Language` header, if present on the HTTP request. 4. The system default locale, as determined by the underlying operating system. Note The user's **preferredLanguages** settings are not used to select a locale for the hosted login pages. ## Identity Provider Login Buttons The button text displayed in the login pages for identity providers such as Google, Facebook or SAML, is retrieved from the identity provider configuration. The [API documentation](https://4002.18-224-161-104.sslip.io/docs/apis/identity-providers/google.md) documents how to set and retrieve this value, which is `identityProvider.buttonText`. This text is used in the default theme like so: Login Template Excerpt ```html