---
title: Optimizely Connect for SharePoint
slug: cms-11/dev-docs/optimizely-connect-for-sharepoint
docTags: 
createdAt: 2026-07-22T19:45:21.284Z
---

:::hint{type="info"}
**Note**
Optimizely Connect for Sharepoint is for CMS 11 and is not available on later versions of CMS.
:::

The connector copies documents, blocks, or other items from SharePoint document libraries and lists these automatically.

You can manually schedule and manage updates available in CMS as media or blocks. Additionally, developers can manipulate documents or blocks as they transfer to customize applications to specific CMS requirements.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/QnoJi66ZReWRIFrLgV33G_d7845f3-connect-forsharepoint-2022-c.PNG)

## Requirements

- [Contact Support](mailto\:support@optimizely.com) to request a license
- A SharePoint license
- SharePoint versions 2013, 2016, 2019, or SharePoint Online
- An Optimizely Content Management System (CMS) installation
- See [Add-ons platform compatibility](docId\:bXYbY3IauDz9fts3sKR_c) for package and version information
- See User guide: [Optimizely Connect for Sharepoint](docId\:xnfuMAxrtnVRdiKMyzw_l)

## Install

- Versions 7.5 and higher are [installed through NuGet](https://nuget.optimizely.com/package/?id=EPiServer.ConnectForSharePoint)
- Lower versions are available as zip files for download

### About the installation

The Optimizely SharePoint connector is [installed as a NuGet package](https://nuget.optimizely.com/package/?id=EPiServer.ConnectForSharePoint).

When you install the SharePoint NuGet package, a third-party dependency adds the following entry in `web.config`, but because the entry is already in `web.config`, it causes a duplicate name error. You can fix the duplicate name error by changing the name of `ExtensionlessUrlHandler-Integrated-4.0` to something else.

```xml
<add name="ExtensionlessUrlHandler-Integrated-4.0" 
     path="." 
     verb="" 
     type="System.Web.Handlers.TransferRequestHandler" 
     preCondition="integratedMode,runtimeVersionv4.0" />
```

### About ISharepointProcessor

The `ISharePointProcessor` interface lets you implement a class to override or enhance how Optimizely processes SharePoint objects. For example, you want to add a prefix to filenames as you copy the SharePoint files to the Optimizely CMS, filter specific file types from being copied to the Optimizely CMS, or notify a user after you copy the files.

### ISharePointProcessor interface

The `ISharePointProcessor` interface has the following methods:

- `AddDocument` – Adds a document to the data store.
- `AddFolder` – Adds a folder to the data store.
- `DeleteDocument` – Deletes a document from the data store.
- `DeleteFolder` – Deletes a folder from the data store.
- `UpdateDocument` – Updates (overwrites) a document in the data store.
- `UpdateFolder` – Updates (overwrites) a folder in the data store.

### Install the SharePointProcessor example

The `SharePointProcessor` example code consists of two classes:

- [InitializeModule.cs](docId\:UAa8Zy5teIv6SS1_76Kcl). Implements the `PackageInitializer` class, which registers the *demo processing module*.
- [DemoProcessor.cs](docId\:UAa8Zy5teIv6SS1_76Kcl). `DemoProcessor` is for demonstration purposes only. The sample `DemoProcessor` implementation calls the default behavior of the existing SharePoint processor and describes how to override the default behavior to extend or enhance it. You can create a class that inherits `ISharePointProcessor` so that when you initialize it, it overrides the default SharePoint processor.

:::hint{type="info"}
**Note**
You can have only one overriding processing service.
:::

To install the `SharePointProcessor` example code:

1. Create a project in Visual Studio.
2. Copy the DLL that contains your processor implementation into the `bin` folder of your solution.
3. Restart the web server.

### Register your processor

Register your SharePoint processor using the service locator in Optimizely, as shown in the following example:

```csharp
private void InitializationEngine_InitComplete(object sender, EventArgs e) { 
  _serviceLocator.Buildup(_processor); // Register our processor 
}
```

### Demo Processor

The demo processor class implements the `ISharePointProcessor` interface. The default implementation of each method is to call the default processor. For example:

```csharp
public void AddFolder(SPListItem item) {
  // Do some custom processing
  // Optionally call the default processor
  defaultProcessor.AddFolder(item);
}
```

:::hint{type="info"}
**Note**
The demo processor reads only the metadata for a specific document in SharePoint and sends the metadata to the plugin processor methods. The demo processor and the `AddDocument` method show how to retrieve the data use the default SharePoint processor by calling the default processor’s `getFileStream(item)` method, as shown in the following code samples.
:::

### InitializeModule.cs

```csharp
using EPiServer.ConnectForSharePoint.Messaging;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Packaging;
using EPiServer.ServiceLocation;
using System;
using System.Threading;

namespace DemoSharepointProcessor {
  /// <summary>
  /// Episerver Module initializer for this plugin.
  /// </summary>
  [InitializableModule]
  [ModuleDependency(typeof (EPiServer.Web.InitializationModule))]
  public class InitializeModule: PackageInitializer {
    IServiceLocator _serviceLocator;
    ISharePointProcessor _processor;

    public InitializeModule() {
      // Get the service locator from the environment
      _serviceLocator = ServiceLocator.Current;
      _processor = new DemoProcessor();
    }

    /// <summary>
    /// For unit testing
    /// </summary>
    /// <param name="serviceLocator"></param>
    internal InitializeModule(IServiceLocator serviceLocator, ISharePointProcessor processor) {
      // Use the Mocked service locator passed in
      _serviceLocator = serviceLocator;
      _processor = processor;
    }

    public override void Initialize(InitializationEngine context) {
      context.InitComplete += InitializationEngine_InitComplete;
    }

    private void InitializationEngine_InitComplete(object sender, EventArgs e) {
      _serviceLocator.Buildup(_processor); // Register our processor
    }

    public override void AfterInstall() {}
    public override void AfterUpdate() {}
    public override void BeforeUninstall() {}
  }
}
```

### DemoProcessor.cs

For example, you can add a prefix to filenames you bring into media from SharePoint.

1. Add `item.File.Name = "EPi" + item.FIle.Name;` in the AddDocument section, just after the code `var data = defaultProcessor.getFileStream(item);`.
2. Build `DemoProcessor.cs`.
3. Run the SharePoint connector to upload the `Sample.txt` sample file. The custom `DemoProcessor` changes the file's name and passes it to the default processor, which copies `Sample.txt` to `EPiSample.txt` in the media store.

```csharp
using EPiServer.ConnectForSharePoint.Messaging;
using EPiServer.ConnectForSharePoint.Models;
using EPiServer.ServiceLocation;
using EPiServer.ConnectForSharePoint.Helpers;

namespace DemoSharepointProcessor {
  [ServiceConfiguration(ServiceType = typeof (ISharePointProcessor))]
  public class DemoProcessor: ISharePointProcessor {
    private SharePointProcessor dp;

    // Default processor that adds documents and folders to EPiServer (optional)
    private SharePointProcessor defaultProcessor {
      get {
        if (dp == null)
          dp = new SharePointProcessor();
        return dp;
      }
    }

    public void AddDocument(SPListItem item) {
      // Do some custom processing

      // The splistitem does not contain the data stream associated with the file.
      // The following line is an example of how to get the data associated with the SPListItem
      SharePointProcessorHelper helper = new SharePointProcessorHelper();
      var rawdata = helper.GetDocumentStream(item);

      // Optionally call the default processor - note that the default processor 
      // also gets the data stream so that the data can be inserted into EPiServer
      defaultProcessor.AddDocument(item);
    }

    public void AddFolder(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.AddFolder(item);
    }

    public void AddListItem(SPListItem item) {
      // Do some custom processing

      SharePointProcessorHelper helper = new SharePointProcessorHelper();
      var rawdata = helper.GetRawListItemData(item);
      var dictionary = helper.GetMetaData(item.ParentList);
      var fields = helper.ParseRawListItemData(dictionary, rawdata);

      // Optionally call the default processor
      defaultProcessor.AddListItem(item);
    }

    public void DeleteDocument(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.DeleteDocument(item);
    }

    public void DeleteFolder(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.DeleteFolder(item);
    }

    public void DeleteListItem(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.DeleteListItem(item);
    }

    public void UpdateDocument(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.UpdateDocument(item);
    }

    public void UpdateFolder(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.UpdateFolder(item);
    }

    public void UpdateListItem(SPListItem item) {
      // Do some custom processing

      // Optionally call the default processor
      defaultProcessor.UpdateListItem(item);
    }
  }
}
```

## Register the Connect for SharePoint app

1. Log on to the Azure portal using your global admin user account.
2. Go to **Azure Active Directory**.
3. Click **App registrations**in the navigation panel—the **App registrations** page displays.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/jorvrliEfRHLXTq4vFFV0_b1ce439-app-registrations.png)

4. Click **New registration**. The **Register an application** page displays.
5. In the **Name** box, enter a name for the app.
6. Under Supported account types, select **Accounts** in this organizational directory only (tenant\_prefix - Single tenant).
7. Click **Register**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/213y5HKeGjD_a9goJ3G0y_e260d57-register-an-application.png)

:::hint{type="warning"}
**Important**
Copy and paste the following values in a document that you can access later. You will enter these values in the Optimizely software when you complete the Office 365 guided setup.

**Application ID**
**Directory ID**
:::

8. In the navigation panel, click **API permissions**.
9. Click **Add a permission**.
10. Click Microsoft Graph and complete the following steps:
    a. Click **Application permissions**.
    b. Select the **User.Read** permission.
11. Click **Add permissions**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/vHtPZ-iU1nKE8n_rXGMck_db235ea-add-permissions.png)

12. Click **Grant admin consent for tenant\_name**.
13. Click **Yes**.
14. In the navigation panel, click **Certificates & secrets.** The Certificates & secrets page displays.
15. Click **New client secret**. The Add a client secret dialog box displays.
16. Enter a description, and then optionally select **Never expire**.
17. Click **Add**.
18. Copy and paste the client secret value in a document you can access later. You will enter this value when you complete the Office 365 guided setup.
19. To assign full permissions to the tenant to back up SharePoint sites, go to the tenant URL in your browser. For example, go to `https://<office_365_tenant_URL>/_layouts/15/appinv.aspx`. The SharePoint admin center page displays.
20. In the App ID box, enter the application ID you recorded earlier and then click Lookup. The application's name appears in the Title box.
21. In the App Domain box, type `tenantname.onmicrosoft.com`. To get the correct domain name, go to the Microsoft Azure website, Custom domain names.
22. In the App's Permission Request XML box, type the following XML:

```xml
<AppPermissionRequests  AllowAppOnlyPolicy="true">
  <AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl" />
  <AppPermissionRequest Scope="http://sharepoint/social/tenant"  Right="Read" />
</AppPermissionRequests>
```

23. Click **Create**.
24. Click **Trust It**.
