Tips and tricks¶
- Microsoft 365 help & learning
- PnP-SPFx-Blog
- Teams Developer Portal
- Pattern & Practises
- Sample Solution Gallery
- Microsoft 365 Extensibility look book gallery
- Microsoft 365 Community Content
- SharePoint For IT Professionals
- SharePoint development
- SharePoint Videos
- Etiquette of Microsoft 365
- Tips & Tricks Coding/SPFX/AzureAD
Shortcut List¶
- cmd.ms | Installation cms.ms
- msportals
- akasearch
- verification-toolset
- Microsoft 365 Message Center Archive
Feedback¶
M365 Docs¶
- microsoft-365
- Microsoft 365 glossary
- SPFx-Json-Schemas
- Microsoft 365 and Office 365 service descriptions
- Microsoft 365 Community Content
Start SPFx Training¶
- SPFx documentation
- Why did Microsoft create the SharePoint Framework?
- What is the SharePoint Framework?
- SharePoint Framework - Getting started
- SharePoint Developer Community - Open-source projects
- Updated SharePoint Framework developer training package now available (2019)
- SharePoint Developer GitHub repositories
- Gateway to Office 365 Training Resources from Microsoft
- Set up an Office 365 developer subscription
- Frontend Workshop from HTML/CSS/JS to TypeScript/React/Redux
- Microsoft Learning Module
- HOW TO GET STARTED WITH REACT FOR BUILDING ADVANCED SPFX SOLUTIONS
- HOW TO USE THE SERVICE PATTERN IN SPFX REACT SOLUTIONS
- Nanddeepn-Getting Started Slides
- Recap of Getting Started SharePoint Framework (SPFx) Webinar Series 2020
- PiaSys: Conferences-Samples
- PnP Virtual Conference – September 2020 – Summary and Recordings
- Microsoft 365 learning pathways
Start SPFx React Development¶
- SPFx Essentials my Getting Started Video | E003
- How to Style your Custom SPFx Web Part to look OOB | E004
- PT2: Custom SPFx Web Part looking like it's OOB | E005
- SPFx, Post Request, React Hooks, and Fluent UI forms | E006
Start Teams Development¶
Reference Samples¶
- SPFx samples in the Microsoft 365 Unified Sample gallery
- SharePoint Framework Client-Side Web Part Samples
- Microsoft Teams Development Samples
- SafeDesk365
- SharePoint Framework DataTable
- Lead Assist Dashboard
- Executive Room Reservation Reference Microsoft Teams Personal App
- News article content at a glance
- react content query online
- Fakeflix - WebApp to learn React/Redux and more
- react-roomchat - Azure Communications Services Building SPFx solution with Azure Communication Services integration
- @pnp/js and ReactJS Functional Components
- React Flight Tracker
- Extend Teams app to other M365 host apps like Outlook, Office.com
- microsoft365dev
- Exposing business data in Microsoft 365 using Azure Data API builder
- ace-expense-report
M365 Full Stack / SPFx¶
Enterprise Reference Samples¶
- Enterprise-grade Reference Architecture for JavaScript
- Rhythm of Business Calendar - SPFx Solution Accelerator - Domain Driven Design
- Rhythm of Business Calendar - SPFx Solution Accelerator Deep Dive
- Contoso Retail Dashboard
- Video: Microsoft 365 & Power Platform weekly call – 6th of June, 2023
PnPJS-V3¶
Fluent UI¶
- fluent2.microsoft.design
- Fluent UI React Components
- Installing the fluent ui components
- Fluent UI 9 SPFx Sample
- Updated Fluent UI 9 Demo to latest SPFx and Fluent UI 9
Learning SPFx Videos¶
- SharePoint Framework for beginners 2021 | Episode 01 - Introduction
- SharePoint Framework for beginners 2021 | Episode 02 - Development Environment
DEV-Tenant¶
- Welcome to the Office 365 Developer Program
- New renewable Office 365 developer subscriptions launch on April 3rd
- 10 Tips for Demo/Dev Tenant
- how-to-use-the-complimentary-azure-credits-in-a-microsoft-365-developer-tenant-step-by-step
- What is a "Dev Tenant" and why would you want one?
Development Roadmap¶
- microsoft-changelog
- SPFx Roadmap / Release Notes
- Microsoft 365 Roadmap
- Monthly Updates about M365 News
Code Guideline¶
- Best practices in cloud applications
- Patterns and Practices for SPFx Development
- Typescriptlang - Handbook
- Airbnb React/JSX Style Guide
- Airbnb JavaScript Style Guide
- Office fabric react - Coding Guidelines
- Office fabric react - React-Guideline
- Office fabric react - TypeScript-Guidelines
- react-typescript-cheatsheet
- Setup TypeScript with React
- Design Patterns
- Awesome React Components & Libraries
Performance Guideline¶
- PnP Virtual Conference - 09/2020 - Ways to optimize SharePoint Framework highly custom Intranet
- SharePoint Framework performance optimization list
- Performance guidance for SharePoint Online portals
- Optimize SPFx Sample
Design Guideline¶
- sharepoint look book
- Official product colors for Microsoft apps
- Teams UI Component Library
- Figma UI Kit for Teams
Code Review Checklist¶
Security Guideline¶
- Basic Security Set Up for Microsoft 365
- Security Scanning a SharePoint Framework Solution
- Security Engineering Portal
- Automate Azure DevOps code security analysis with the Microsoft Security Code Analysis extensions
- Allow or prevent custom script
Granting Permission¶
- Beware of Declarative Permissions in SharePoint Framework Projects
- Easily grant API permissions with the Office 365 CLI
- Logging in to Office 365
m365 spo login https://<tenant>-admin.sharepoint.com
spo serviceprincipal grant add --resource 'Microsoft Graph' --scope 'Mail.Read'
Content Style Guide¶
Coding Patterns¶
SPFx Workflow¶
SharePoint PNP Community¶
Create Project (pnpm)¶
with pnpm manager
yo @microsoft/sharepoint –package-manager pnpm
pnpm i tslint@5.9.1 -DE
pnpm i typescript@2.4.2 -DE
Check Package Version¶
node –v
npm –v
yo --generators
gulp –v
tsc –v
tsd --version
Git Basics¶
Init local repo
git init
Add all Files to local repo
git add -A
git commit -m "init repo"
Show last commit
git show --name-only
show full history
git log --full-history --src/path/to/file.js
- The Smart Ways to Correct Mistakes in Git
- A successful Git branching model
- GitHub cheat sheet for PnP contributions
- Illustrated Notes on Fixing Git Mistakes
Development(local workbench)¶
Importend: only for spfx < 13.1
gulp serve
https://localhost:4321/temp/workbench.html
Development(online workbench)¶
gulp serve --nobrowser
/_layouts/15/workbench.aspx?forceLocale=de-de
/_layouts/workbench.aspx
Prepare Deployment Solution¶
gulp clean
gulp build --ship
gulp bundle --ship
gulp package-solution --ship
Debug in vs.code¶
Checklist SPFx initial¶
Update Version¶
npm version major
npm version minor
npm version patch
Add imported pnp modules¶
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/graph --save
npm install @pnp/spfx-controls-react@latest --save --save-exact
npm install @pnp/spfx-property-controls@latest --save --save-exact
Localizations¶
- Location files are in JSON format
- They work similar as Resources files (XML) on VS Solution
- The default language is English (en-us)
- Developers can test the locale by:
- Updating write-manifests.json file
{
"cdnBasePath": "<!-- PATH TO CDN -->",
"debugLocale": "de-de"
}
or by using the "locale" command argument
gulp serve --locale=de-de
App Permission¶
- Working with Application Permissions (App-Only Auth) in SharePoint Online and the Microsoft Graph
- SharePoint lifehacks: create SharePoint app registration with client secret which never expires
SharePoint Online Data¶
MSGraph Data¶
Scoped service¶
- Elegant Dependency Injection in SPFx
- SPFx WebPart scoped service
- Using React hooks to globally share service scope between components
- SPFX Service Scopes Hooks
Data Service¶
- APIs Everywhere
- RSS Reader
- Sample FieldVisitTab
- SPFx – How to handle large list items
- Filter large lists in SharePoint Online
Sample Folder structure
- barrel: each folder should has a index.ts file
-
src
- models
- IHelpDeskItem.ts
- index.ts
- services
- IDataService.ts
- MockDataservice.ts
- SharepointDataService.ts
- index.ts
- webparts
- components
- loc
- WebpartNameWebPart.ts
Data Model¶
Interface to define our Data structure
export interface IHelpDeskItem {
id?: number;
title?: string;
description?: string;
level?: string;
status?: string;
assignedTo?: string;
resolution?: string;
}
Interface to define our Data Access services
import { IHelpDeskItem } from "./../models/IHelpDeskItem";
import { WebPartContext } from "@microsoft/sp-webpart-base";
export default interface IDataService {
getTitle(): string;
isConfigured(): boolean;
getItems(context: WebPartContext): Promise<IHelpDeskItem[]>;
addItem(item: IHelpDeskItem): Promise<void>;
deleteItem(id: number): Promise<void>;
}
Mocking Service for testing in local Workbench development
import { IHelpDeskItem } from "./../models/IHelpDeskItem";
import IDataService from "./IDataService";
import { IWebPartContext } from "@microsoft/sp-webpart-base";
export default class MockDataService implements IDataService {
...
private _webPartContext: IWebPartContext;
private _listId: string;
constructor(webPartContext: IWebPartContext, listId: string) {
this._webPartContext = webPartContext;
this._listId = listId;
}
...
public getItems(context: IWebPartContext): Promise<IHelpDeskItem[]> {
return new Promise<IHelpDeskItem[]>((resolve, reject) => {
setTimeout(() => resolve([
{
id : 1,
title : "That doesn't work",
description : "When I do that, it doesn't work",
level : "Low",
status: "Open",
resolution: "Do this and it will work!",
assignedTo: "Sébastien Levert",
}
]), 300);
});
}
}
Get Data with Sharepoint REST¶
public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {
return new Promise<IHelpDeskItem[]>((resolve, reject) => {
context.spHttpClient
.get( `${this._webPartContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById('${this._listId}')/items` +
`?$select=*,HelpDeskAssignedTo/Title&$expand=HelpDeskAssignedTo`, SPHttpClient.configurations.v1)
.then(res => res.json())
.then(res => {
let helpDeskItems:IHelpDeskItem[] = [];
for(let helpDeskListItem of res.value) {
helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));
}
resolve(helpDeskItems);
})
.catch(err => console.log(err));
});
}
Get Data with Pnp-JS-Core¶
Reference Sample
Advantages
- Type safe so you get your errors while you code and not when you execute and test
- Works on all versions of SharePoint (On-Premises, Online, etc.)
- Offers built-in caching mechanisms
- Heavily used in the SharePoint Development Community
Init context in react webpart component source
public onInit(): Promise<void> {
return super.onInit().then(_ => {
pnpSetup({
spfxContext: this.context
});
});
}
init service in react webpart component
public render(): void {
const element: React.ReactElement<IListContentProps> = React.createElement(
ListContent,
{
context: this.context,
dataService: this.getDataService(),
list: this.properties.list
}
);
ReactDom.render(element, this.domElement);
}
Get items from list Source
public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {
return new Promise<IHelpDeskItem[]>((resolve, reject) => {
sp.web.lists.getById(this._listId).items
.select("*", "HelpDeskAssignedTo/Title")
.expand("HelpDeskAssignedTo").getAll().then((sessionItems: any[]) => {
let helpDeskItems:IHelpDeskItem[] = [];
for(let helpDeskListItem of sessionItems) {
helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));
}
resolve(helpDeskItems);
});
});
}
Get Search Data with async/await¶
Using PnPJS and Async/Await to Really Simplify Your API Calls
async/await
private async _getSiteData(): Promise<ISPSite[]> {
var thisDomain: string = location.host.split(".")[0];
var exclusions: string[] = ["https://" + thisDomain + "-my.sharepoint.com", "https://" + thisDomain + ".sharepoint.com/portals/personal"];
var exclusionString: string = " -Path:" + exclusions.join(" -Path:");
exclusionString += " -Path=https://" + thisDomain + ".sharepoint.com";
try {
let result = await sp.search(<SearchQuery>{
Querytext: "contentclass:sts_site " + exclusionString,
RowLimit: 500,
TrimDuplicates: false,
Properties: [{
Name:"EnableDynamicGroups",
Value: {
BoolVal: true,
QueryPropertyValueTypeIndex: QueryPropertyValueType.BooleanType
}
}],
SelectProperties: ["Title", "Path", "SiteLogo"]
});
return this.processSearchResults(result);
} catch (e) {
console.error(e);
return null;
}
}
public async getShipmentStatuses(serviceProps: IServiceProperties): Promise<IStatus[]> {
try {
let items = await sp
.web
.lists
.getByTitle("SL_ShippingStatuses")
.items
.select("Id", "Title", "SortOrder", "CanBeCancelled")
.orderBy("SortOrder")
.get(spODataEntityArray<Item, IStatus>(Item));
return items;
} catch (e) {
console.error(e);
return null;
}
}
private async _getItems() {
let select = '*';
let expand = 'File';
let filter = '';
// filter by selected term if required
if (this.props.term !== undefined && this.props.term !== null && this.props.term.length > 0) {
const term = this.props.term[0];
select = `${select},TaxCatchAll/Term`;
expand = `${expand},TaxCatchAll`;
filter = `TaxCatchAll/Term eq '${term.name}'`;
}
const items = await sp.web.lists.getById(this.props.list).items
.select(select)
.expand(expand)
.filter(filter)
.get();
// update state
this.setState({
items: items ? items : []
});
console.log('List Items:', this.state.items);
}
Get Data from MSGraph¶
- Using PnPjs to send requests to MS Graph with SharePoint Framework 1.6
- Example of wrapper to ease usage of Graph calls in SPFx
- msgraph-helper
- SPFx webpart with MS Graph and PnPjs: step by step guide
Start Office Fabric React¶
Create Sample
- Use Office UI Fabric React components in your SharePoint client-side web part
- TypeScript React Starter
- React app with an Office UI Fabric React DocumentCard
create-react-app demo-office-fabric-react-ts --scripts-version=react-scripts-ts
init git
git init
git add .
git commit -m "Initial commit."
add office fabric react
- office-ui-fabric-react@5.131.0
- Use Office UI Fabric React components in your SharePoint client-side web part
npm install office-ui-fabric-react@5.132.0 --save
Generator for SP applications¶
Upgrade yo generator SPFx¶
npm list -g --depth=0
npm ls -g --depth=0 @microsoft/generator-sharepoint
npm outdated --global
npm install @microsoft/generator-sharepoint@latest --global
SPFx Version Upgrade¶
Office 365 CLI¶
- Office 365 User Guide
- Comparison to SharePoint PowerShell
- Office 365 GitHhub Actions
- GETTING STARTED WITH THE OFFICE 365 CLI
- Working with Office365 CLI and JSON parameters
- CLI.Microsoft365.PowerShell.Predictor
Latest version
npm i -g @pnp/cli-microsoft365@latest
Latest Beta version
npm i -g @pnp/cli-microsoft365@next
Create report for upgrade
m365 spfx project upgrade --shell powershell --toVersion 1.12.1 --output md > report.md
Update SPFx packages¶
Custom yo spfx generator¶
Add External JS-Frameworks¶
- How to add external libraries and assets in SharePoint client-side web part
- Loading dependent JS files into SPFx Solution in right order
- How To Include JavaScript Files In SharePoint Framework Solutions?
SPFx Utilities¶
- Utility functions which you might not know existed in SPFx
- SPFx Fast Serve Tool
- sp-formatter
- SP Formatter: the big update
- SharePoint produtivity tools
- Ultimate Developer Tool List for SPFx