en flag +1 214 306 68 37

Pitfalls of using JSLink with SharePoint apps for Office Store

Aliaksandr Kananchuk

Aliaksandr Kananchuk

Aliaksandr Kananchuk

Aliaksandr Kananchuk

Published:

We were engaged in creating a SharePoint add-in, a solution to find pictures on Google and download them to the SharePoint Picture library that would override the standard SharePoint picture/url field functionality. Technically, we needed to override a rendering template for the picture/url field. Beginning with SharePoint 2013, you can achieve it by using the Client-side rendering (CSR) mechanism, which relies on JS code (it's easy to find samples on the Internet). The main idea was to set a JSLink property of the field to a script link with the required JS code. But in case with SharePoint App and Office 365, we encountered several issues that didn't allows us to do it programmatically. Let's have a look.

Issue 1: JSLink functionality is disabled by default in Office 365

To enable this functionality, you need to go to O365 Admin --> SharePoint --> Settings.

Here you have to allow the "Custom Script" option. The system will take around 24 hours to affect the site collection settings. After that, the JSLink option will show up.

The needed options are as follows:

  • Allow users to run custom script on personal sites
  • Allow users to run custom script on self-service created sites

This is how they look by default:

Custom Script option

It is difficult to determine by the option titles whether your default root site is related to these options.

Note! Some users had to wait even more than 24 hours until the change would be implemented.

A deeper investigation has shown that the problem is in the SP.PermissionKind.AddAndCustomizePages permission level.

You can check the current permissions using this JSOM code:


function sharePointReady() {
        this._currentUser = web.get_currentUser();
        context.load(this._currentUser);
        context.load(web, 'EffectiveBasePermissions');
        context.executeQueryAsync(Function.createDelegate(this, onSuccessMethod1), null);
    }

    function onSuccessMethod1(sender, args) {
        if (web.get_effectiveBasePermissions().has(SP.PermissionKind.addAndCustomizePages)) {
            alert('You have permissions');
        }
        else {
            alert('You haven't permissions!');
        }
    }

Workaround! You can apply the new settings right away. To do that, you need to enable custom scripting on a particular site collection immediately via CSOM, JSOM or SharePoint Online Management Shell.

This is the code for SharePoint Online Management Shell:

Set-SPOsite  -DenyAddAndCustomizePages 0

 

Note! In case the Custom Script feature is disabled, you will get Access Denied even if you are the site collection administrator.

Note! If the add-in has less than full control permission, permissions checking code on the host web will return Access Denied when you execute the code on the app web. So even if you have this permission on the host web, you cannot set a JSLink from the app web.

Note! Be careful when you use this code for some site collections. If you set a different configuration on the Office SharePoint Settings page, SharePoint will override your settings within 24 hours. So, the right way to apply the settings immediately is to enable it on the Office 365 settings page first and then set the same configuration with code.

Issue 2. JSLink can be set by the full control permission level for the app. But it is not valid for app to store

If you forget about it, Microsoft Testers Team will let you know, but it is better to know before creating code.

Issue 3. JSLink functionality and minimal download strategy feature

The problem is that regular JS files will not work when the Minimal Download Strategy feature is enabled.

Workaround

Add the following code in the beginning of a JS file:


RegisterModuleInit((_spPageContextInfo.webServerRelativeUrl == "/" "" : 
_spPageContextInfo.webServerRelativeUrl) +
 "/SiteAssets/ImagesUploaderApp/PictureUrlRendering.js", StartExecution);
StartExecution();

 

Where StartExecution is your custom function.

The first line will be used with the enabled MDS feature, the second line is for regular cases.

Note! The Minimal Download Strategy feature is enabled by default on root SharePoint Site in Office 365.

Note! Be careful while testing. If the MDS feature is enabled, and you are on the page where it has effect (URL contains '_layout/15/start.aspx'), any of your code will work if you reload this page (for example, by pushing the F5 button). But you should test the redirection to your target page from the other pages.

Issue 4. The same issue with WebPart JSLink

In this article, we review the issues with JSLink properties on the field level. But these issues are actual for JSLink properties on the others levels, too (for example for WebPart JSLink).

Issue 5. JSLink supports links only from the current site collection

You cannot set a link from the app web to a JSLink property on the host web. That is why we decided to copy the JS/CSS files to the host web and set the JSLink property to URL from the host web (not from the app web).

Issue 6. IE9 Issue doesn't support all HTML5 commands

IE9 does not support the full list of HTML5 commands. You need to have the latest IE9 updates installed for correct work. At the same time, the App in Store should support IE9 by default. So, the easiest solution is to mark your app as IE10+ in the description.

We faced this issue trying to copy a file from the app web to the host web:


sourceExecutor.executeAsync({
                                    url: appweburl + 
"/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + folderUrl + 
"')/Files/add(url='" + targetFileName + "',overwrite='true')?@target='" + hostweburl + "'",
                                    method: "POST",
                                    contentType: "application/json;odata=verbose",
                                    binaryStringRequestBody: true,
                                    body: getFileData.body,
                                    headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": digest },
                                    success: function () {

                                    },
                                    error: errorHandler
                                       });


Conclusion

It is impossible to set a JS link on the host web from the app with a JS code because of permission reasons.

We tried to find a workaround but failed:

Execution of code from the host web:

a) Copy aspx page from the app web to the host web.(Failed) -> Access Denied You can copy JS/CSS files but not ASPX.

b) Copy html page from the app to the host web. (Failed) -> HTML that is stored in library is just for downloading in Office 365

Trying to achieve maximum security, Microsoft isolated the app architecture for the Office Store. In other words, you cannot use the app for a JS injection to the host web. So we suggest setting up a JS link on the web part level manually after having applied all the settings on the app page.

By the way, we can help you create your own app. Apart from providing SharePoint consulting and development services, our team has already delivered several add-ins to the Microsoft AppSource marketplace.

Do you want to adapt SharePoint to your unique business context? Our developers will tune the platform in line with your specific requirements.