Add tabs on backlog pages

Last Update: 11/29/2016

If you have a web page that can be hosted in an iframe, it can be hosted in Visual Studio Team Services as a tab on the backlog pages. In this example, we'll add a simple Hello World tab on the Product Backlog and the Iteration Backlog.

Tab location on the Visual Studio Team Services Product backlog page

Tab location on the Visual Studio Team Services Product backlog page

Create your web page

  1. Get the Client SDK VSS.SDK.js file and add it to your web app. Place it in the home/sdk/scripts folder.

    1. Use the 'npm install' command to retrieve the SDK: npm install vss-web-extension-sdk.
    2. To learn more about the SDK, visit the Client SDK Github Page.
  2. Add the web page that you want to display as a hub. We're doing a simple hello-world.html page here, added to the home directory.

  3. In your HTML page, add a reference to the SDK, and call init() and notifyLoadSucceeded().

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Hello World</title>
        <script src="sdk/scripts/VSS.SDK.js"></script>
    </head>
    <body>
        <script type="text/javascript">VSS.init();</script>
        <h1>Hello World</h1>
        <script type="text/javascript">VSS.notifyLoadSucceeded();</script>
    </body>
    </html>
    

Update your extension manifest

Update your extension manifest file with the following code:

...

    "contributions": [
        {
            "id": "Fabrikam.HelloWorld.Backlog.Tabs",
            "type": "ms.vss-web.tab",
            "description": "Adds a 'Hello' tab to the Product and Iteration backlog tabs.",
            "targets": [
                "ms.vss-work-web.product-backlog-tabs",
                "ms.vss-work-web.iteration-backlog-tabs",
            ],
            "properties": {
                "name": "Hello",
                "uri": "hello-world.html",
                "registeredObjectId": "backlogTabObject"
            }
        }
    ],
    "scopes": [
        "vso.work"
    ],
    "files": [
        {
            "path": "hello-world.html", "addressable": true
        },
        {
            "path": "scripts", "addressable": true
        },
        {
            "path": "sdk/scripts", "addressable": true
        },
        {
            "path": "images/logo.png", "addressable": true
        }
    ]
...

Contributions

The contributions stanza contains information about your tasks.

For each contribution in your extension, the manifest defines

  • the type of contribution (tab in this case),
  • the contribution target (the product or iteration backlog tabs in this case),
  • and the properties that are specific to each type of contribution. For a tab, we have
    Property Description
    name name of the hub
    uri path (relative to the extension's baseUri) of the page to surface as the tab
    registeredObjectId Id of the object registered for the tab. Include code like the example below in the html file indicated in the "uri" property of the contribution shown above.

Scopes

It includes the scopes that your extension requires. In this case, we need vso.work to access work items.

Files

Include all of the files your extension will access.
For your files, set addressable to true unless you include other files that don't need to be URL-addressable.

Example registeredObjectId

VSS.register("backlogTabObject", {
    pageTitle: function(state) {
        return "Hello Tab";
    },
    updateContext: function(tabContext) {                            
    },
    isInvisible: function(state) {
        return false;
    },
    isDisabled: function(state) {
        return false;
    }
});

Learn about all of the places where you can add a hub in the contributions reference.

Next Steps:

Now that you've written your extension, the next steps are to Package, Publish, and Install your extension. You can also check out the documentation for Testing and Debugging your extension.