---
title: Configure a custom localization provider
slug: cms-11/dev-docs/configuring-a-custom-localization-provider
createdAt: 2026-07-22T19:45:17.666Z
---

You have two choices for configuring localization providers.

- Configure localization in the `<episerver.framework>` section of your `web.config`. Here, you can control the behavior of providers registered on your site and disable built-in providers.
- Register a provider in the localization service through code during website initialization. This choice lets you place language documents in a location other than the default `lang` folder.
  The following sections show how to achieve this. You might be required to grant access to the folder to the IIS application pool.

:::hint{type="info"}
**Note**
A large number of providers increases the time needed to find strings. So, for best performance, support only a few providers.
:::

## Use the configuration option

When you add a provider that reads XML language documents through configuration, you specify a path to a physical folder. Optimizely Content Management System (CMS) does not support specifying a path to a virtual path provider (VPP). For details about the attributes available with the `<localization>` element, see the [EPiServer.Framework.Configuration.LocalizationElement](/epiui/CMS/Content/documentation/Class-library,,66786/?epieditmode=False\&documentId=cms/10/8D84F6EC) class.

The following example configuration demonstrates this option. Set the `addDefaultProviders` attribute to **false** to ignore the `lang` folder when initializing the site. No language documents are included.

```xml
<episerver.framework>
  ...
  <localization fallbackBehavior="FallbackCulture, MissingMessage, Echo" fallbackCulture="en">
    <providers>
      <add physicalPath="c:\temp\resourceFolder"
           name="customResources"
           type="EPiServer.Framework.Localization.XmlResources.FileXmlLocalizationProvider" />
    </providers>
  </localization>
  ...
</episerver.framework>
```

## Use the code-only option

Register localization providers during site initialization. The preferred way to do this is to implement the [IInitializableModule interface](/epiui/CMS/Content/documentation/Class-library,,66786/?epieditmode=False\&documentId=cms/10/6816AD61) and handle the registration in the Initialize method.

The following example (using a physical path) shows one way to create an `IInitializableModule` that registers a similar provider as in the configuration option above but this time through code.

```csharp
using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Framework.Localization;
using EPiServer.Framework.Localization.XmlResources;

namespace CodeSamples {
  [InitializableModule]
  [ModuleDependency(typeof (FrameworkInitialization))]
  public class CustomLanguageProviderInitializationWithPhysicalPath: IInitializableModule {
    private
    const string ProviderName = "customResources";
    public void Initialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        string langFolder = @ "c:\temp\resourceFolder";
        if (Directory.Exists(langFolder)) {
          NameValueCollection configValues = new NameValueCollection();
          //This config value tells the provider where to find XML language documents.
          configValues.Add(FileXmlLocalizationProvider.PhysicalPathKey, langFolder);
          FileXmlLocalizationProvider localizationProvider = new FileXmlLocalizationProvider();
          //Instanciates the provider
          localizationProvider.Initialize(ProviderName, configValues);
          //Adds it at the end of the list of providers.
          localizationService.Providers.Add(localizationProvider);
        }
      }
    }

    public void Uninitialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        //Gets any provider that has the same name as the one initialized.
        LocalizationProvider localizationProvider = localizationService.Providers.FirstOrDefault(p => p.Name.Equals(ProviderName, StringComparison.Ordinal));
        if (localizationProvider != null) {
          //If found, remove it.
          localizationService.Providers.Remove(localizationProvider);
        }
      }
    }

    public void Preload(string[] parameters) {}
  }
}
```

Optimizely provides two convenience classes, [VirtualPathXmlLocalizationProviderInitializer](/epiui/CMS/Content/documentation/Class-library,,66786/?epieditmode=False\&documentId=cms/10/990E8B21) and [EmbeddedXmlLocalizationProviderInitializer](/epiui/CMS/Content/documentation/Class-library,,66786/?epieditmode=False\&documentId=cms/10/21DF70AF), located in the [EPiServer.Framework.Localization.XmlResources](/epiui/CMS/Content/documentation/Class-library,,66786/?epieditmode=False\&documentId=cms/10/64E3B082) namespace. Use them when you register localization providers.

The following example (using virtual path) demonstrates using a convenience class to read XML language documents from a specified virtual path. A prerequisite for this sample is that you configure a VPP under the `<episerver>` section of `web.config`. The example uses the virtual path registered there virtual path. Also, this module is dependent on the Optimizely CMS `InitializationModule`, which requires a VPP because CMS start-up initializes VPPs.

```csharp
using System;
using System.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Framework.Localization;
using EPiServer.Framework.Localization.XmlResources;
using EPiServer.Web.Hosting;

namespace CodeSamples {
  [InitializableModule]
  //A dependency to Optimizely CMS initialization is needed to be able to use a VPP
  [ModuleDependency(typeof (EPiServer.Web.InitializationModule))]
  public class CustomLanguageProviderInitializationWithVirtualPath: IInitializableModule {
    private
    const string ProviderName = "CustomProviderName";

    public void Initialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        VirtualPathXmlLocalizationProviderInitializer localizationProviderInitializer =
          new VirtualPathXmlLocalizationProviderInitializer(GenericHostingEnvironment.VirtualPathProvider);
        //a VPP with the path below must be registered in the sites configuration.
        string virtualPath = "~/MyCustomLanguageVPP/";
        FileXmlLocalizationProvider localizationProvider = localizationProviderInitializer.GetInitializedProvider(virtualPath, ProviderName);
        //Inserts the provider first in the provider list so that it is prioritized over default providers.
        localizationService.Providers.Insert(0, localizationProvider);
      }
    }

    public void Uninitialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        //Gets any provider that has the same name as the one initialized.
        LocalizationProvider localizationProvider = localizationService.Providers.FirstOrDefault(p => p.Name.Equals(ProviderName, StringComparison.Ordinal));
        if (localizationProvider != null) {
          //If found, remove it.
          localizationService.Providers.Remove(localizationProvider);
        }
      }
    }

    public void Preload(string[] parameters) {}
  }
}
```
