Create a content page
Content page is the base level webpage that is rendered within Microsoft Teams client where a developer can add the content of a tab. It allows you to seamlessly integrate your web content within the Teams client, creating a more immersive and engaging environment for users. For instance, you can use content pages to display custom data, integrate third-party services, or create a more personalized user experience. A content page is necessary to create any of the following tabs:
- A personal-scoped custom tab: In this case, the content page is the first page the user encounters.
- A channel or group custom tab: The content page is displayed after the user pins and configures the tab in the appropriate context.
- A dialog: You can create a content page and embed it as a webview inside a dialog (referred as task module in TeamsJS v1.x). The page is rendered inside the modal pop-up.
If you need to add your tab within a channel or group, or personal scope, present an HTML content page in your tab. For static tabs, the content URL is set directly in your app manifest.
This article is specific to using content pages as tabs; however, most of the guidance here applies regardless of how the content page is presented to the user.
Note
This topic reflects version 2.0.x of the Microsoft Teams JavaScript client library (TeamsJS). If you are using an earlier version, refer to the TeamsJS library overview for guidance on the differences between the latest TeamsJS and earlier versions.
Tab content and design guidelines
Your tab's overall objective is to provide access to meaningful and engaging content that has a practical value and a clear purpose.
You need to focus on making your tab design clean, navigation intuitive, and content immersive. For more information, see tab design guidelines and Microsoft Teams Store validation guidelines.
Integrate your code with Teams
To display your page in Teams, you'll need to include the Microsoft Teams JavaScript client library (TeamsJS) in your code and call app.initialize()
after your page loads.
Note
It takes close to 24-48 hours for any content or UI changes to reflect in the tab app due to cache.
The following code is an example of how your page and the Teams client communicate:
<!DOCTYPE html>
<html>
<head>
...
<script src="https://res.cdn.office.net/teams-js/2.2.0/js/MicrosoftTeams.min.js"
integrity="sha384yBjE++eHeBPzIg+IKl9OHFqMbSdrzY2S/LW3qeitc5vqXewEYRWegByWzBN/chRh"
crossorigin="anonymous" >
</script>
<script>
// Initialize the library
await microsoftTeams.app.initialize();
</script>
</head>
<body>
...<h1>Personal Tab</h1>
<p><img src="/assets/icon.png"></p>
<p>This is your personal tab!</p>
</body>
</html>
For more information on how to create and add a content page to a personal tab, see add a content page to the tab.
The following images show the configuration of an HTML content page and the output of content page in tab:
Content page configuration
Output in web
Output in tab
Access additional content
You can access additional content by using TeamsJS to interact with Teams, creating deep links, using dialogs, and verifying if URL domains are included in the validDomains
array.
Use TeamsJS to interact with Teams: The Microsoft Teams JavaScript client library provides many more functions that you can find useful while developing your content page.
Deep links: You can create deep links to entities in Teams. They're used to create links that navigate to content and information within your tab. For more information, see create deep links to content and features in Teams.
Dialogs: A dialog is a modal pop-up experience that you can trigger from your tab. Use dialogs in a content page to present forms for gathering additional information, displaying the details of an item in a list, or presenting the user with additional information. The dialogs themselves can be additional content pages or created completely using Adaptive Cards. For more information, see using dialogs in tabs.
Valid domains: Ensure that all URL domains used in your tabs are included in the
validDomains
array in your app manifest. For more information, see validDomains.
Note
The core functionality of your tab exists within Teams and not outside of Teams.
Show a native loading indicator
You can configure and show a native loading indicator to a tab. You can provide a native loading indicator starting with manifest schema v1.7. For example, tab content page, configuration page, removal page, and dialogs in tabs.
Note
The behavior on mobile clients isn't configurable through the native loading indicator property. Mobile clients show this indicator by default across content pages and iframe-based dialogs. This indicator on mobile is shown when a request is made to fetch content and gets dismissed as soon as the request gets completed.
If you indicate showLoadingIndicator : true
in your app manifest, then all tab configuration, content, removal pages, and all iframe-based dialogs must follow these steps:
Use the following steps to show the native loading indicator:
Add
"showLoadingIndicator": true
to your app manifest.Call
app.initialize();
.Call
app.notifySuccess()
in all iframe-based contents to notify Teams that your app has successfully loaded. If applicable, Teams hides the loading indicator. IfnotifySuccess
isn't called within 30 seconds, Teams assumes that your app has timed out, and displays an error screen with a retry option. For app updates, this step is applicable for already configured tabs. If you don't perform this step, an error screen is displayed for the existing users. [Mandatory]If you're ready to print to the screen and wish to lazy load the rest of your application's content, you can hide the loading indicator manually by calling
app.notifyAppLoaded();
. [Optional]If your application doesn't load, you can call
app.notifyFailure({reason: app.FailedReason.Timeout, message: "failure message"});
to let Teams know about the failure. Themessage
property isn't used, therefore the failure message doesn't appear in the UI, and a generic error screen appears to the user. The following code shows the enumeration that defines the possible reasons you can indicate for the application's failure to load:/* List of failure reasons */ export const enum FailedReason { AuthFailed = "AuthFailed", Timeout = "Timeout", Other = "Other" }