SPFx in Teams tab not rendering until browsed to in spo
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
macOS
What browser(s) / client(s) have you tested
- [ ] 💥 Internet Explorer
- [X] 💥 Microsoft Edge
- [X] 💥 Google Chrome
- [ ] 💥 FireFox
- [ ] 💥 Safari
- [ ] mobile (iOS/iPadOS)
- [ ] mobile (Android)
- [ ] not applicable
- [X] other (enter in the "Additional environment details" area below)
Additional environment details
- MacOS Teams Desktop Client
Describe the bug / error
I have a custom Teams personal app that has two tabs: one tab surfaces an spfx webpart, while the other a React SPA provisioned and deployed using the Teams Toolkit. After a couple days of not browsing to the custom Teams app, however, the tab that surfaces the SPFx component is stuck on a spinner -- the other tab has no problems. The console gives me the following error: App resource defined in manifest and iframe origin do not match failureCallback @ TeamsLogon.aspx?SPFX...rceLocale=en-us:240
In order to get the spfx tab to render I have to do the following in Chrome and Edge: browse to a SharePoint page with the webpart and then refresh the static tab in Teams
On the Teams Desktop client I added a reference to the SharePoint page in a Teams Channel and after browsing to that Teams channel tab I can then see the spfx component in the custom app's spfx tab
Steps to reproduce
- Create 3 webparts: a search webpart, a directory webpart, and a faculty webpart that references the two main components of the search and directory webparts. For example, the FacultyWebpart.tsx will render the Faculty.tsx component, whose function is to render the Search.tsx and Faculty.tsx components.
- Create your own teams manifest.json file in the teams folder of the SharePoint solution, so that when you deploy the sppkg it knows which webpart to make available in Teams
- Create a Fluent UI Personal app using the Teams Toolkit
- In the manifest.json inside the appPackage folder, create two static tabs: one that references the spfx webpart to be served and the other tab for the React app provided by Teams Toolkit
- Provision, Deploy, and send to Production
Expected behavior
I shouldn't have to browse to the SPO page with the spfx webpart to then see it in the custom Teams app
Here's what my Teams Toolkit manifest.json looks like:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.17/MicrosoftTeams.schema.json",
"version": "1.26.0",
"manifestVersion": "1.17",
"id": "bda4dea9-fa92-4f2c-81a1-8b95a8c70e40",
"name": {
"short": "Directory",
"full": "Full name for Directory"
},
"developer": {
"name": "JourneyTEAM, LLC",
"websiteUrl": "https://www.journeyteam.com",
"privacyUrl": "https://www.journeyteam.com",
"termsOfUseUrl": "https://www.journeyteam.com"
},
"description": {
"short": "Short description of DepartmentDirectory",
"full": "Full description of DepartmentDirectory"
},
"icons": {
"outline": "outline.png",
"color": "color.png"
},
"accentColor": "#FFFFFF",
"staticTabs": [
{
"entityId": "SPFxEmployeeDirectoryTab",
"name": "Faculty & Staff",
"contentUrl": "https://(redacted_domain_name).sharepoint.com/_layouts/15/TeamsLogon.aspx?SPFX=true&dest=/_layouts/15/teamshostedapp.aspx%3Fteams%26personal%26componentId=386dd1b8-71f5-4d5d-a568-b44b211067f0%26forceLocale=en-us",
"scopes": [
"personal"
],
"context": [
"personalTab"
]
},
{
"entityId": "DepartmentDirectoryTab",
"name": "Departments",
"contentUrl": "https://ashy-hill-0f884b110.5.azurestaticapps.net/index.html#/department-directory",
"websiteUrl": "https://ashy-hill-0f884b110.5.azurestaticapps.net/index.html#/department-directory",
"scopes": [
"personal"
]
},
{
"entityId": "about",
"scopes": [
"personal"
]
}
],
"validDomains": [
"(redacted_domain_name).sharepoint.com",
"ashy-hill-0f884b110.5.azurestaticapps.net",
"*.login.microsoftonline.com",
"*.sharepoint.com",
"*.sharepoint-df.com",
"spoppe-a.akamaihd.net",
"spoprod-a.akamaihd.net",
"ashy-hill-0f884b110.5.azurestaticapps.net*"
],
"webApplicationInfo": {
"id": "2db8265f-5a18-4d83-a39c-335603046850",
"resource": "api://ashy-hill-0f884b110.5.azurestaticapps.net/2db8265f-5a18-4d83-a39c-335603046850"
},
"authorization": {
"permissions": {
"resourceSpecific": []
}
}
}
Here's what my spfx teams manifest.json looks like:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.17/MicrosoftTeams.schema.json",
"version": "1.2",
"manifestVersion": "1.17",
"id": "aa1185ab-38c1-4621-b54d-90e94523e602",
"developer": {
"name": "JourneyTEAM, LLC",
"mpnId": "",
"websiteUrl": "https://www.journeyteam.com",
"privacyUrl": "https://www.journeyteam.com",
"termsOfUseUrl": "https://www.journeyteam.com"
},
"name": {
"short": "Teams Faculty Directory",
"full": "Teams Faculty Directory"
},
"description": {
"short": "Teams Employee Directory description",
"full": "Teams Employee Directory description"
},
"icons": {
"outline": "aa1185ab-38c1-4621-b54d-90e94523e602_outline.png",
"color": "aa1185ab-38c1-4621-b54d-90e94523e602_color.png"
},
"accentColor": "#FFFFFF",
"staticTabs": [
{
"entityId": "Belmont Faculty Directory",
"name": "Faculty Directory",
"contentUrl": "https://(redacted_domain_name).sharepoint.com/_layouts/15/TeamsLogon.aspx?SPFX=true&dest=/_layouts/15/teamshostedapp.aspx%3Fteams%26personal%26componentId=386dd1b8-71f5-4d5d-a568-b44b211067f0%26forceLocale=en-us",
"scopes": ["personal"],
"context": ["personalTab"]
},
{
"entityId": "about",
"scopes": ["personal"]
}
],
"validDomains": [
"*.login.microsoftonline.com",
"*.sharepoint.com",
"*.sharepoint-df.com",
"spoppe-a.akamaihd.net",
"spoprod-a.akamaihd.net",
"resourceseng.blob.core.windows.net",
"msft.spoppe.com"
],
"webApplicationInfo": {
"id": "00000003-0000-0ff1-ce00-000000000000",
"resource": ""
}
}
Here's an example of how I call the two components from two separate webparts:
import * as React from "react";
import { useMemo, useState } from "react";
import styles from "./FacultyStudentTeamsDirectory.module.scss";
import type { IFacultyStudentTeamsDirectoryProps } from "./IFacultyStudentTeamsDirectoryProps";
import EmployeeDirectory from "../../employeeDirectory/components/EmployeeDirectory";
import { IReactTemplateProps } from "@journeyteam/directory-extensions";
import SearchBox from "../../searchBox/components/SearchBox";
import { ISelectedRefiner, ISelectedRefinerValues } from "../../../models/refiner";
import * as SPSearch from "@pnp/sp/search/types";
export declare enum TemplateType {
adaptiveCard = "adaptive-card",
react = "react",
handlebars = "handelbars",
}
export default function FacultyStudentTeamsDirectory(props: IFacultyStudentTeamsDirectoryProps) {
const {
isDarkTheme,
hasTeamsContext,
initialSearchText,
employeeCardTemplate,
studentView,
propertyPanelOpen,
focusSections,
directoryRefiners,
refiners,
} = props;
const [selectedRefiners, setSelectedRefiners] =
useState<ISelectedRefinerValues[]>(directoryRefiners);
const [searchBoxRefinersSourceData, setSearchBoxRefinersSourceData] = useState<
SPSearch.IRefiner[]
>([]);
const [searchText, setSearchText] = useState(initialSearchText ? initialSearchText : "");
const [cardWidth, setCardWidth] = useState(275);
useMemo(() => {
const handleResize = () => {
if (window.innerWidth < 500) {
setCardWidth(150);
} else if (window.innerWidth < 800) {
setCardWidth(200);
} else {
setCardWidth(275);
}
};
// Call the handleResize function initially to set the width based on the current viewport size
handleResize();
// Set up the event listener for the resize event
window.addEventListener("resize", handleResize);
// Clean up the event listener when the component is unmounted
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
const searchBoxRefinersChanged = (searchBoxRefiners: ISelectedRefiner[]) => {
const mappedSelectedRefiners = refiners.map<ISelectedRefinerValues>((refiner) => {
const matchedRefiners = searchBoxRefiners.filter(
(selectedRefiner) => selectedRefiner.Name === refiner.PropertyName
);
return {
PropertyName: refiner.PropertyName,
SelectedRefiners: matchedRefiners,
};
});
setSelectedRefiners(mappedSelectedRefiners);
};
const onSearchChange = (val: string) => {
setSearchText(val);
};
const _refinersChanged = (refiners: SPSearch.IRefiner[]) => {
if (searchBoxRefinersSourceData.length === 0) {
setSearchBoxRefinersSourceData(refiners);
}
if (searchBoxRefinersSourceData[0]?.Entries.length < 20) {
setSearchBoxRefinersSourceData(refiners);
}
};
return (
<section
className={`${styles.facultyStudentTeamsDirectory} ${hasTeamsContext ? styles.teams : ""}`}>
<SearchBox
onSearchChanged={onSearchChange}
initialSearchText={initialSearchText}
refinerSourceData={searchBoxRefinersSourceData}
refiners={props.refiners}
onSelectedRefinersChanged={searchBoxRefinersChanged}
searchByFilters={props.searchByFilters}
searchByLabel={undefined}
searchByPlaceholder="Search By"
refinersLabel=""
refinersPlaceholder="Search Refiners"
searchLabel={""}
searchPlaceholder={""}
/>
<br />
<br />
<EmployeeDirectory
searchText={`${
searchText}*`}
itemsPerPage={20}
preFilter={`-"SPS-HideFromAddressLists":1`}
refiners={selectedRefiners}
onRefinersChanged={_refinersChanged}
useLibraryTemplate={false}
showProfileLink={undefined}
customStyles={undefined}
employeeCardTemplate={employeeCardTemplate}
focusSections={focusSections}
headerSections={props.headerSections}
otherSections={[]}
sourceId={undefined}
sort={[
{
Property: "firstName",
Direction: 0,
},
]}
hiddenRefiner={[]}
serviceScope={props.serviceScope}
context={props.context}
templates={props.templates}
editMode={true}
employeeCardWidth={cardWidth}
propertyPanelOpen={propertyPanelOpen}
paginationLocation={1}
toggleDirectReportsExport={false}
directReportsExportUrl=""
studentView={studentView}
isDarkTheme={isDarkTheme}
/>
</section>
);
}
Further update...just deploying my spfx solution and syncing to Teams works as a standalone personal app. The personal app that has multiple personal tabs (one being the spfx component and the other being a React app provisioned and deployed in Entra) doesn't work for the spfx tab until I first navigate to the standalone spfx personal app
@VesaJuvonen any update on your guys end by chance?
From what I'm seeing, seems the issue may lie in that the teams app manifest only allows for one set of id and resource to be referenced in the webApplicationInfo. In my case, one tab is leveraging an spfx component (resource would be the teamsitedomain and id the multi-tentant Microsoft Graph app id) and the other a teams app that was provisioned in entra using the Teams Toolkit.
Hello @JonoSuave, Thank you for bringing this issue to our attention. We will look into it and get back to you shortly. Could you please confirm if the issue still persists for you?
I believe this issue occurs when you have two tabs on a team’s static app with one being a teams-first app and the other being an spfx-first app.
On Wed, Apr 30, 2025 at 5:25 AM Amey-MSFT @.***> wrote:
Amey-MSFT left a comment (SharePoint/sp-dev-docs#9920) https://github.com/SharePoint/sp-dev-docs/issues/9920#issuecomment-2841672623
Hello @JonoSuave https://github.com/JonoSuave, Thank you for bringing this issue to our attention. We will look into it and get back to you shortly. Could you please confirm if the issue still persists for you?
— Reply to this email directly, view it on GitHub https://github.com/SharePoint/sp-dev-docs/issues/9920#issuecomment-2841672623, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFPH445NYE2NZ6I32O7EIBT24CXMHAVCNFSM6AAAAABOJ5GQJCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQNBRGY3TENRSGM . You are receiving this because you were mentioned.Message ID: @.***>
Hello @JonoSuave, We were able to reproduce the issue, and we are investigating it. We have logged this as a bug, and our engineering team will look into it. Thank you!
Awesome, thanks for the update!
On Sun, May 4, 2025 at 10:12 PM Amey-MSFT @.***> wrote:
Amey-MSFT left a comment (SharePoint/sp-dev-docs#9920) https://github.com/SharePoint/sp-dev-docs/issues/9920#issuecomment-2849864583
Hello @JonoSuave https://github.com/JonoSuave, We were able to reproduce the issue, and we are investigating it. We have logged this as a bug, and our engineering team will look into it. Thank you!
— Reply to this email directly, view it on GitHub https://github.com/SharePoint/sp-dev-docs/issues/9920#issuecomment-2849864583, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFPH446CJ3N7YZC52BBOWID243QJ7AVCNFSM6AAAAABOJ5GQJCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQNBZHA3DINJYGM . You are receiving this because you were mentioned.Message ID: @.***>