---
title: Localize the UI
slug: cms-11/dev-docs/localizing-the-user-interface
docTags: 
createdAt: 2026-07-22T19:45:20.939Z
---

The default localization service uses a provider system to retrieve translated resource files from a predefined location in the project folders.

The default localization service configures the provider to look for XML string resource files in a folder under the content root named **lang**. You can add your own localizations or override system strings by adding files to this location. Translations added to an XML file in the lang directory override system-defined resources.

The default localizes the user interface according to the editor's **Language Settings** > **Personal Language**. However, you can create a localization provider and add more conditions if you want something more sophisticated. To do this, you have to inherit from `LocalizationProvider` and register it as described in [Configure a custom localization provider](docId\:EAzswrSllDe-i8X7eFK0G).

## Setup

To get localization to work, specify a physical localization provider or a virtual one in the `web.config` file under `<episerver.framework>`:

```xml
<episerver.framework>
  ...
  <localization fallbackBehavior="Echo" fallbackCulture="en">
    <providers>
      <add virtualPath="~/Resources/LanguageFiles" 
           name="languageFiles" 
           type="EPiServer.Framework.Localization.XmlResources.FileXmlLocalizationProvider, EPiServer.Framework.Aspnet" />
    </providers>
  </localization>
</episerver.framework>
```

When you add the provider, you can add one or more language files in XML format to that location (or as embedded resources if `EmbeddedXmlLocalizationProvider` is used), such as `ContentTypeNames.xml`.

You can give the language file any name and have each language in a separate file (or in one file). However, you need a certain structure in the language file, as follows.

One language:

```xml
<?xml version="1.0" encoding="utf-8"?>
<languages>
  <language name="English" id="en">
  </language>
</languages>
```

Two languages:

```xml
<?xml version="1.0" encoding="utf-8"?>
<languages>
  <language name="English" id="en">
    ...
  </language>
  <language name="Swedish" id="sv">
    ...
  </language>
</languages>
```

## Add localized text

You can localize the text shown in the user interface for your content types by adding localized texts in a convention-based format. The following code example shows how to add localized texts for the `StandardPage` content type, such as the attribute name and description or properties for the standard page like `MainContentArea`.

```csharp
[ContentType(Description = "This text can you have in XML instead")]

public class StandardPage: PageData {
  [Display(
    GroupName = SystemTabNames.Content,
    Name = "This text can you have in XML instead",
    Description = "This text can you have in XML instead"
  )]
  public virtual ContentArea MainContentArea {
    get;
    set;
  }
}
```

If you have a `StandardPage` content type with the attributes and properties as in the example above, the structure in the language file would be as follows:

```xml
<language name="en">
  <contenttypes>
    <standardpage>
      <description>A description of the page type</description>
      <properties>
        <maincontentarea>
          <caption>Name text from XML</caption>
          <help>Description text from XML</help>
        </maincontentarea >
      </properties>
    </standardpage>
  </contenttypes>
</language>
```

### Reuse localization for properties between content types

You can add common translations to an inherited type, for instance `PageData` or `IContentData`.

```csharp
public class StandardPage: PageData {
  public virtual string Name {
    get;
    set;
  }
}
```

```xml
<language id="en" name="English">
  <contenttypes>
    <pagedata>
      <properties>
        <name>
          <caption>Name text from language file</caption>
        </name>
      </properties>
    </pagedata>
  </contenttypes>
</language>
```

```xml
<language id="en" name="English">
  <contenttypes>
    <icontentdata>
      <properties>
        <disableindexing>
          <caption>Disable indexing</caption>
          <help>Prevents the page from being indexed by search engines</help>
        </disableindexing>
      </properties>
    </icontentdata>
  </contenttypes>
</language>
```

:::hint{type="info"}
**Note**
If you have your own base classes that are not registered as content types, and you want to add translations to these classes, you must create a `UIDescriptor` for the base class.
:::

### Localize headers

You can localize headers, such as tabs used to group properties, in the top-level section groups.

```csharp
public class StandardPage: PageData {
  [Display(GroupName = SystemTabNames.Content, )]
  public virtual ContentArea MainContentArea {
    get;
    set;
  }
}

public static class SystemTabNames {
  public
  const string Content = "Information";
}
```

Group name on the property `MainContentArea` is referred to `SystemTabNames.Content` and, as shown in the previous example, `SystemTabNames.Content` is referring to *Information*.

The correct way here is to add `<groups>` and then the property name.

```xml
<language name="en">
  <groups>
    <information>Group name from XML file</information>
  </groups>
</language>
```
