SPFx WebPart Disappearing
This post will go over an odd “bug” where SPFx webparts may be removed from the page.
Overview of Issue
When adding a webpart to a page and setting its properties, I noticed that it would disappear after refreshing the page. My webpart property was storing a JSON configuration in a multi-line text field property. I was able to save the page, which seemed like the webpart page saved correctly; but after refreshing the page it was removed. When you edit the page, you will see a very helpful message:
I’ve tried to search on this issue, but was unable to find anything. Further testing pointed my issue to my SPFx webpart properties, so I thought it was my code. It was actually the value I was putting in there. This post will go over this issue by recreating it in a basic “Hello World” solution.
Overview of Solution
For those who don’t want to read the entire post. You can’t use the double brackets ([[ ]]
) within HTML
for a text webpart property value.
Create Solution
For this example, I’m going to use the offical Hello World solution from Microsoft. Below are the properties I used:
- Which type of client-side component to create?: WebPart
- What is your Web part name?: TestPropertyBug
- Which template would you like to use?: No framework
Update WebPart Properties
The first step is to update the webpart properties. I wanted to test both the single line and multi-line text properties. We will use the default Description
property for the single line text, but will need to add a multi-line option for this test.
Update Strings
Update the following files to add the new Configuration
webpart property.
loc/en-us.js
Add the ConfigurationFieldLabel
property.
define([], function() {
return {
"PropertyPaneDescription": "Description",
"BasicGroupName": "Group Name",
"ConfigurationFieldLabel": "Configuration Field",
"DescriptionFieldLabel": "Description Field",
"AppLocalEnvironmentSharePoint": "The app is running on your local environment as SharePoint web part",
"AppLocalEnvironmentTeams": "The app is running on your local environment as Microsoft Teams app",
"AppSharePointEnvironment": "The app is running on SharePoint page",
"AppTeamsTabEnvironment": "The app is running in Microsoft Teams"
}
});
loc/mystrings.d.ts
Add the ConfigurationFieldLabel
property.
declare interface ITestPropertyBugWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
ConfigurationFieldLabel: string;
DescriptionFieldLabel: string;
AppLocalEnvironmentSharePoint: string;
AppLocalEnvironmentTeams: string;
AppSharePointEnvironment: string;
AppTeamsTabEnvironment: string;
}
declare module 'TestPropertyBugWebPartStrings' {
const strings: ITestPropertyBugWebPartStrings;
export = strings;
}
Update WebPart Code
In the main webpart code, we will make the following updates.
Interface
Add the configuration
property to store the new multi-line property value.
export interface ITestPropertyBugWebPartProps {
configuration: string;
description: string;
}
WebPart Property Configuration Pane
The next step is to add the new configuration
multi-line property to the configuration.
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
}),
PropertyPaneTextField('configuration', {
label: strings.ConfigurationFieldLabel,
multiline: true,
rows: 15
})
]
}
]
}
]
};
}
Optional
You don’t need to add this option, but if you would like to disable reactive changes add the following code to the file.
protected get disableReactivePropertyChanges(): boolean { return true; }
Render
The last step is to update the render method to include the configuration
property. We will just render the value under the description
value.
public render(): void {
this.domElement.innerHTML = `
<section class="${styles.testPropertyBug} ${!!this.context.sdks.microsoftTeams ? styles.teams : ''}">
<div class="${styles.welcome}">
<img alt="" src="${this._isDarkTheme ? require('./assets/welcome-dark.png') : require('./assets/welcome-light.png')}" class="${styles.welcomeImage}" />
<h2>Well done, ${escape(this.context.pageContext.user.displayName)}!</h2>
<div>${this._environmentMessage}</div>
<div>Web part property <strong>description</strong>: ${escape(this.properties.description)}</div>
<div>Web part property <strong>configuration</strong>: ${escape(this.properties.configuration)}</div>
</div>
<div>
<h3>Welcome to SharePoint Framework!</h3>
<p>
The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It's the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling.
</p>
<h4>Learn more about SPFx development:</h4>
<ul class="${styles.links}">
<li><a href="https://aka.ms/spfx" target="_blank">SharePoint Framework Overview</a></li>
<li><a href="https://aka.ms/spfx-yeoman-graph" target="_blank">Use Microsoft Graph in your solution</a></li>
<li><a href="https://aka.ms/spfx-yeoman-teams" target="_blank">Build for Microsoft Teams using SharePoint Framework</a></li>
<li><a href="https://aka.ms/spfx-yeoman-viva" target="_blank">Build for Microsoft Viva Connections using SharePoint Framework</a></li>
<li><a href="https://aka.ms/spfx-yeoman-store" target="_blank">Publish SharePoint Framework applications to the marketplace</a></li>
<li><a href="https://aka.ms/spfx-yeoman-api" target="_blank">SharePoint Framework API reference</a></li>
<li><a href="https://aka.ms/m365pnp" target="_blank">Microsoft 365 Developer Community</a></li>
</ul>
</div>
</section>`;
}
Test Solution
Update the config/serve.json
file with your tenant url information, and run gulp serve
to test out the solution. Below is what you should see:
Deploy to App Catalog
Run the following commands to package the solution.
gulp clean --ship
gulp build --ship
gulp bundle --ship
gulp package-solution --ship
Once the package is created, upload it to the tenant app catalog and deploy it. To simplify the deployment, I made the solution available to all sites immediately. This will skip the step to “Add an App” to the test site we will use.
Test WebPart
Create a modern Site Page
and publish it for now.
Test Steps
These are the test steps taken for each example.
- Edit the Page
- Set the property
- Click on
Apply
to save the properties - Click on
Save as Draft
orRepublish
to save the page and return toDisplay
mode - Refresh the page (Ctrl+F5)
- Validate the webpart is still on the page
Test Single-Line Issue
[Pass] Test 1 - Plain Text
This is a test.
[Pass] Test 2 - Use of [[ ]]
This is a [[test]].
[Fail] Test 3 - Use of [[ ]] within HTML
<p>This is a [[test]].</p>
When you edit the page, you will see the following error:
Test Multi-Line Issue
[Pass] Test 1 - Use of [[ ]]
This is a test for storing [[values]] with a bracket around it.
[Pass] Test 2 - Use of [[ ]] within Quotes
"This is a test for storing [[values]] with a bracket around it."
[Pass] Test 3 - Use of [[ ]] within JSON
{
"test": "This is a test for storing [[values]] with a bracket around it."
}
[Fail] Test 4 - Use of [[ ]] within HTML and JSON
{
"test": "<p>This is a test for storing [[values]] with a bracket around it.</p>"
}
When you edit the page, you will see the following error:
[Pass] Test 5 - Use of [ ] within HTML and JSON
{
"test": "<p>This is a test for storing [values] with a bracket around it.</p>"
}
Summary
The overall bug is when you use double brackets ([[ ]]) within HTML. If you use single brackets ([ ]) within HTML, it will work fine. I hope this helps others out who may have run across this issue.