100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Microsoft 365

Tabs: Personal and Channel

Teams tabs embed web content inside the client as either a personal, always-available experience or a per-channel configured instance, powered by the Teams JavaScript SDK.

Building Teams AppsBeginner9 min readJul 10, 2026
Analogies

Personal Tabs vs. Channel Tabs

A tab in Teams is fundamentally an iframe pointing at a web page you host, surfaced inside the Teams shell. Personal tabs live in the user's personal app bar on the left side and show the same content to that user regardless of which team or chat they're in; they're declared in the manifest's staticTabs array with a fixed contentUrl. Channel (or group) tabs, declared as configurableTabs, are added inside a specific channel or group chat and can hold different configuration per instance, for example a Planner tab pinned to one channel showing that channel's specific plan.

🏏

Cricket analogy: A personal tab is like a player's individual kit bag that travels with them to every match regardless of venue, while a channel tab is like a scoreboard fixed to one specific stadium showing only that ground's live match.

Configuring a Channel Tab

When a user adds a configurableTab to a channel, Teams opens the configurationUrl in an iframe and calls the Teams JS SDK's pages.config.registerOnSaveHandler, letting the tab set entityId, contentUrl, and a display name for this specific instance before the user clicks Save. Those values are persisted per channel, so the same tab app can show a different Trello board, Jira project, or SharePoint document library depending on which channel it was configured in. The SDK also exposes pages.config.setValidityState(true) so the Save button only becomes clickable once the user has picked valid configuration options.

🏏

Cricket analogy: The configurationUrl step is like a groundskeeper setting up a pitch's specific dimensions and boundary rope before a match, a one-time setup that determines everything that happens on that ground afterward.

Using the Teams JavaScript SDK Inside a Tab

Every tab must call app.initialize() from the @microsoft/teams-js package before doing anything else; this handshake tells the Teams client the iframe is ready and returns context via app.getContext(), including the current user's UPN, tenant id, theme (default, dark, or high-contrast), and the entityId if the tab is channel-scoped. Tabs should also register app.registerOnThemeChangeHandler to restyle instantly when a user toggles Teams' dark mode, since the SDK does not do this automatically. For pages needing an identity beyond the basic context, authentication.getAuthToken() (or the newer app.getContext combined with an Azure AD SSO flow) retrieves an access token scoped to the app's Azure AD registration without a separate login popup, provided webApplicationInfo is correctly set in the manifest.

🏏

Cricket analogy: app.initialize() is like a batter tapping their bat on the crease to signal readiness to the umpire before the bowler runs in, a required handshake before any play can proceed.

javascript
import { app, pages, authentication } from "@microsoft/teams-js";

async function initTab() {
  await app.initialize();

  const context = await app.getContext();
  console.log(`User: ${context.user?.userPrincipalName}, Theme: ${context.app.theme}`);

  app.registerOnThemeChangeHandler((theme) => {
    document.body.className = theme; // "default" | "dark" | "contrast"
  });

  // Configurable tab: enable Save once a project is chosen
  pages.config.registerOnSaveHandler(async (saveEvent) => {
    await pages.config.setConfig({
      entityId: "project-123",
      contentUrl: "https://tabs.contoso.com/project/123",
      suggestedDisplayName: "Project 123"
    });
    saveEvent.notifySuccess();
  });
  pages.config.setValidityState(true);

  // Silent SSO
  const token = await authentication.getAuthToken();
}

initTab();

app.getContext() is also how a tab detects it's rendering inside a meeting stage versus a normal channel tab, via context.page.frameContext. Meeting-aware tabs use this to switch between a full collaborative view (sidePanel or meetingStage) and a compact configuration view.

Tabs can navigate the Teams client itself, not just their own iframe, using pages.navigateToApp to jump to another tab within the same app, or pages.currentApp.navigateTo to move between subpages of a single-page app while keeping Teams' back-button and browser history in sync. Deep links generated with pages.shareDeepLink or the standard https://teams.microsoft.com/l/entity/{appId}/{entityId} format let a tab construct a URL that opens Teams directly to a specific entity, which is heavily used for notification emails or bot cards that need to route a click back into a precise tab state.

🏏

Cricket analogy: A deep link to a specific entityId is like a TV broadcast cutting directly to over 42.3 of a match rather than making viewers scrub through the whole day's play from ball one.

Forgetting to call app.initialize() (or calling Teams JS SDK APIs before it resolves) is the most common tab bug — the iframe will appear to hang or context calls will silently return undefined. Always await it as the very first line of your tab's bootstrap code.

  • Personal tabs (staticTabs) show identical content to a user everywhere; channel tabs (configurableTabs) are configured per channel or group chat instance.
  • Channel tabs require a one-time configurationUrl setup that calls pages.config.registerOnSaveHandler and setValidityState.
  • Every tab must call app.initialize() before any other Teams JS SDK call, or context calls will fail silently.
  • app.getContext() exposes user, tenant, theme, and frame context (e.g., meeting stage) for adaptive rendering.
  • registerOnThemeChangeHandler must be wired manually to support Teams' dark and high-contrast themes.
  • authentication.getAuthToken() enables silent SSO when webApplicationInfo is correctly configured in the manifest.
  • Deep links via entityId let notifications and bot cards route users directly into a specific tab state.

Practice what you learned

Was this page helpful?

Topics covered

#Microsoft365#MicrosoftTeamsDevelopmentStudyNotes#MicrosoftTechnologies#TabsPersonalAndChannel#Tabs#Personal#Channel#Configuring#StudyNotes#SkillVeris