Skip to main content

Siteimprove CMS Plugin SDK

General

Token endpoint: https://my2.siteimprove.com/auth/token?cms=nameOfCMS

  • Authentication is not needed to reach this endpoint.
  • Returns a json payload with one key token.
  • The token should be persisted in the CMS.
  • The url parameter "cms" is the name and version of the CMS, e.g. Drupal 8. You can use spaces using normal URL encoding such as cms=Drupal%208.

Script: https://cdn.siteimprove.net/cms/overlay-latest.js. See more details about script versioning below.

Script

The script's functionality is available globally under the name _si.

  • It has 8 core functions:

    • input(url, token, callback) is used by the CMS to inform the plugin that we're at a place in the CMS where a single page is in context and that we're on a page that might have been checked by Siteimprove. The "callback" parameter is optional (or can be set as null) but when set, will be called when data has been successfully fetched. The token has to be provided, and be the value from the token endpoint above. You can also provide an empty URL (or null) and the plugin will know that no page is currently in context and clear out existing data.

    • clear(callback, token) is used by the CMS to inform the plugin that the previously passed URL for the input function is not longer in scope and the results should be cleared. Use this function if the CMS is navigating away from editing a page and e.g. going to a settings page. This is the same as calling input with an empty or null URL, and the "callback" and "token" parameters are the same as above.

      Note that the "token" parameter was added as part of version 2 of the plugin and was therefor added as the last parameter even though the "callback" parameter is optional. We consider "token" as mandatory with the newest version because the plugin can now also be initialized with clear, and we need the token upon initialization.

    • recheck(url, token, callback) is used by the CMS to start a full recheck of a single page outside of the regular Siteimprove crawl schedule, and can be used by the CMS for either a user action or called automatically when a new version of a page is published. The "url" parameter is the page to recheck and "callback" and "token" is used the same way as above. Note that the callback is called when the recheck is successfully ordered and not finished.

    • contentcheck(content, url, token, callback) is used by the CMS to push the HTML content of a page and run checks before the page is published. Content - the html content (as text) to be checked before publishing. The URL is optional but when provided it is used to provide better context to the checks - e.g. for resolving relative resource links in the page. The URL doesn't have to be the same as the provided URL in the input call and is handled separately by the content check. The "token" and "callback" parameters are the same as for the above calls.

    • contentcheck-flat-dom(contentDOM, url, token, callback) is used by the CMS to push a DOM reference for the plugin to traverse and run checks before the page is published (previously known as "contentcheck", but now called "prepublish check"). The URL is optional but when provided it is used to provide better context to the checks - e.g. for resolving relative resource links in the DOM. The URL doesn't have to be the same as the provided URL in the input call and is handled separately by the content check. The "token" and "callback" parameters are the same as for the above calls.

      The DOM reference must be the DOM node of the rendered page - it can be the Document node of an <iframe> or a new window, but the content must be done rendering before calling this function, and the content must be accessible with JavaScript (so on the same domain to avoid XSS errors). This will trigger a JavaScript "traversal" of the DOM, which is then uploaded and analyzed by Siteimprove.

      It is possible to also call this function after having called clear, in which case we will show the plugin in a special prepublish-only mode where we focus on just prepublish and we don't display data about the last crawl data for the selected page. This mode can be used to check issues on a DOM that is not a full page such as a shared component, snippet or widget.

    • contentcheck-zip(zip, url, token, callback) is a function that can be used by the CMS to check ZIP files before publishing. The first parameter is a zipped archive in file bytes containing the ZIP content to be checked, as well inside any related js- or css-files. The second parameter is an optional URL which can provide better context for the checks, especially for resolving relative resource links in the page. The URL doesn't have to be the same as the provided URL in the input call and is handled separately by the content check. The "token" and "callback" parameters are the same as for the above calls.

      Upon calling this function, the content will be sent to the ContentCheck API for analysis. The API will take into account any scripts and stylesheets included in the archive when analyzing the HTML.

    • registerPrepublishCallback(callback) is used by the CMS to provide a way for the CMS plugin to ask for the DOM reference for running a prepublish "content check" test on the current page. In version 2 of the plugin we have added the ability to start the prepublish check from inside the CMS plugin itself as research has found that the feature could be hard to discover. If the CMS registers a callback with this method, the plugin will then show a button to "pull" the DOM from the CMS to be checked, but the CMS is also able to "push" the DOM to the plugin with the contentcheck-flat-dom method.

      The "callback" parameter can also be null, in which case the CMS plugin will dynamically remove the button to pull the DOM again. So the CMS should call this method with either a valid callback or null depending on if we're in a situation where it's possible to collect the DOM.

      The callback method must provide the DOM of the rendered page, which can be the Document node of an <iframe> or a new window, but the content must be accessible with javascript (so on the same domain to avoid XSS errors). This will be used in a JavaScript "traversal" of the DOM, which is then uploaded and analyzed by Siteimprove.

      The callback method must have one of the following signatures:

      function() : [Promise<document>, function(): void]
      function() : Promise<document>
      function() : [document, function(): void]
      function() : document
      

      The way the DOM is returned can be either as a Promise the resolves into a document element, or just the document element itself. If you end up opening a window or <iframe> "on demand", it may be useful to return a promise that resolves once the document is done rendering (by tying it up to a window event). However, if you already have a "preview" of the content open, you can simply return the document element.

      Either the callback returns just the DOM element, or an array with the DOM and a function that will be invoked once the DOM is analyzed - this function can be used for closing a window or <iframe> that may have been opened specifically for rendering the DOM.

    • onHighlight(callback) takes one parameter - the callback which will be called when trying to highlight an issue in the CMS. You can set the callback at any time and you can set it to null if highlighting is not supported at some point. The callback will receive one parameter structured like this, where offset is optional:

        {
            highlights: [
                { selector: "<string>", offset: { start: <number>, length: <number> } },
                { selector: "<string>" } },
                ...
            ]
        }
    
  • It has 1 utility function:

    • showlog() with no parameters. This will show an internal log for the script. This way it is possible to see what is going on inside the script.

Script versioning

The current version of the CMS plugin SDK is 2.x and a few breaking changes were made to the original 1.x version:

  • The domain function is no-longer supported. The function was used for the CMS plugin to show site-wide information, but this has now been deprecated and we focus only on page-specific issues.
  • The recrawl function is no-longer supported. The function was used to trigger a full crawl of the whole site, but now the focus is on individual pages instead.
  • The clear function now also takes in the token as a paramater. This is because clear may also be used to initialize the plugin, at which point we need to know the token.

Originally the script path was https://cdn.siteimprove.net/cms/overlay.js and for backwards compatibility this path still servers the original version.

To better support future updates, we are now publishing several versions of overlay.js and are changing the recommendation to use the following:

At some point we will fully deprecate version 1.x and at that point https://cdn.siteimprove.net/cms/overlay.js will serve the version 2.x code as well. We now recommend all CMS's to switch to using https://cdn.siteimprove.net/cms/overlay-latest.js going forward.

Order of function calls

The CMS plugin is initialized when you call either input or clear, so make sure these are the first calls you make. registerPrepublishCallback and onHighlight can be called at any time. contentcheck-flat-dom can be called either after a call to input or clear.

Using the functions

In order to handle the script being loaded asynchronously, the script functionality is used in a different way than just a function call in the variable. But it means a little bit extra work when calling function in _ si

  • Input function
var _si = window._si || [];
_si.push([
    "input",
    "<url-goes-here>",
    "<token-goes-here>",
    function () {
        console.log("Inputted page specific url to Siteimprove");
    },
]);
  • Clear function
var _si = window._si || [];
_si.push([
    "clear",
    function () {
        console.log("Cleared");
    },
    "<token-goes-here>",
]);
  • ContentcheckFlatDom function
var _si = window._si || [];
_si.push([
    "contentcheck-flat-dom",
    domContent,
    "<url-goes-here>",
    "<token-goes-here>",
    function () {
        console.log("Pre-publish check ordered (flat dom version)");
    },
]);
  • ContentcheckZip function
var _si = window._si || [];
_si.push([
    "contentcheck-zip",
    zipFileInBytes,
    "<url-goes-here>",
    "<token-goes-here>",
    function () {
        console.log("Pre-publish check ordered (zip version)");
    },
]);
  • RegisterPrepublishCallback function
var _si = window._si || [];
_si.push(["registerPrepublishCallback", getDomCallback]);

// To disable prepublish again
_si.push(["registerPrepublishCallback", null]);
  • onHighlight function
var _si = window._si || [];
_si.push([
    "onHighlight",
    function (highlightInfo) {
        console.log("Highlight " + highlightInfo);
    },
]);
// Example implementation of rendering the page in a popup window
var getDomCallback = async function () {
    var pageWindow = window.open(
        pageUrl,
        "Page Preview",
        "width=400,height=500"
    );
    var promise = new Promise(function (resolve, reject) {
        pageWindow.addEventListener(
            "load",
            () => {
                resolve(pageWindow.document);
            },
            { once: true }
        );
    });

    var document = await promise;
    return [
        document,
        () => {
            pageWindow.close();
        },
    ];
};

How to provide the best Prepublish experience

To provide the best and fastest prepublish experience, we suggest to use the direct DOM method (or "FlatDOM") where Siteimprove receives a DOM reference through either the contentcheck-flat-dom or registerPrepublishCallback methods. For this to work, however, the CMS has to generate the DOM for the page and this can provide some challenges:

  • If the DOM is not automatically available, we suggest to create a new <iframe> on the page, render it there and then pass the CMS plugin the DOM from there.

  • Some checks might be dependent on the screen size, so the <iframe> should have the same size as current view.

  • What we have found to work it to dynamically (with JavaScript) add a new <div> add the end of <body>. In this, create a new <iframe> element with the url that renders a preview of the page. Finally, set style='height:100vh; width:100%' to the <iframe> to get it to render at the bottom of the document but with same height and width as the main page.

  • Make sure to only render the actual concent of the page in the new <iframe>; No extra menus from the CMS and don't load the Siteimprove overlay script which will render the CMS plugin icon in the side.

  • Add an event handler in JavaScript for the load event on the <iframe> and in there you can get the DOM reference through contentWindow.document on the <iframe> element. Once the contentcheck-flat-dom or registerPrepublishCallback is done, the <iframe> and <div> can be removed again.

Server-side recheck or recrawl

As well as the client-side call to recheck a single page as listed above, we also offer rechecks and recrawls initiated by the CMS server-side using a HTTP REST endpoint. It must be called by a HTTP POST to this endpoint: https://api-gateway.siteimprove.com/cms-recheck. The endpoint will receive a JSON payload describing the URL, token and type of check.

Recheck page

{
    "url": "url",
    "token": "token",
    "type": "recheck"
}

Recrawl site

{
    "url": "url",
    "token": "token",
    "type": "recrawl"
}

The Siteimprove icon

If you need to show the official Siteimprove icon on a button or other action in the CMS, we suggest using this official SVG:

<svg xmlns="http://www.w3.org/2000/svg" height="28px" width="28px" viewBox="0 0 24 24" focusable="false" aria-hidden="true" fill="currentColor">
   <path fill="#141155" d="M12.015625.113281C5.433594.113281.113281 5.433594.113281 12.015625c0 6.578125 5.320313 11.886719 11.902344 11.886719 6.578125 0 11.886719-5.324219 11.886719-11.886719 0-6.566406-5.324219-11.902344-11.886719-11.902344Zm0 0"></path>
   <path fill="#fff" d="m6.097656 14.796875 1.695313-1.003906c.367187.945312 1.074219 1.539062 2.328125 1.539062 1.257812 0 1.625-.507812 1.625-1.074219 0-.746093-.679688-1.042968-2.1875-1.480468-1.539063-.4375-3.050782-1.074219-3.050782-3.007813 0-1.933593 1.609376-2.992187 3.332032-2.992187s2.9375.847656 3.613281 2.257812l-1.664063.960938c-.367187-.777344-.917968-1.300782-1.949218-1.300782-.832032 0-1.328125.4375-1.328125 1.019532 0 .621094.382812.945312 1.921875 1.410156 1.609375.523438 3.316406 1.058594 3.316406 3.121094 0 1.890625-1.523438 3.046875-3.671875 3.046875-2.058594.015625-3.441406-.972657-3.980469-2.496094m8.667969-6.917969c0-.621094.507813-1.160156 1.144531-1.160156.636719 0 1.15625.539062 1.15625 1.160156 0 .621094-.507812 1.140625-1.15625 1.140625-.648437 0-1.144531-.519531-1.144531-1.140625m.214844 1.988282h1.863281v7.230468h-1.863281Zm0 0"></path>
</svg>