Updates from: 05/26/2022 01:19:23
Service Microsoft Docs article Related commit history on GitHub Change details
platform Deep Links https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/build-and-test/deep-links.md
ms.localizationpriority: high
# Create deep links
-You can create links to information and features within Teams. The scenarios where creating deep links are useful are as follows:
+Deep links are a navigation mechanism that you can use to connect users with information and features within Teams and Teams apps. Some scenarios where creating deep links can be useful are as follows:
* Navigating the user to the content within one of your app's tabs. For instance, your app can have a bot that sends messages notifying the user of an important activity. When the user taps on the notification, the deep link navigates to the tab so that the user can view more details about the activity.
-* Your app automates or simplifies certain user tasks, such as creating a chat or scheduling a meeting, by pre populating the deep links with required parameters. This avoids the need for users to manually enter information.
+* Your app automates or simplifies certain user tasks, such as creating a chat or scheduling a meeting, by pre-populating the deep links with required parameters. This avoids the need for users to manually enter information.
+
+The Microsoft Teams JavaScript client SDK (TeamsJS) simplifies the process of navigation. For many scenarios, such as navigating to content and information within your tab or even launching a chat dialog, the SDK provides strongly typed APIs that make for an improved experience and can replace the usage of deep links. These APIs are recommended for Teams apps that might be run in other hosts (Outlook, Office), as they also provide a way to check that the capability being used is supported by that host. The following sections show information about deep linking, but also highlight how scenarios that used to require it have changed with the v2 release of TeamsJS.
+ > [!NOTE] >
-> A deeplink launches the browser first before navigating to content. The behaviour of deep links on Teams entities are as follows:
+> The behavior of deep links is dependent on a number of factors. The following list outlines the behavior of deep links on Teams entities.
> > **Tab**:
-> Γ£ö Directly navigates to the deeplink url.
+> Γ£ö Directly navigates to the deep link url.
> > **Bot**:
-> Γ£ö Deeplink in card body: Opens in browser first.
-> Γ£ö Deeplink added to OpenURL action in Adaptive Card: Directly navigates to the deeplink url.
+> Γ£ö Deep link in card body: Opens in browser first.
+> Γ£ö Deep link added to OpenURL action in Adaptive Card: Directly navigates to the deep link url.
> Γ£ö Hyperlink markdown text in the card: Opens in browser first. > > **Chat**:
-> Γ£ö Text message hyperlink markdown: Directly navigates to deeplink url.
-> Γ£ö Link pasted in general chat conversation: Directly navigates to deeplink url.
+> Γ£ö Text message hyperlink markdown: Directly navigates to deep link url.
+> Γ£ö Link pasted in general chat conversation: Directly navigates to deep link url.
+>
+>
+>The navigation behavior of a Teams app extended across Microsoft 365 (Outlook/Office) is dependent on two factors:
+>
+> * The target that the deep link points to
+> * The host where the Teams app is running
+>
+> If the Teams app is running within the host where the deep link is targeted, your app will open directly within the host. However, if the Teams app is running in a different host from where the deep link is targeted, the app will first open in the browser.
+
+## Deep link to your tab
+
+You can create deep links to entities in Teams apps. This method is used to create links that navigate to content and information within your tab. For example, if your tab contains a task list, team members can create and share links to individual tasks. When you select the link, it navigates to your tab that focuses on the specific item.
+
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+To implement this, add a **copy link** action to each item, in whatever way best suits your UI. When the user takes this action, call [pages.shareDeepLink()](/javascript/api/@microsoft/teams-js/pages?view=msteams-client-js-latest#@microsoft-teams-js-pages-sharedeeplink&preserve-view=true) to display a dialog box containing a link that the user can copy to the clipboard. When you make this call, pass an ID for your item, which you get back in the [context](~/tabs/how-to/access-teams-context.md) when the link is followed and your tab is reloaded.
+
+```javascript
+pages.shareDeepLink({ subPageId: <subPageId>, subPageLabel: <subPageLabel>, subPageWebUrl: <subPageWebUrl> })
+```
+
+You will need to replace the fields with the appropriate information:
+
+* `subPageId`: A unique identifier for the item within your page to which you're deep linking.
+* `subPageLabel`: A label for the item to use for displaying the deep link.
+* `subPageWebUrl`: A fallback URL to use if the client can't render the page.
-## Deep linking to your tab
+For more information see, [pages.shareDeepLink()](/javascript/api/@microsoft/teams-js/pages?view=msteams-client-js-latest#@microsoft-teams-js-pages-sharedeeplink&preserve-view=true).
-You can create deep links to entities in Teams. This is used to create links that navigate to content and information within your tab. For example, if your tab contains a task list, team members can create and share links to individual tasks. When you select the link, it navigates to your tab that focuses on the specific item. To implement this, you add a **copy link** action to each item, in whatever way best suits your UI. When the user takes this action, you call `shareDeepLink()` to display a dialog box containing a link that the user can copy to the clipboard. When you make this call, you also pass an ID for your item, which you get back in the [context](~/tabs/how-to/access-teams-context.md) when the link is followed and your tab is reloaded.
+# [TeamsJS v1](#tab/teamsjs-v1)
+
+To implement this, you add a **copy link** action to each item, in whatever way best suits your UI. When the user takes this action, you call `shareDeepLink()` to display a dialog box containing a link that the user can copy to the clipboard. When you make this call, you also pass an ID for your item, which you get back in the [context](~/tabs/how-to/access-teams-context.md) when the link is followed and your tab is reloaded.
+
+```javascript
+microsoftTeams.shareDeepLink({ subEntityId: <subEntityId>, subEntityLabel: <subEntityLabel>, subEntityWebUrl: <subEntityWebUrl> })
+```
+
+You will need to replace the fields with the appropriate information:
+
+* `subEntityId`: A unique identifier for the item within your tab to which you're deep linking.
+* `subEntityLabel`: A label for the item to use for displaying the deep link.
+* `subEntityWebUrl`: An optional field with a fallback URL to use if the client doesn't support rendering the tab.
++ Alternatively, you can also generate deep links programmatically, using the format specified later in this article. You can use deep links in [bot](~/bots/what-are-bots.md) and [connector](~/webhooks-and-connectors/what-are-webhooks-and-connectors.md) messages that inform users about changes to your tab, or to items within it.
Alternatively, you can also generate deep links programmatically, using the form
>[!IMPORTANT] > Currently, shareDeepLink does not work on mobile platforms.
-### Show a deep link to an item within your tab
-
-To show a dialog box that contains a deep link to an item within your tab, call `microsoftTeams.shareDeepLink({ subEntityId: <subEntityId>, subEntityLabel: <subEntityLabel>, subEntityWebUrl: <subEntityWebUrl> })`.
+### Consume a deep link from a tab
-Provide the following fields:
+When navigating to a deep link, Microsoft Teams simply navigates to the tab and provides a mechanism through the Microsoft Teams JavaScript library to retrieve the sub-page ID if it exists.
-* `subEntityId`: A unique identifier for the item within your tab to which you're deep linking.
-* `subEntityLabel`: A label for the item to use for displaying the deep link.
-* `subEntityWebUrl`: An optional field with a fallback URL to use if the client doesn't support rendering the tab.
+The [`app.getContext()`](/javascript/api/@microsoft/teams-js/app?view=msteams-client-js-latest#@microsoft-teams-js-app-getcontext&preserve-view=true) call (`microsoftTeams.getContext()`) in TeamsJS v1) returns a promise that will resolve with the context that includes the `subPageId` property (subEntityId for TeamsJS v1) if the tab is navigated through a deep link. For more information see [PageInfo interface](/javascript/api/@microsoft/teams-js/app?view=msteams-client-js-latest#@microsoft-teams-js-app-pageinfo&preserve-view=true).
### Generate a deep link to your tab
+While it is recommended to use `shareDeepLink()` to generate a deep link to your tab, it is possible to manually create one too.
+ > [!NOTE] > > * Personal tabs have a `personal` scope, while channel and group tabs use `team` or `group` scopes. The two tab types have a slightly different syntax since only the configurable tab has a `channel` property associated with its context object. See the [manifest](~/resources/schem) reference for more information on tab scopes.
The query parameters are:
>`https://teams.microsoft.com/l/entity/fe4a8eba-2a31-4737-8e33-e5fae6fee194/tasklist123?webUrl=https://tasklist.example.com/123/456&label=Task 456?context={"chatId": "17:b42de192376346a7906a7dd5cb84b673@thread.v2","contextType":"chat"}` > [!IMPORTANT]
-> Ensure that all query parameters are properly URI encoded. You must follow the preceeding examples using the last example:
+> Ensure that all query parameters are properly URI encoded. You must follow the preceding examples using the last example:
> > ```javascript > var encodedWebUrl = encodeURI('https://tasklist.example.com/123/456&label=Task 456');
The query parameters are:
> var taskItemUrl = 'https://teams.microsoft.com/l/entity/fe4a8eba-2a31-4737-8e33-e5fae6fee194/tasklist123?webUrl=' + encodedWebUrl + '&context=' + encodedContext; > ```
-### Consume a deep link from a tab
+## Navigation from your tab
+
+You can navigate to content in Teams from your tab using TeamsJS or deep links. This is useful if your tab needs to connect users with other content in Teams, such as to a channel, message, another tab or even to open a scheduling dialog. Formerly, navigation might have required a deep link, but it can now in many instances be accomplished using the SDK. The following sections show both methods, but where possible use of the strongly typed capabilities of the SDK is recommended.
-When navigating to a deep link, Microsoft Teams simply navigates to the tab and provides a mechanism through the Microsoft Teams JavaScript library to retrieve the sub-entity ID if it exists.
+One of the benefits of using TeamsJS, particularly for Teams apps that might run in other hosts (Outlook and Office), is that it's possible to check that the host supports the capability you're attempting to use. To check a host's support of a capability, you can use the `isSupported()` function associated with the namespace of the API. The TeamsJS SDK organizes APIs into capabilities by way of namespaces. For example, prior to usage of an API in the `pages` namespace you can check the returned boolean value from `pages.isSupported()` and take the appropriate action within the context of your app and apps UI.
-The [`microsoftTeams.getContext`](/javascript/api/@microsoft/teams-js#getcontext--context--context--void-) call returns a context that includes the `subEntityId` field if the tab is navigated through a deep link.
+For additional information about capabilities and the APIs in TeamsJS, see [Building tabs and other hosted experiences with the Microsoft Teams JavaScript client SDK](~/tabs/how-to/using-teams-client-sdk.md#apis-organized-into-capabilities).
-## Deep linking from your tab
+### Navigate within your app
-You can deep link to content in Teams from your tab. This is useful if your tab needs to link to other content in Teams, such as to a channel, message, another tab or even to open a scheduling dialog. To trigger a deeplink from your tab, call:
+It is possible to navigate within an app using TeamsJS. The following code demonstrates how to navigate to a specific entity within your Teams app.
-```Javascript
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+You can trigger a navigation from your tab using the [pages.navigateToApp()](/javascript/api/@microsoft/teams-js/pages?view=msteams-client-js-latest#@microsoft-teams-js-pages-navigatetoapp&preserve-view=true) function as shown in the following code:
+
+```javascript
+if (pages.isSupported()) {
+ const navPromise = pages.navigateToApp({ appId: <appId>, pageId: <pageId>, webUrl: <webUrl>, subPageId: <subPageId>, channelId:<channelId>});
+ navPromise.
+ then((result) => {/*Successful navigation*/}).
+ catch((error) => {/*Failed navigation*/});
+}
+else { /* handle case where capability isn't supported */ }
+```
+
+For more information about using the pages capability, see [pages.navigateToApp()](/javascript/api/@microsoft/teams-js/pages?view=msteams-client-js-latest#@microsoft-teams-js-pages-navigatetoapp&preserve-view=true) and the [pages](/javascript/api/@microsoft/teams-js/pages?view=msteams-client-js-latest&preserve-view=true) namespace for other navigation options. If needed, it is also possible to directly open a deep link using the [app.openLink()](/javascript/api/@microsoft/teams-js/app?view=msteams-client-js-latest#@microsoft-teams-js-app-openlink&preserve-view=true) function.
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+
+To trigger a deep link from your tab, call:
+
+```javascript
microsoftTeams.executeDeepLink(/*deepLink*/); ```
-This call navigates you to the correct URL, or trigger a client action, such as opening a scheduling or app install dialog. See the following example:
++
+### Open a scheduling dialog
+
+You can open a scheduling dialog from your Teams app, as shown in the following code. This is especially useful if your app helps the user complete calendar or scheduling related tasks.
+
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```javascript
+// Open a scheduling dialog from your tab
+if(calendar.isSupported()) {
+ const calendarPromise = calendar.composeMeeting({
+ attendees: ["joe@contoso.com", "bob@contoso.com"],
+ content: "test content",
+ endTime: "2018-10-24T10:30:00-07:00"
+ startTime: "2018-10-24T10:00:00-07:00"
+ subject: "test subject"});
+ calendarPromise.
+ then((result) => {/*Successful operation*/}).
+ catch((error) => {/*Unsuccessful operation*/});
+}
+else { /* handle case where capability isn't supported */ }
+```
+
+For more information about working with the calendar see, the [calendar](/javascript/api/@microsoft/teams-js/calendar?view=msteams-client-js-latest&preserve-view=true) namespace in the API reference documentation.
+
+# [TeamsJS v1](#tab/teamsjs-v1)
-```Javascript
+```javascript
// Open a scheduling dialog from your tab microsoftTeams.executeDeepLink("https://teams.microsoft.com/l/meeting/new?subject=test%20subject&attendees=joe@contoso.com,bob@contoso.com&startTime=10%2F24%2F2018%2010%3A30%3A00&endTime=10%2F24%2F2018%2010%3A30%3A00&content=ΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïtest%3AcontentΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇï");
+```
+++
+#### Generate a deep link to the scheduling dialog
+While it's recommended to use the strongly typed APIs of TeamsJS, it is possible to manually create deep links to the Teams built-in scheduling dialog. Use the following format for a deep link that you can use in a bot, Connector, or message extension card:
+`https://teams.microsoft.com/l/meeting/new?subject=<meeting subject>&startTime=<date>&endTime=<date>&content=<content>&attendees=<user1>,<user2>,<user3>,...`
+
+Example: `https://teams.microsoft.com/l/meeting/new?subject=test%20subject&attendees=joe@contoso.com,bob@contoso.com&startTime=10%2F24%2F2018%2010%3A30%3A00&endTime=10%2F24%2F2018%2010%3A30%3A00&content=ΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïtest%3AcontentΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇï`
+
+> [!NOTE]
+> The search parameters don't support `+` signal in place of whitespace (` `). Ensure your uri encoding code returns `%20` for spaces for example, `?subject=test%20subject` is good, but `?subject=test+subject` is bad.
+
+The query parameters are:
+
+* `attendees`: The optional comma-separated list of user IDs representing the attendees of the meeting. The user performing the action is the meeting organizer. Currently, the User ID field supports only the Azure AD UserPrincipalName, typically an email address.
+* `startTime`: The optional start time of the event. This should be in [long ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601), for example *2018-03-12T23:55:25+02:00*.
+* `endTime`: The optional end time of the event, also in ISO 8601 format.
+* `subject`: An optional field for the meeting subject.
+* `content`: An optional field for the meeting details field.
+
+> [!NOTE]
+> Currently, specifying the location isn't supported. You must specify the UTC offset, it means time zones when generating your start and end times.
+
+To use this deep link with your bot, you can specify this as the URL target in your card's button or tap action through the `openUrl` action type.
+
+### Open an app install dialog
+
+You can open an app install dialog from your Teams app, as shown in the following code.
+
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```javascript
+// Open an app install dialog from your tab
+if(appInstallDialog.isSupported()) {
+ const dialogPromise = appInstallDialog.openAppInstallDialog({ appID: <appId>});
+ dialogPromise.
+ then((result) => {/*Successful operation*/}).
+ catch((error) => {/*Unsuccessful operation*/});
+}
+else { /* handle case where capability isn't supported */ }
+```
+
+For more information about the install dialog see the [appInstallDialog.openAppInstallDialog()](/javascript/api/@microsoft/teams-js/appinstalldialog?view=msteams-client-js-latest#@microsoft-teams-js-appinstalldialog-openappinstalldialog&preserve-view=true) function in the API reference documentation.
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+
+```javascript
// Open an app install dialog from your tab microsoftTeams.executeDeepLink("https://teams.microsoft.com/l/app/f46ad259-0fe5-4f12-872d-c737b174bcb4"); ```
-## Deep linking to a chat
++
+### Navigate to a chat
-You can create deep links to private chats between users by specifying the set of participants. If a chat doesnΓÇÖt exist with the specified participants, the link navigates the user to an empty new chat. New chats are created in draft state until the user sends the first message. Otherwise, you can specify the name of the chat if it doesnΓÇÖt already exist, along with text that should be inserted into the user's compose box. You can think of this feature as a shortcut for the user taking the manual action of navigating to or creating the chat, and then typing out the message.
+You can navigate to or create private chats between users with TeamsJS by specifying the set of participants. If a chat doesnΓÇÖt exist with the specified participants, the user is navigated to an empty new chat. New chats are created in draft state until the user sends the first message. Otherwise, you can specify the name of the chat if it doesnΓÇÖt already exist, along with text that should be inserted into the user's compose box. You can think of this feature as a shortcut for the user taking the manual action of navigating to or creating the chat, and then typing out the message.
-As an example use case, if youΓÇÖre returning an Office 365 user profile from your bot as a card, this deep link can allow the user to easily chat with that person.
+As an example use case, if youΓÇÖre returning an Office 365 user profile from your bot as a card, this deep link can allow the user to easily chat with that person. The following example demonstrates how to open a chat message to a group of participants with an initial message.
-### Generate a deep link to a chat
+```javascript
+if(chat.isSupported()) {
+ const chatPromise = chat.openGroupChat({ users: ["joe@contoso.com","bob@contoso.com"], topic: "Prep For Meeting Tomorrow", message: "Hi folks kicking off chat about our meeting tomorrow"});
+ chatPromise.
+ then((result) => {/*Successful operation*/}).
+ catch((error) => {/*Unsuccessful operation*/});
+}
+else { /* handle case where capability isn't supported */ }
+```
-Use this format for a deep link that you can use in a bot, connector, or message extension card:
+While use of the strongly typed APIs is recommended, you can alternatively use the following format for a manually created deep link that you can use in a bot, connector, or message extension card:
`https://teams.microsoft.com/l/chat/0/0?users=<user1>,<user2>,...&topicName=<chat name>&message=<precanned text>`
The query parameters are:
To use this deep link with your bot, specify this as the URL target in your card's button or tap action through the `openUrl` action type.
-## Generate deep links to channel conversation
+### Generate deep links to channel conversation
Use this deep link format to navigate to a particular conversation within channel thread:
The query parameters are:
> [!NOTE] > You can see `channelId` and `groupId` in the URL from the channel.
-## Generate deep links to file in channel
+### Generate deep links to file in channel
The following deep link format can be used in a bot, connector, or message extension card:
The following example format illustrates the deep link to files:
`https://teams.microsoft.com/l/file/5E0154FC-F2B4-4DA5-8CDA-F096E72C0A80?tenantId=0d9b645f-597b-41f0-a2a3-ef103fbd91bb&fileType=pptx&objectUrl=https%3A%2F%2Fmicrosoft.sharepoint.com%2Fteams%2FActionPlatform%2FShared%20Documents%2FFC7-%20Bot%20and%20Action%20Infra%2FKaizala%20Actions%20in%20Adaptive%20Cards%20-%20Deck.pptx&baseUrl=https%3A%2F%2Fmicrosoft.sharepoint.com%2Fteams%2FActionPlatform&serviceName=teams&threadId=19:f8fbfc4d89e24ef5b3b8692538cebeb7@thread.skype&groupId=ae063b79-5315-4ddb-ba70-27328ba6c31e`
-### Serialization of this object
+#### Serialization of this object
```javascript {
groupId: "ae063b79-5315-4ddb-ba70-27328ba6c31e"
} ```
-## Deep linking to an app
+### Deep linking to an app
-Create deeplinks for the app after the app is listed in the Teams store. To create a link to launch Teams, append the app ID to the following URL: `https://teams.microsoft.com/l/app/<your-app-id>`. A dialog box appears to install the app.
+Create a deep link for the app after the app is listed in the Teams store. To create a link to launch Teams, append the app ID to the following URL: `https://teams.microsoft.com/l/app/<your-app-id>`. A dialog box appears to install the app.
-## Deep linking for SharePoint Framework tabs
+### Deep linking for SharePoint Framework tabs
The following deep link format can be used in a bot, connector or message extension card: `https://teams.microsoft.com/l/entity/<AppId>/<EntityId>?webUrl=<entityWebUrl>/<EntityName>`
The query parameters are:
Example: `https://teams.microsoft.com/l/entity/fe4a8eba-2a31-4737-8e33-e5fae6fee194/tasklist123?webUrl=https://tasklist.example.com/123&TaskList`
-## Deep linking to the scheduling dialog
-
-> [!NOTE]
-> This feature is currently in developer preview.
-
-You can create deep links to the Teams built-in scheduling dialog. This is especially useful if your app helps the user complete calendar or scheduling related tasks.
-
-### Generate a deep link to the scheduling dialog
-
-Use the following format for a deep link that you can use in a bot, Connector, or message extension card:
-`https://teams.microsoft.com/l/meeting/new?subject=<meeting subject>&startTime=<date>&endTime=<date>&content=<content>&attendees=<user1>,<user2>,<user3>,...`
-
-Example: `https://teams.microsoft.com/l/meeting/new?subject=test%20subject&attendees=joe@contoso.com,bob@contoso.com&startTime=10%2F24%2F2018%2010%3A30%3A00&endTime=10%2F24%2F2018%2010%3A30%3A00&content=ΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïtest%3AcontentΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇïΓÇï`
-
-> [!NOTE]
-> The search parameters don't support `+` signal in place of whitespace (` `). Ensure your uri encoding code returns `%20` for spaces for example, `?subject=test%20subject` is good, but `?subject=test+subject` is bad.
+### Navigate to an audio or audio-video call
-The query parameters are:
+You can invoke audio only or audio-video calls to a single user or a group of users, by specifying the call type and the participants. Before placing the call, Teams client prompts a confirmation to make the call. In case of group call, you can call a set of VoIP users and a set of PSTN users in the same deep link invocation.
-* `attendees`: The optional comma-separated list of user IDs representing the attendees of the meeting. The user performing the action is the meeting organizer. The User ID field currently only supports the Azure AD UserPrincipalName, typically an email address.
-* `startTime`: The optional start time of the event. This should be in [long ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601), for example *2018-03-12T23:55:25+02:00*.
-* `endTime`: The optional end time of the event, also in ISO 8601 format.
-* `subject`: An optional field for the meeting subject.
-* `content`: An optional field for the meeting details field.
+In case of a video call, the client will ask for confirmation and turn on the caller's video for the call. The receiver of the call has a choice to respond through audio only or audio and video, through the Teams call notification window.
> [!NOTE]
-> Currently, specifying the location isn't supported. You must specify the UTC offset, it means time zones when generating your start and end times.
+> This method cannot be used for invoking a meeting.
-To use this deep link with your bot, you can specify this as the URL target in your card's button or tap action through the `openUrl` action type.
-
-## Deep linking to an audio or audio-video call
+The following code demonstrates using the TeamsJS SDK to start a call:
-You can create deep links to invoke audio only or audio-video calls to a single user or a group of users, by specifying the call type, as *audio* or *av*, and the participants. After the deep link is invoked and before placing the call, Teams client prompts a confirmation to make the call. In case of group call, you can call a set of VoIP users and a set of PSTN users in the same deeplink invocation.
+```javascript
+if(call.isSupported()) {
+ const callPromise = call.startCall({ targets: ["joe@contoso.com","bob@contoso.com","4:9876543210"], requestedModalities: [call.CallModalities.Audio], source: "demoApp"});
+ callPromise.
+ then((result) => {/*Successful operation*/}).
+ catch((error) => {/*Unsuccessful operation*/});
+}
+else { /* handle case where capability isn't supported */ }
-In case of a video call, the client will ask for confirmation and turn on the caller's video for the call. The receiver of the call has a choice to respond through audio only or audio and video, through the Teams call notification window.
+```
-> [!NOTE]
-> This deeplink cannot be used for invoking a meeting.
+#### Generate a deep link to a call
-### Generate a deep link to a call
+While use of the strongly typed APIs of TeamsJS is recommended, you can also use a manually created deep link to start a call.
| Deep link | Format | Example | |--|--||
Following are the query parameters:
* `users`: The comma-separated list of user IDs representing the participants of the call. Currently, the User ID field supports the Azure AD UserPrincipalName, typically an email address, or in case of a PSTN call, it supports a pstn mri 4:&lt;phonenumber&gt;. * `withVideo`: This is an optional parameter, which you can use to make a video call. Setting this parameter will only turn on the caller's camera. The receiver of the call has a choice to answer through audio or audio and video call through the Teams call notification window.
-* `Source`: This is an optional parameter, which informs about the source of the deeplink.
+* `Source`: This is an optional parameter, which informs about the source of the deep link.
-## Code sample
+## Code Sample
| Sample name | Description | C# |Node.js| |-|-||-|
-|Deep Link consuming Subentity ID |Microsoft Teams sample app for demonstrating deeplink from bot chat to tab consuming Subentity ID.|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/csharp)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/nodejs)|
+|Deep Link consuming Subentity ID |Microsoft Teams sample app for demonstrating deep link from bot chat to tab consuming Subentity ID.|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/csharp)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/tab-deeplink/nodejs)|
## See also
platform Sdk Include https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/includes/sdk-include.md
+> [!NOTE]
+> This topic reflects version 2.0.0 of the Microsoft Teams JavaScript client SDK. If you are using an earlier version, refer to the [Teams JS SDK overview](msteams-docs/msteams-platform/tabs/how-to/../../../../../tabs/how-to/using-teams-client-sdk.md) for guidance on the differences between v1 and v2.
platform Manifest Schema https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/resources/schema/manifest-schema.md
keywords: teams manifest schema
# Reference: Manifest schema for Microsoft Teams
-The Microsoft Teams app manifest describes how your app integrates into the Microsoft Teams product. Your app manifest must conform to the schema hosted at [`https://developer.microsoft.com/json-schemas/teams/v1.12/MicrosoftTeams.schema.json`]( https://developer.microsoft.com/json-schemas/teams/v1.13/MicrosoftTeams.schema.json). Previous versions 1.0, 1.1,...,1.12 and the current 1.13 version (see note below) are also supported (using "v1.x" in the URL).
+The Microsoft Teams app manifest describes how your app integrates into the Microsoft Teams product. Your app manifest must conform to the schema hosted at [`https://developer.microsoft.com/json-schemas/teams/v1.13/MicrosoftTeams.schema.json`]( https://developer.microsoft.com/json-schemas/teams/v1.13/MicrosoftTeams.schema.json). Previous versions 1.0, 1.1,...,1.12 and the current 1.13 version (see note below) are each supported (using "v1.x" in the URL).
For more information on the changes made in each version, see [manifest change log](https://github.com/OfficeDev/microsoft-teams-app-schema/releases). > [!Important]
The following schema sample shows all extensibility options:
```json {
- "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.12/MicrosoftTeams.schema.json",
- "manifestVersion": "1.12",
+ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.13/MicrosoftTeams.schema.json",
+ "manifestVersion": "1.13",
"version": "1.0.0", "id": "%MICROSOFT-APP-ID%", "packageName": "com.example.myapp",
platform Access Teams Context https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/access-teams-context.md
Your tab requires contextual information to display relevant content:
* Locale and theme information. * Read the `entityId` or `subEntityId` that identifies what is in this tab. + ## User context Context about the user, team, or company can be especially useful when:
You can access context information in two ways:
### Get context by inserting URL placeholder values
-Use placeholders in your configuration or content URLs. Microsoft Teams replaces the placeholders with the relevant values when determining the actual configuration or content URL. The available placeholders include all fields on the [context](/javascript/api/@microsoft/teams-js/microsoftteams.context?view=msteams-client-js-latest&preserve-view=true) object. Common placeholders include the following:
+Use placeholders in your configuration or content URLs. Microsoft Teams replaces the placeholders with the relevant values when determining the actual configuration or content URL. The available placeholders include all fields on the [context](/javascript/api/@microsoft/teams-js/microsoftteams.context?view=msteams-client-js-1.12.1&preserve-view=true) object. Common placeholders include the following:
* {entityId}: The ID you supplied for the item in this tab when first [configuring the tab](~/tabs/how-to/create-tab-pages/configuration-page.md). * {subEntityId}: The ID you supplied when generating a [deep link](~/concepts/build-and-test/deep-links.md) for a specific item within this tab. This must be used to restore to a specific state within an entity; for example, scrolling to or activating a specific piece of content.
When they configure the tab, Teams calls the following URL:
### Get context by using the Microsoft Teams JavaScript library
-You can also retrieve the information listed above using the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client) by calling `microsoftTeams.getContext(function(context) { /* ... */ })`.
-
-The following code provides an example of context variable:
-
-```json
-{
- "teamId": "The Microsoft Teams ID in the format 19:[id]@thread.skype",
- "teamName": "The name of the current team",
- "channelId": "The channel ID in the format 19:[id]@thread.skype",
- "channelName": "The name of the current channel",
- "chatId": "The chat ID in the format 19:[id]@thread.skype",
- "locale": "The current locale of the user formatted as languageId-countryId (for example, en-us)",
- "entityId": "The developer-defined unique ID for the entity this content points to",
- "subEntityId": "The developer-defined unique ID for the sub-entity this content points to",
- "loginHint": "A value suitable as a login hint for Azure AD. This is usually the login name of the current user, in their home tenant",
- "userPrincipalName": "The principal name of the current user, in the current tenant",
- "userObjectId": "The Azure AD object id of the current user, in the current tenant",
- "tid": "The Azure AD tenant ID of the current user",
- "groupId": "Guid identifying the current Office 365 Group ID",
- "theme": "The current UI theme: default | dark | contrast",
- "isFullScreen": "Indicates if the tab is in full-screen",
- "teamType": "The type of team",
- "teamSiteUrl": "The root SharePoint site associated with the team",
- "teamSiteDomain": "The domain of the root SharePoint site associated with the team",
- "teamSitePath": "The relative path to the SharePoint site associated with the team",
- "channelRelativeUrl": "The relative path to the SharePoint folder associated with the channel",
- "sessionId": "The unique ID for the current Teams session for use in correlating telemetry data",
- "userTeamRole": "The user's role in the team",
- "isTeamArchived": "Indicates if team is archived",
- "hostClientType": "The type of host client. Possible values are android, ios, web, desktop, surfaceHub, teamsRoomsAndroid, teamsPhones, teamsDisplays rigel (deprecated, use teamsRoomsWindows instead)",
- "frameContext": "The context where tab URL is loaded (for example, content, task, setting, remove, sidePanel)",
- "sharepoint": "The SharePoint context is available only when hosted in SharePoint",
- "tenantSKU": "The license type for the current user tenant. Possible values are enterprise, free, edu, unknown",
- "userLicenseType": "The license type for the current user",
- "parentMessageId": "The parent message ID from which this task module is launched",
- "ringId": "The current ring ID",
- "appSessionId": "The unique ID for the current session used for correlating telemetry data",
- "isCallingAllowed": "Indicates if calling is allowed for the current logged in user",
- "isPSTNCallingAllowed": "Indicates if PSTN calling is allowed for the current logged in user",
- "meetingId": "The meeting ID used by tab when running in meeting context",
- "defaultOneNoteSectionId": "The OneNote section ID that is linked to the channel",
- "isMultiWindow": "The indication whether the tab is in a pop out window"
-}
-```
+You can also retrieve the information listed above using the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client) by calling the `app.getContext()` function. For additional information, see the properties of the [Context interface](/javascript/api/@microsoft/teams-js/app.context?view=msteams-client-js-latest&preserve-view=true).
## Retrieve context in private channels
If your page makes use of any of these values, the value of `channelType` field
## Handle theme change
-You can register your app to be informed if the theme changes by calling `microsoftTeams.registerOnThemeChangeHandler(function(theme) { /* ... */ })`.
+You can register your app to be informed if the theme changes by calling `app.registerOnThemeChangeHandler(function(theme) { /* ... */ })`.
The `theme` argument in the function is a string with a value of `default`, `dark`, or `contrast`.
platform Create Channel Group Tab https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/create-channel-group-tab.md
Ensure that you keep the command prompt with ngrok running and make a note of th
* [Create a personal tab](~/tabs/how-to/create-personal-tab.md) * [Tabs on mobile](~/tabs/design/tabs-mobile.md) * [Build tabs with Adaptive Cards](~/tabs/how-to/build-adaptive-card-tabs.md)
-* [Create a removal page](~/tabs/how-to/create-tab-pages/removal-page.md)
+* [Create a removal page](~/tabs/how-to/create-tab-pages/removal-page.md)
platform Create Personal Tab https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/create-personal-tab.md
zone_pivot_groups: teams-app-environment
Personal tabs, along with personally-scoped bots, are part of personal apps and are scoped to a single user. They can be pinned to the left pane for easy access. You can also [reorder](#reorder-static-personal-tabs) your personal tabs.
-Ensure that you have all the [prerequsites](~/tabs/how-to/tab-requirements.md) to build your personal tab.
+Ensure that you have all the [prerequisites](~/tabs/how-to/tab-requirements.md) to build your personal tab.
+ ::: zone pivot="node-java-script"
gulp ngrok-serve
1. In the left pane of Teams, select ellipses &#x25CF;&#x25CF;&#x25CF; and then choose your uploaded app to view your personal tab.
- Now you have succesfully created and added your personal tab in Teams.
+ Now you have successfully created and added your personal tab in Teams.
As you have your personal tab in Teams, you can also [reorder](#reorder-static-personal-tabs) your personal tab.
In Visual Studio Solution Explorer, right-click on the project and select **Edit
```HTML <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
- <script src="https://statics.teams.cdn.office.net/sdk/v1.6.0/js/MicrosoftTeams.min.js"></script>
+ <script src="https://statics.teams.cdn.office.net/sdk/v2.0.0/js/MicrosoftTeams.min.js"></script>
```
-1. In Visual Studio Solution Explorer open **PersonalTab.cshtml** from **Pages** folder and add `microsoftTeams.initialize()` in the `<script>` tags and save.
+1. In Visual Studio Solution Explorer open **PersonalTab.cshtml** from **Pages** folder and add `app.initialize()` in the `<script>` tags and save.
1. In Visual Studio, select **F5** or choose **Start Debugging** from your application's **Debug** menu.
ngrok http 3978 --host-header=localhost
:::image type="content" source="~/assets/images/tab-images/personaltabaspnetuploaded.png" alt-text="Default Tab" border="true":::
- Now you have succesfully created and added your personal tab in Teams.
+ Now you have successfully created and added your personal tab in Teams.
As you have your personal tab in Teams, you can also [reorder](#reorder-static-personal-tabs) your personal tab.
The controllers use the `ViewBag` property to transfer values dynamically to the
```HTML <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
- <script src="https://statics.teams.cdn.office.net/sdk/v1.6.0/js/MicrosoftTeams.min.js"></script>
+ <script src="https://statics.teams.cdn.office.net/sdk/v2.0.0/js/MicrosoftTeams.min.js"></script>
```
-1. In Visual Studio Solution Explorer open **PersonalTab.cshtml** from **Views** > **PersonalTab** folder and add `microsoftTeams.initialize()` inside the `<script>` tags and save.
+1. In Visual Studio Solution Explorer open **PersonalTab.cshtml** from **Views** > **PersonalTab** folder and add `app.initialize()` inside the `<script>` tags and save.
1. In Visual Studio, select **F5** or choose **Start Debugging** from your application's **Debug** menu.
ngrok http 3978 --host-header=localhost
:::image type="content" source="~/assets/images/tab-images/personaltabaspnetmvccoreuploaded.png" alt-text="Personal tab" border="true":::
- Now you have succesfully created and added your personal tab in Teams.
+ Now you have successfully created and added your personal tab in Teams.
As you have your personal tab in Teams, you can also [reorder](#reorder-static-personal-tabs) your personal tab.
platform Configuration Page https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/create-tab-pages/configuration-page.md
A configuration page is a special type of [content page](content-page.md). The u
* A [message extension](~/messaging-extensions/what-are-messaging-extensions.md). * An [Office 365 Connector](~/webhooks-and-connectors/what-are-webhooks-and-connectors.md). + ## Configure a channel or group chat tab
-The application must reference the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) and call `microsoft.initialize()`. The URLs used must be secured HTTPS endpoints and available from the cloud.
+The application must reference the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) and call `app.initialize()`. The URLs used must be secured HTTPS endpoints and available from the cloud.
### Example
An example of a configuration page is shown in the following image:
The following code is an example of corresponding code for the configuration page:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```html
+<head>
+ <script src='https://statics.teams.cdn.office.net/sdk/v2.0.0/js/MicrosoftTeams.min.js'></script>
+</head>
+<body>
+ <button onclick="(document.getElementById('icon').src = '/images/iconGray.png'); colorClickGray()">Select Gray</button>
+ <img id="icon" src="/images/teamsIcon.png" alt="icon" style="width:100px" />
+ <button onclick="(document.getElementById('icon').src = '/images/iconRed.png'); colorClickRed()">Select Red</button>
+
+ <script>
+ app.initialize();
+ let saveGray = () => {
+ pages.config.registerOnSaveHandler((saveEvent) => {
+ const configPromise = pages.config.setConfig({
+ websiteUrl: "https://yourWebsite.com",
+ contentUrl: "https://yourWebsite.com/gray",
+ entityId: "grayIconTab",
+ suggestedDisplayName: "MyNewTab"
+ });
+ configPromise.
+ then((result) => {saveEvent.notifySuccess()}).
+ catch((error) => {saveEvent.notifyFailure("failure message")});
+ });
+ }
+
+ let saveRed = () => {
+ pages.config.registerOnSaveHandler((saveEvent) => {
+ const configPromise = pages.config.setConfig({
+ websiteUrl: "https://yourWebsite.com",
+ contentUrl: "https://yourWebsite.com/red",
+ entityId: "redIconTab",
+ suggestedDisplayName: "MyNewTab"
+ });
+ configPromise.
+ then((result) => {saveEvent.notifySuccess();}).
+ catch((error) => {saveEvent.notifyFailure("failure message")});
+ });
+ }
+
+ let gr = document.getElementById("gray").style;
+ let rd = document.getElementById("red").style;
+
+ const colorClickGray = () => {
+ gr.display = "block";
+ rd.display = "none";
+ pages.config.setValidityState(true);
+ saveGray()
+ }
+
+ const colorClickRed = () => {
+ rd.display = "block";
+ gr.display = "none";
+ pages.config.setValidityState(true);
+ saveRed();
+ }
+ </script>
+ ...
+</body>
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+ ```html <head> <script src='https://statics.teams.cdn.office.net/sdk/v1.6.0/js/MicrosoftTeams.min.js'></script>
The following code is an example of corresponding code for the configuration pag
</body> ```
+***
Choose either **Select Gray** or **Select Red** button in the configuration page, to display the tab content with a gray or red icon. The following image displays the tab content with **Gray** icon selected:
The following image displays the tab content with **Red** icon selected:
Choosing the appropriate button triggers either `saveGray()` or `saveRed()`, and invokes the following:
-* Set `settings.setValidityState(true)` to true.
-* The `microsoftTeams.settings.registerOnSaveHandler()` event handler is triggered.
+* Set `pages.config.setValidityState(true)` to true.
+* The `pages.config.registerOnSaveHandler()` event handler is triggered.
* **Save** on the app's configuration page, is enabled.
-The configuration page code informs Teams that the configuration requirements are satisfied and the installation can proceed. When the user selects **Save**, the parameters of `settings.setSettings()` are set, as defined by the `Settings` interface. For more information, see [settings interface](/javascript/api/@microsoft/teams-js/microsoftteams.settings.settings?view=msteams-client-js-latest&preserve-view=true). `saveEvent.notifySuccess()` is called to indicate that the content URL has successfully resolved.
+The configuration page code informs Teams that the configuration requirements are satisfied and the installation can proceed. When the user selects **Save**, the parameters of `pages.config.setConfig()` are set, as defined by the `Config` interface. For more information, see [config interface](/javascript/api/@microsoft/teams-js/pages.config.Config?view=msteams-client-js-latest&preserve-view=true). `saveEvent.notifySuccess()` is called to indicate that the content URL has successfully resolved.
>[!NOTE] > >* You have 30 seconds to complete the save operation (the callback to registerOnSaveHandler) before the timeout. After the timeout, a generic error message appears.
->* If you register a save handler using `microsoftTeams.settings.registerOnSaveHandler()`, the callback must invoke `saveEvent.notifySuccess()` or `saveEvent.notifyFailure()` to indicate the outcome of the configuration.
+>* If you register a save handler using `registerOnSaveHandler()`, the callback must invoke `saveEvent.notifySuccess()` or `saveEvent.notifyFailure()` to indicate the outcome of the configuration.
>* If you do not register a save handler, the `saveEvent.notifySuccess()` call is made automatically when the user selects **Save**. ### Get context data for your tab settings Your tab requires contextual information to display relevant content. Contextual information further enhances your tab's appeal by providing a more customized user experience.
-For more information on the properties used for tab configuration, see [context interface](/javascript/api/@microsoft/teams-js/microsoftteams.context?view=msteams-client-js-latest&preserve-view=true). Collect the values of context data variables in the following two ways:
+For more information on the properties used for tab configuration, see [context interface](/javascript/api/@microsoft/teams-js/app.context?view=msteams-client-js-latest&preserve-view=true). Collect the values of context data variables in the following two ways:
* Insert URL query string placeholders in your manifest's `configurationURL`.
-* Use the [Teams SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) `microsoftTeams.getContext((context) =>{})` method.
+* Use the [Teams SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) `app.getContext()` method.
#### Insert placeholders in the `configurationUrl`
Add context interface placeholders to your base `configurationUrl`. For example:
After your page uploads, Teams updates the query string placeholders with relevant values. Include logic in the configuration page to retrieve and use those values. For more information on working with URL query strings, see [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) in MDN Web Docs. The following code example provides the way to extract a value from the `configurationUrl` property:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```html
+<script>
+ app.initialize();
+ const getId = () => {
+ let urlParams = new URLSearchParams(document.location.search.substring(1));
+ let blueTeamId = urlParams.get('team');
+ return blueTeamId
+ }
+//For testing, you can invoke the following to view the pertinent value:
+document.write(getId());
+</script>
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+ ```html <script> microsoftTeams.initialize();
document.write(getId());
</script> ```
+***
+ ### Use the `getContext()` function to retrieve context
-The `microsoftTeams.getContext((context) => {})` function retrieves the [context interface](/javascript/api/@microsoft/teams-js/microsoftteams.context?view=msteams-client-js-latest&preserve-view=true) when invoked.
+The `app.getContext()` function returns a promise that resolves with the [context interface](/javascript/api/@microsoft/teams-js/app.context?view=msteams-client-js-latest&preserve-view=true) object.
The following code provides an example of adding this function to the configuration page to retrieve context values:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```html
+<!-- `userPrincipalName` will render in the span with the id "user". -->
+
+<span id="user"></span>
+...
+<script>
+ const contextPromise = app.getContext();
+ contextPromise.
+ then((context) => {
+ let userId = document.getElementById('user');
+ userId.innerHTML = context.user.userPrincipalName;
+ }).
+ catch((error) => {/*Unsuccessful operation*/});
+</script>
+...
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+ ```html <!-- `userPrincipalName` will render in the span with the id "user". -->
The following code provides an example of adding this function to the configurat
... ```
+***
+ ## Context and authentication Authenticate before allowing a user to configure your app. Otherwise, your content might include sources that have their authentication protocols. For more information, see [authenticate a user in a Microsoft Teams tab](~/tabs/how-to/authentication/auth-flow-tab.md). Use context information to construct the authentication requests and authorization page URLs. Ensure that all domains used in your tab pages are listed in the `manifest.json` and `validDomains` array. ## Modify or remove a tab
-Set your manifest's `canUpdateConfiguration` property to `true`, that enables the users to modify, reconfigure, or rename a channel or group tab. Also, indicate what happens to the content when a tab is removed, by including a removal options page in the app and setting a value for the `removeUrl` property in the `setSettings()` configuration. The user can uninstall personal tabs but cannot modify them. For more information, see [create a removal page for your tab](~/tabs/how-to/create-tab-pages/removal-page.md).
+Set your manifest's `canUpdateConfiguration` property to `true`. It enables the users to modify, reconfigure, or rename a channel or group tab. Inform the user about the impact on content when a tab is removed. To do this, include a removal options page in the app, and set a value for the `removeUrl` property in the `setConfig()` (formerly `setSettings()`) configuration. The user can uninstall personal tabs but cannot modify them. For more information, see [create a removal page for your tab](~/tabs/how-to/create-tab-pages/removal-page.md).
+
+Microsoft Teams `setConfig()` (formerly `setSettings()`) configuration for removal page:
-Microsoft Teams `setSettings()` configuration for removal page:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```javascript
+const configPromise = pages.config.setConfig({
+ contentUrl: "add content page URL here",
+ entityId: "add a unique identifier here",
+ suggestedDisplayName: "add name to display on tab here",
+ websiteUrl: "add website URL here //Required field for configurable tabs on Mobile Clients",
+ removeUrl: "add removal page URL here"
+});
+configPromise.
+ then((result) => {/*Successful operation*/).
+ catch((error) => {/*Unsuccessful operation*/});
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
```javascript microsoftTeams.settings.setSettings({
microsoftTeams.settings.setSettings({
}); ```
+***
+ ## Mobile clients
-If you choose to have your channel or group tab appear on the Teams mobile clients, the `setSettings()` configuration must have a value for `websiteUrl`. For more information, see [guidance for tabs on mobile](~/tabs/design/tabs-mobile.md).
+If you choose to have your channel or group tab appear on the Teams mobile clients, the `setConfig()` configuration must have a value for `websiteUrl`. For more information, see [guidance for tabs on mobile](~/tabs/design/tabs-mobile.md).
## Next step
platform Content Page https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/create-tab-pages/content-page.md
A content page is a webpage that is rendered within the Teams client. These are
This article is specific to using content pages as tabs; however the majority of the guidance here applies regardless of how the content page is presented to the user. + ## Tab content and design guidelines Your tab's overall objective is to provide access to meaningful and engaging content that has practical value and an evident purpose. You must focus on making your tab design clean, navigation intuitive, and content immersive.
For more information, see [tab design guidelines](~/tabs/design/tabs.md) and [Mi
## Integrate your code with Teams
-For your page to display in Teams, you must include the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) and include a call to `microsoftTeams.initialize()` after your page loads.
+For your page to display in Teams, you must include the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client?view=msteams-client-js-latest&preserve-view=true) and include a call to `app.initialize()` after your page loads.
The following code provides an example of how your page and the Teams client communicate:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```html
+<!DOCTYPE html>
+<html>
+<head>
+...
+ <script src= 'https://statics.teams.cdn.office.net/sdk/v2.0.0/js/MicrosoftTeams.min.js'></script>
+...
+</head>
+
+<body>
+...
+ <script>
+ app.initialize();
+ </script>
+...
+</body>
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+ ```html <!DOCTYPE html> <html>
The following code provides an example of how your page and the Teams client com
</body> ```
+***
+ ## Access additional content You can access additional content by using the SDK to interact with Teams, creating deep links, using task modules, and verifying if URL domains are included in the `validDomains` array.
If you indicate `showLoadingIndicator : true` in your app manifest, then all ta
To show the loading indicator: 1. Add `"showLoadingIndicator": true` to your manifest.
-1. Call `microsoftTeams.initialize();`.
-1. As a **mandatory** step, call `microsoftTeams.appInitialization.notifySuccess()` to notify Teams that your app has successfully loaded. Teams then hides the loading indicator, if applicable. If `notifySuccess` is not called within 30 seconds, it is assumed that your app timed out and an error screen with a retry option appears.
-1. **Optionally**, if you are ready to print to the screen and wish to lazy load the rest of your application's content, you can manually hide the loading indicator by calling `microsoftTeams.appInitialization.notifyAppLoaded();`.
-1. If your application fails to load, you can call `microsoftTeams.appInitialization.notifyFailure(reason);` to let Teams know there was an error. An error screen is shown to the user. The following code provides an example of application failure reasons:
+1. Call `app.initialize();`.
+1. As a **mandatory** step, call `app.notifySuccess()` to notify Teams that your app has successfully loaded. Then, Teams hides the loading indicator, if applicable. If `notifySuccess` is not called within 30 seconds, Teams assumes that that your app timed out, and displays an error screen with a retry option.
+1. **Optionally**, 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();`.
+1. 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 and, optionally, provide a failure message. An error screen is shown to the user. The following code shows the enumeration that defines the possible reasons you can indicate for the application's failure to load:
```typescript /* List of failure reasons */
platform Removal Page https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/create-tab-pages/removal-page.md
You can extend and enhance the user experience by supporting removal and modification options in your app. Teams enables users to rename or remove a channel or group tab and you can permit users to reconfigure your tab after installation. Additionally, the tab removal experience provides the users with post-removal options to delete or archive content. + ## Enable your tab to be reconfigured after installation Your `manifest.json` defines your tab's features and capabilities. The tab instance `canUpdateConfiguration` property takes a Boolean value that indicates whether a user can modify or reconfigure the tab after it is created. The following table provides the property details:
When your tab is uploaded to a channel or group chat, Teams adds a right-click d
## Create a tab removal page for your application
-The optional removal page is an HTML page that you host and is displayed when the tab is removed. The removal page URL is designated by the `setSettings()` method within your configuration page. As with all pages in your app, the removal page must comply with [Teams tab prerequisites](../../../tabs/how-to/tab-requirements.md).
+The optional removal page is an HTML page that you host and is displayed when the tab is removed. The removal page URL is designated by the `setConfig()` method (formerly `setSettings()`) within your configuration page. As with all pages in your app, the removal page must comply with [Teams tab prerequisites](../../../tabs/how-to/tab-requirements.md).
### Register a remove handler
-Optionally, within your removal page logic, you can invoke the `registerOnRemoveHandler((RemoveEvent) => {}` event handler when the user removes an existing tab configuration. The method takes in the [`RemoveEvent`](/javascript/api/@microsoft/teams-js/microsoftteams.settings.removeevent?view=msteams-client-js-latest&preserve-view=true) interface and executes the code in the handler when a user attempts to remove content. The method is used to perform cleanup operations such as removing the underlying resource powering the tab content. At a time only one remove handler can be registered.
+Optionally, within your removal page logic, you can invoke the `registerOnRemoveHandler((RemoveEvent) => {}` event handler when the user removes an existing tab configuration. The method takes in the [`RemoveEvent`](/javascript/api/@microsoft/teams-js/pages.config.removeevent?view=msteams-client-js-latest&preserve-view=true) interface and executes the code in the handler when a user attempts to remove content. The method is used to perform cleanup operations such as removing the underlying resource powering the tab content. At a time only one remove handler can be registered.
The `RemoveEvent` interface describes an object with two methods:
The `RemoveEvent` interface describes an object with two methods:
* The `notifyFailure(string)` function is optional. It indicates that removal of the underlying resource failed and its content cannot be removed. The optional string parameter specifies a reason for the failure. If provided, this string is displayed to the user; else a generic error is displayed.
-#### Use the `getSettings()` function
+#### Use the `getConfig()` function
-You can use `getSettings()`to assign the tab content to be removed. The `getSettings((Settings) =>{})` function takes in the [`Settings interface`](/javascript/api/@microsoft/teams-js/microsoftteams.settings.settings?view=msteams-client-js-latest&preserve-view=true) and provides the valid settings property values that can be retrieved.
+You can use `getConfig()` (formerly `getSettings()`) to assign the tab content to be removed. The `getConfig()` function returns a promise that resolves with the Config object and provides the valid settings property values that can be retrieved.
#### Use the `getContext()` function
-You can use `getContext()` to get the current context in which the frame is running. The `getContext((Context) =>{})` function takes in the [`Context interface`](/javascript/api/@microsoft/teams-js/microsoftteams.context?view=msteams-client-js-latest&preserve-view=true). The function provides valid `Context` property values that you can use in your removal page logic to determine the content to display in the removal page.
+You can use `getContext()` to get the current context in which the frame is running. The `getContext()` function returns a promise that will resolve with the Context object. The Context object provides valid `Context` property values that you can use in your removal page logic to determine the content to display in the removal page.
#### Include authentication
Authentication is required before allowing a user to delete the tab content. Con
The following is a sample tab removal code block:
+# [TeamsJS v2](#tab/teamsjs-v2)
+
+```html
+<body>
+ <button onclick="onClick()">Delete this tab and all underlying data?</button>
+ <script>
+ app.initialize();
+ pages.config.registerOnRemoveHandler((removeEvent) => {
+ // Here you can designate the tab content to be removed and/or archived.
+ const configPromise = pages.getConfig();
+ configPromise.
+ then((configuration) => {
+ configuration.contentUrl = "...";
+ removeEvent.notifySuccess()}).
+ catch((error) => {removeEvent.notifyFailure("failure message")});
+ });
+
+ const onClick() => {
+ pages.config.setValidityState(true);
+ }
+ </script>
+</body>
+```
+
+# [TeamsJS v1](#tab/teamsjs-v1)
+ ```html <body> <button onclick="onClick()">Delete this tab and all underlying data?</button>
The following is a sample tab removal code block:
</body> ```
-When a user selects **Remove** from the tab's drop-down menu, Teams loads the optional `removeUrl` page assigned in your **configuration page**, into an IFrame. The user is shown a button loaded with the `onClick()` function that calls `microsoftTeams.settings.setValidityState(true)` and enables the **Remove** button shown at the bottom of the removal page IFrame.
+***
+
+When a user selects **Remove** from the tab's drop-down menu, Teams loads the optional `removeUrl` page assigned in your **configuration page**, into an IFrame. The user is shown a button loaded with the `onClick()` function that calls `pages.config.setValidityState(true)` and enables the **Remove** button shown at the bottom of the removal page IFrame.
After the remove handler is executed, `removeEvent.notifySuccess()` or `removeEvent.notifyFailure()` notifies Teams of the content removal outcome.
platform Tab Requirements https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/how-to/tab-requirements.md
Ensure that you adhere to the following prerequisites while building your Teams
* Style your tabs based on the Teams client's theme, design, and intent. Tabs work best when they're built to address a specific need and focus on a small set of tasks or a subset of data that is relevant to the tab's channel location.
-* Within your content page, add a reference to [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client) using script tags. After your page loads, make a call to `microsoftTeams.initialize()`, otherwise your page is not displayed.
+* Within your content page, add a reference to [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client) using script tags. After your page loads, make a call to `app.initialize()`, otherwise your page will not be displayed.
* For authentication to work on mobile clients, you must upgrade to Teams JavaScript SDK 1.4.1 and later.
-* If you choose to have your channel or group tab to appear on Teams mobile client, the `setSettings()` configuration must have a value for the `websiteUrl` property.
+* If you choose to have your channel or group tab to appear on Teams mobile client, the `setConfig()` configuration must have a value for the `websiteUrl` property.
-* Microsoft Teams tab does'nt support the ability to load intranet websites that use self-signed certificates.
+* Microsoft Teams tab doesn't support the ability to load intranet websites that use self-signed certificates.
+ ## Tools to build tabs
platform What Are Tabs https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/what-are-tabs.md
Tabs are Teams-aware webpages embedded in Microsoft Teams. They're simple HTML `
> > We recommend you to use the Teams client SDK via [npm package](https://www.npmjs.com/package/@microsoft/teams-js) and bundle it with your app as currently Teams client SDK is not available in Government Cloud CDN. + The following image shows personal tabs: :::image type="content" source="../assets/images/tabs/personaltab.png" alt-text="Personal tab" lightbox="../assets/images/tabs/personaltab.png":::
There are few prerequisites that you must go through before working on tabs.
There are two types of tabs available in Teams, personal and channel or group. [Personal tabs](~/tabs/how-to/create-personal-tab.md), along with personal-scoped bots, are part of personal apps and are scoped to a single user. They can be pinned to the left navigation bar for easy access. [Channel or group tabs](~/tabs/how-to/create-channel-group-tab.md) deliver content to channels and group chats, and are a great way to create collaborative spaces around dedicated web-based content.
-You can [create a content page](~/tabs/how-to/create-tab-pages/content-page.md) as part of a personal tab, channel or group tab, or task module. You can [create a configuration page](~/tabs/how-to/create-tab-pages/configuration-page.md) that enables users to configure Microsoft Teams app and use it to configure a channel or group chat tab, a message extension, or an Office 365 Connector. You can permit users to reconfigure your tab after installation and [create a tab removal page](~/tabs/how-to/create-tab-pages/removal-page.md) for your application. When you build a Teams app that includes a tab, you must test how your [tab functions on both the Android and iOS Teams clients](~/tabs/design/tabs-mobile.md). Your tab must [get context](~/tabs/how-to/access-teams-context.md) through basic information, locale and theme information, and `entityId` or `subEntityId` that identifies what is in the tab.
+You can [create a content page](~/tabs/how-to/create-tab-pages/content-page.md) as part of a personal tab, channel or group tab, or task module. You can [create a configuration page](~/tabs/how-to/create-tab-pages/configuration-page.md) that enables users to configure Microsoft Teams app and use it to configure a channel or group chat tab, a message extension, or an Office 365 Connector. You can permit users to reconfigure your tab after installation and [create a tab removal page](~/tabs/how-to/create-tab-pages/removal-page.md) for your application. When you build a Teams app that includes a tab, you must test how your [tab functions on both the Android and iOS Teams clients](~/tabs/design/tabs-mobile.md). Your tab must [get context](~/tabs/how-to/access-teams-context.md) through basic information, locale and theme information, and `app.Context.page.id` or `app.Context.page.subPageId` that identifies what is in the tab.
You can build tabs with Adaptive Cards and centralize all Teams app capabilities by eliminating the need for a different backend for your bots and tabs. [Stage View](~/tabs/tabs-link-unfurling.md) is a new UI component that allows you to render the content opened in full screen in Teams and pinned as a tab. The existing [link unfurling](~/tabs/tabs-link-unfurling.md) service is updated, so that it's used to turn URLs into a tab using an Adaptive Card and Chat Services. You can [create conversational tabs](~/tabs/how-to/conversational-tabs.md) using conversational sub-entities that allow users to have conversations about sub-entities in your tab, such as specific task, patient, and sales opportunity, instead of discussing the entire tab. You can make changes to [tab margins](~/resources/removing-tab-margins.md) to enhance the developer's experience when building apps. You can drag the tab and place it in the desired position to interchange the tab positions within your personal apps and channel or group chats.
You can use one of the following methods to create tabs:
### Declare custom tab in app manifest
-A custom tab is declared in the app manifest of your app package. For each webpage you want included as a tab in your app, you define a URL and a scope. Additionally, you can add the [Teams JavaScript client SDK](/javascript/api/overview/msteams-client) to your page, and call `microsoftTeams.initialize()` after your page loads. Teams displays your page and provides access to Teams-specific information, for example, the Teams client is running the dark theme.
+A custom tab is declared in the app manifest of your app package. For each webpage you want included as a tab in your app, you define a URL and a scope. Additionally, you can add the [Teams JavaScript client SDK](/javascript/api/overview/msteams-client) to your page, and call `app.initialize()` after your page loads. Teams displays your page and provides access to Teams-specific information, for example, the Teams client is running the dark theme.
Whether you choose to expose your tab within the channel or group, or personal scope, you must present an <iframe\> HTML [content page](~/tabs/how-to/create-tab-pages/content-page.md) in your tab. For personal tabs, the content URL is set directly in your Teams app manifest by the `contentUrl` property in the `staticTabs` array. Your tab's content is the same for all users.
platform Teams Toolkit Fundamentals https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/teams-toolkit-fundamentals.md
Last updated 05/17/2022
# Teams Toolkit Overview - Teams Toolkit for Microsoft Visual Studio Code helps you to create and deploy Teams apps with integrated identity, access to cloud storage, data from Microsoft Graph, and other services in Azure and Microsoft 365 with zero-configuration approach. For Teams app development, similar to Teams Toolkit for Visual Studio, you can use [CLI tool](https://github.com/OfficeDev/TeamsFx/blob/dev/docs/cli/user-manual.md), which consists of Toolkit `teamsfx`. Teams Toolkit lets you create, debug, and deploy your Teams app right from Visual Studio Code. App development with the toolkit has the advantages of:
platform Whats New https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/whats-new.md
Discover Microsoft Teams platform features that are generally available (GA) and
|05/24/2022| Submit your Outlook- and Office-enabled apps to the Teams store | Extend your app across Microsoft 365 > [Overview](m365-apps/overview.md) | |05/24/2022| App guidance and what's new in TeamsJS version 2.0.0| Tools and SDKs > [Teams JavaScript client SDK](tabs/how-to/using-teams-client-sdk.md) | | 05/24/2022 | Teams Toolkit version 4.0.0 for Visual Studio Code is now GA | Tools and SDKs > Teams Toolkit for Visual Studio Code > <br> ΓÇó [Teams Toolkit Overview](toolkit/teams-toolkit-fundamentals.md) <br> ΓÇó [Build command bot with JavaScript](toolkit/add-capability.md) <br> ΓÇó [Build notification bot with JavaScript](toolkit/add-capability.md) <br> ΓÇó [Preview and customize Teams app manifest](toolkit/TeamsFx-preview-and-customize-app-manifest.md) <br> ΓÇó [Connect to existing APIs](toolkit/add-API-connection.md) <br> ΓÇó [Add capabilities to your Teams apps](toolkit/add-capability.md) <br> ΓÇó [Add single sign-on experience](toolkit/add-single-sign-on.md) <br> ΓÇó [Add cloud resources to Teams app](toolkit/add-resource.md) |
+| 05/24/2022 | Introduced app manifest version 1.13 | App manifest > [Manifest schema for Microsoft Teams](resources/schem) |
| 05/24/2022 | Bots and Message extensions in GCC and GCCH | ΓÇó Plan your app > [Overview](concepts/app-fundamentals-overview.md#government-community-cloud) </br> ΓÇó Build bots > [Overview](bots/what-are-bots.md) </br> ΓÇó Build message extensions > [Overview](messaging-extensions/what-are-messaging-extensions.md) | <!--
Microsoft Teams platform features that are available to all app developers.
|05/24/2022| Submit your Outlook- and Office-enabled apps to the Teams store | Extend your app across Microsoft 365 > [Overview](m365-apps/overview.md) | |05/24/2022| App guidance and what's new in TeamsJS version 2.0.0| Tools and SDKs > [Teams JavaScript client SDK](tabs/how-to/using-teams-client-sdk.md) | | 05/24/2022 | Teams Toolkit version 4.0.0 for Visual Studio Code is now GA | Tools and SDKs > Teams Toolkit for Visual Studio Code > <br> ΓÇó [Teams Toolkit Overview](toolkit/teams-toolkit-fundamentals.md) <br> ΓÇó [Build command bot with JavaScript](toolkit/add-capability.md) <br> ΓÇó [Build notification bot with JavaScript](toolkit/add-capability.md) <br> ΓÇó [Preview and customize Teams app manifest](toolkit/TeamsFx-preview-and-customize-app-manifest.md) <br> ΓÇó [Connect to existing APIs](toolkit/add-API-connection.md) <br> ΓÇó [Add capabilities to your Teams apps](toolkit/add-capability.md) <br> ΓÇó [Add single sign-on experience](toolkit/add-single-sign-on.md) <br> ΓÇó [Add cloud resources to Teams app](toolkit/add-resource.md) |
+| 05/24/2022 | Introduced app manifest version 1.13 | App manifest > [Manifest schema for Microsoft Teams](resources/schem) |
|05/24/2022|Bots and Message extensions in GCC and GCCH| ΓÇó Plan your app > [Overview](concepts/app-fundamentals-overview.md#government-community-cloud) </br> ΓÇó Build bots > [Overview](bots/what-are-bots.md) </br> ΓÇó Build message extensions > [Overview](messaging-extensions/what-are-messaging-extensions.md) | |04/26/2022|Uninstall behavior for personal app with bot | Build bots > Bot conversations > [Uninstall behavior updates in personal apps with bots](bots/how-to/conversations/subscribe-to-conversation-events.md#uninstall-behavior-for-personal-app-with-bot)| |04/22/2022| Test preview for monetized apps | Monetize your app > [Test preview for monetized apps](concepts/deploy-and-publish/appsource/prepare/test-preview-for-monetized-apps.md)
Explore updates from the previous GA releases listed here.
|05/13/2021| Added information on mConnect and Skooler | Integrate with Teams > Moodle LMS > [Moodle learning management system](resources/moodle-overview.md)| |05/10/2021| App manifest v1.10 released | App manifest > [Manifest schema](resources/schem) | |05/10/2021| New app customization feature | Design your app > [Enable orgs to customize your app](concepts/design/enable-app-customization.md) |
-|05/07/2021| Deep links for audio and video calls in chat | Integrate with Teams > [Deep links](concepts/build-and-test/deep-links.md#deep-linking-to-an-audio-or-audio-video-call) |
+|05/07/2021| Deep links for audio and video calls in chat | Integrate with Teams > [Deep links](concepts/build-and-test/deep-links.md#navigate-to-an-audio-or-audio-video-call) |
|04/30/2021|New guidance on how to publish apps to the Teams store | ΓÇó Publish to the Teams store > [Publish your app to the Teams store](concepts/deploy-and-publish/appsource/publish.md)</br> ΓÇó Publish to the Teams store > [Teams store validation guidelines](concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md) | |04/29/2021 | Support for Universal Actions for Adaptive Cards v1.4 | Build cards and task module > Build cards > Universal actions for Adaptive Cards > [Universal Actions for Adaptive Cards](task-modules-and-cards/cards/universal-actions-for-adaptive-cards/overview.md) | |04/29/2021 | User Specific Views | Build cards and task module > Build cards > Universal actions for Adaptive Cards > [User Specific Views](task-modules-and-cards/cards/universal-actions-for-adaptive-cards/User-Specific-Views.md) |
Explore updates from the previous GA releases listed here.
| 05/06/2019 | Application Certification program for store apps. | [Application Certification](~/concepts/deploy-and-publish/appsource/post-publish/overview.md#complete-microsoft-365-certification) | | 05/06/2019 | App Templates are now available | [App Templates](~/samples/app-templates.md) | | 04/23/2019 | Action-based Message Extensions are now available. | [Action-based Message Extensions](~/concepts/messaging-extensions/create-extensions.md) |
-| 02/18/2019 | Creating deep links to private chat. | [Deep linking to a chat](concepts/build-and-test/deep-links.md#deep-linking-to-a-chat) |
+| 02/18/2019 | Creating deep links to private chat. | [Deep linking to a chat](concepts/build-and-test/deep-links.md#navigate-to-a-chat) |
| 01/23/2019 | Surfacing SKU and licenceType information in the tab context. | [Tab Context](~/concepts/tabs/tabs-context.md) | | </details>
Explore updates from the previous GA releases listed here.
| -- | | | | 11/12/2018 | Tabs in group chat is now available in the released version of Teams. As part of this work, the tabs section has been reworked for clarity.| [Configurable tabs](~/concepts/tabs/tabs-configurable.md) | | 11/11/2018 | Getting started for Node JS and for .NET/C# has been updated to use App Studio in Teams, and a new section has been added on hosting Node based Teams apps in Azure. | [Get started on the Microsoft Teams platform with C#/.NET and App Studio](~/get-started/get-started-dotnet-app-studio.md), [Get started on the Microsoft Teams platform with Node JS and App Studio](~/get-started/get-started-nodejs-app-studio.md), [Host your Node Teams app in Azure](~/get-started/get-started-nodejs-in-azure.md)|
-| 11/09/2018 | You can now create deep links to private chats between users. | [Deep linking to a chat](concepts/build-and-test/deep-links.md#deep-linking-to-a-chat) |
+| 11/09/2018 | You can now create deep links to private chats between users. | [Deep linking to a chat](concepts/build-and-test/deep-links.md#navigate-to-a-chat) |
| 11/08/2018 | SharePoint Framework 1.7 has shipped and with it a new feature to use Microsoft Teams tab as a SharePoint Framework web part. | [Tabs in SharePoint](~/concepts/tabs/tabs-in-sharepoint.md) | | 11/05/2018 | The **task module** feature was released. A task module allows you to create modal popup experiences in your Teams application, from both bots and tabs. Inside the popup, you can run your own custom HTML/JavaScript code, show an `<iframe>`-based widget such as a YouTube or Microsoft Stream video, or display an [Adaptive card](/adaptive-cards/). | [Task module Overview](~/concepts/task-modules/task-modules-overview.md), [task module in tabs](~/concepts/task-modules/task-modules-tabs.md), [task module in bots](~/concepts/task-modules/task-modules-bots.md) | | 10/05/2018 | Formatting information for cards has been updated and tested in the desktop, iOS, and Android clients for Teams. | [Cards](~/concepts/cards/cards.md), [Card formatting](~/concepts/cards/cards-format.md) |