If you’ve ever built an SPFx web part and noticed it looks like an uninvited guest — sporting a bright blue palette on a red-themed SharePoint site — you already know why reading the current theme matters. Your web part should blend in, not stick out like a sore thumb.
In this tutorial, I’ll walk you through exactly how to get the current theme in SPFx. I’ll cover three practical methods, give you real code you can drop into your project, and explain when to use each approach.
Why Theme Awareness Matters in SPFx
When SharePoint scaffolds a new web part for you, it ships with a fixed blue palette baked into the CSS. That’s fine for demos, but in the real world, every organization has its own branding. Site admins pick red themes, green themes, dark themes — and your hard-coded blue buttons will clash with all of them.
Getting the current theme lets your web part:
- Automatically adapt colors to whatever theme the site is using
- Respond when users switch section backgrounds (neutral, soft, strong, etc.)
- Work correctly in Teams too, including dark mode and high-contrast mode
- Look like it belongs — not like a third-party plugin that got dropped in
Check out SPFx Web Part Audience Targeting
Understanding SPFx Theming Basics
SharePoint themes are made up of tokens. Instead of hard-coding #0078d7, you reference a token like themePrimary, and SharePoint swaps in the right hex value at runtime.
There are two layers you’ll deal with:
- Palette colors — things like
themePrimary,themeDark,neutralSecondary. These come from the site’s color scheme. - Semantic colors — things like
bodyBackground,bodyText,buttonText. These are higher-level abstractions that map to palette colors based on context.
When possible, use semantic colors. They’re more stable and meaningful — bodyText always means “the color text should be on the page body,” regardless of the underlying palette.
Method 1: Using SPFx Theme Tokens in SCSS
This is the easiest approach, and it requires zero TypeScript. You just use a special syntax directly in your SCSS file, and SPFx does the rest.
How it works:
Instead of writing a fixed color:
.button {
background-color: #0078d7;
}
You write a theme token reference:
.button {
background-color: "[theme: themePrimary, default: #0078d7]";
}
The @microsoft/load-themed-styles package — which is bundled with SPFx — scans your CSS at load time, finds these token strings, and replaces them with the actual color from the current site theme. The default value is your safety net for environments where the token isn’t available.
A real example — updating a scaffolded web part:
Open your .module.scss file and update your selectors:
.row {
padding: 20px;
background-color: "[theme: themeDark, default: #005a9e]";
}
.button {
background-color: "[theme: themePrimary, default: #0078d7]";
border-color: "[theme: themePrimary, default: #0078d7]";
color: "[theme: white, default: #ffffff]";
border-style: solid;
border-width: 1px;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
border-radius: 2px;
}
.title {
color: "[theme: neutralPrimary, default: #333333]";
font-size: 24px;
font-weight: 600;
margin: 0 0 8px 0;
}

When to use this:
Use it when you only need colors in CSS and don’t want to mess around with TypeScript at all. It’s perfect for quick wins and straightforward styling.
In the .tsx file below, I just took sample text and a button control and applied the styles we defined at the top.
import * as React from 'react';
import styles from './BrandTheme.module.scss';
import type { IBrandThemeProps } from './IBrandThemeProps';
export default class BrandTheme extends React.Component<IBrandThemeProps> {
public render(): React.ReactElement<IBrandThemeProps> {
return (
<section>
<div className={styles.row}>
<h2 className={styles.title}>Get the Current Theme in SPFx</h2>
<p>
SPFx automatically resolves theme tokens in <code>.module.scss</code> files using the
SharePoint theme system. The background, text, and button colors on this web part all
adapt to the current site theme.
</p>
<button className={styles.button}>Themed Button</button>
</div>
</section>
);
}
}
Now, look at the output image: the button on the div element dynamically adopts the SharePoint site theme.

The catch:
This doesn’t automatically react to section background changes. If someone switches a section from neutral to dark-colored, your web part won’t know about it. For that, you need one of the next two methods.
Check out SPFx Drag and Drop File Upload: Single & Multiple Files
Method 2: Detecting Theme Changes with onThemeChanged
BaseClientSideWebPart has a built-in lifecycle method called onThemeChanged. Every time the theme changes — including when section backgrounds are toggled — SharePoint calls this method and hands you the current theme object.
This is cleaner than polling or reading global variables, and it’s the Microsoft-recommended way for most web parts.
- Import the interface: At the top of your web part
.tsfile, add:
import { IReadonlyTheme } from "@microsoft/sp-component-base";
- Override the method in your web part class:
protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
if (!currentTheme) {
return;
}
const { semanticColors } = currentTheme;
if (semanticColors) {
this.domElement.style.setProperty(
"--bodyText",
semanticColors.bodyText || null
);
this.domElement.style.setProperty(
"--bodyBackground",
semanticColors.bodyBackground || null
);
this.domElement.style.setProperty(
"--buttonBackground",
semanticColors.buttonBackground || null
);
}
}
