How to Get the Current Theme in SPFx (3 Methods That Actually Work)

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 themePrimarythemeDarkneutralSecondary. These come from the site’s color scheme.
  • Semantic colors — things like bodyBackgroundbodyTextbuttonText. 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;
}
get current theme colors in spfx

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.

spfx get the current 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.

  1. Import the interface: At the top of your web part .ts file, add:
import { IReadonlyTheme } from "@microsoft/sp-component-base";
  1. 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
);
}
}
spfx onthemechanged override flutter

What’s happening here: you’re reading the semantic color values from the theme and pushing them as CSS custom properties onto your web part’s root DOM element.

  1. Use those CSS variables in your SCSS:
.myWebPart {
color: var(--bodyText);
background-color: var(--bodyBackground);
}

.myButton {
background-color: var(--buttonBackground);
}

This is a really clean pattern because your TypeScript handles the data side and your SCSS handles the display side; they’re cleanly separated.

Detecting Theme Changes with onThemeChanged in SPFx

Commonly used semanticColors properties you can pull:

  • bodyText — main text color
  • bodyBackground — page background
  • buttonText — text on default buttons
  • buttonBackground — button background
  • primaryButtonText — text on primary/CTA buttons
  • link — hyperlink color
  • errorText — error message text
  • inputText — text inside form inputs
  • disabledText — grayed-out element text
  • focusBorder — focus ring color

Check out Fluent UI in SharePoint Framework (SPFx)

Method 3: Accessing Theme Data with ThemeProvider

This is the most powerful approach. Instead of waiting for onThemeChanged to fire, you proactively consume the ThemeProvider service in onInit, get the current theme right away, and also register for future changes.

Use this when you need to pass theme data into React components as props, or when you need to do something more complex than just setting CSS variables.

  1. Import what you need:
import {
ThemeProvider,
ThemeChangedEventArgs,
IReadonlyTheme,
} from "@microsoft/sp-component-base";
  1. Declare private variables in your web part class:
private _themeProvider: ThemeProvider;
private _themeVariant: IReadonlyTheme | undefined;
  1. Initialize in onInit:
protected onInit(): Promise<void> {
// Consume the ThemeProvider service
this._themeProvider = this.context.serviceScope.consume(
ThemeProvider.serviceKey
);

// Get the current theme right now
this._themeVariant = this._themeProvider.tryGetTheme();

// Listen for future changes
this._themeProvider.themeChangedEvent.add(
this,
this._handleThemeChangedEvent
);

return super.onInit();
}
  1. Handle theme change events:
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
this._themeVariant = args.theme;
this.render();
}
  1. Pass the theme to your React component:
public render(): void {
const element: React.ReactElement<IMyComponentProps> = React.createElement(
MyComponent,
{
themeVariant: this._themeVariant,
}
);

ReactDom.render(element, this.domElement);
}
  1. Use the theme inside your React component:
import { IReadonlyTheme } from "@microsoft/sp-component-base";

export interface IMyComponentProps {
themeVariant: IReadonlyTheme | undefined;
}

export const MyComponent: React.FC<IMyComponentProps> = ({ themeVariant }) => {
const semanticColors = themeVariant?.semanticColors;

return (
<div
style={{
backgroundColor: semanticColors?.bodyBackground,
color: semanticColors?.bodyText,
padding: "20px",
}}
>
<h2 style={{ color: semanticColors?.link }}>Hello, theme-aware world!</h2>
<button
style={{
backgroundColor: semanticColors?.buttonBackground,
color: semanticColors?.buttonText,
border: `1px solid ${semanticColors?.buttonBorder}`,
}}
>
Click Me
</button>
</div>
);
};
Accessing the theme data with ThemeProvider in SPFx

When to use this method:
Go with ThemeProvider when your web part is React-based and you want to wire the theme into component props cleanly. It gives you full access to both semanticColors and palette in one place, and you can drill it down the component tree however you like.

Check out Call an Azure Function from an SPFx Web Part

Reading Theme Information from the Window Object

You’ll sometimes see this pattern in older tutorials and StackOverflow answers:

const themeColorsFromWindow: any = (window as any).__themeState__.theme;

This reads the raw theme palette directly from the global window state that SharePoint injects on every page. It works, and you can get any token value from it. But I’d treat this as a last resort — it’s not a documented API, so Microsoft can change the structure without warning. Stick to onThemeChanged or ThemeProvider for anything production-facing.

Comparing Theme Retrieval Methods in SPFx

MethodBest ForReacts to Section ChangesTypeScript Needed
SCSS Theme TokensCSS-only color stylingNoNo
onThemeChangedSimple color injection via CSS varsYesMinimal
ThemeProviderReact components with prop-based themingYesYes

Commonly Used SPFx Theme Tokens

Here are some commonly used theme tokens you can use in SCSS:

  • themePrimary — main brand color
  • themeDark — darker variant of primary
  • themeDarkAlt — slightly lighter dark variant
  • themeDarker — deepest dark variant
  • themeLight — light variant
  • themeLighter — lighter variant
  • neutralPrimary — main body text
  • neutralSecondary — secondary text and icons
  • neutralLight — borders and dividers
  • white — pure white backgrounds
  • black — pure black text

Always include a default fallback value when using SCSS tokens. That fallback kicks in when the theme value isn’t available — for example, on a classic SharePoint page or in a local workbench.

Common Mistakes When Working with SPFx Themes

A lot of developers use getTheme() from @fluentui/react (or the older office-ui-fabric-react) thinking it’ll return the SharePoint site theme. It doesn’t — it returns Fluent UI’s own internal theme, which defaults to Microsoft’s blue palette regardless of what’s applied to the SharePoint site. Don’t rely on it for SharePoint-specific theming.

Complete Example: Bringing Everything Together

If I’m starting a fresh web part today and want theme support:

  1. For CSS-only styling — I use SCSS theme tokens. Fast, zero overhead.
  2. For a simpler web part with some dynamic styling — I override onThemeChanged and set CSS custom properties.
  3. For a React-based web part where I want theme values in components, I go with ThemeProvider in onInit and pass themeVariant as a prop.

The important thing is to always handle the case where the theme is undefined — It can happen in classic pages, the local workbench, and certain Teams contexts. A simple if (!currentTheme) return; guard goes a long way.

Conclusion

I hope you found this article helpful. In this article, I explained 3 different methods to get the current theme in SharePoint Framework (SPFx). I also explained when to use each method and what makes them different.

When you build a SharePoint Framework web part, it is always a good idea to use the current theme instead of hardcoded colors. This helps your web part match the site theme and gives users a more consistent experience.

If you only need colors in your styles, theme tokens are usually the easiest option. If you need to react when the theme changes, use the onThemeChanged method. And if you need full control over theme information, ThemeProvider is the best choice.

Choose the method that fits your requirement, and your SPFx solutions will look more professional and work better with modern SharePoint themes.

Also, you may like:

Power Apps functions free pdf

30 Power Apps Functions

This free guide walks you through the 30 most-used Power Apps functions with real business examples, exact syntax, and results you can see.

Live Webinar

SharePoint Integration Power Apps Form With Repeating Table [Invoice Management System]

Learn how to build an invoice management system using SharePoint integration and a repeating table.

📅 2nd September 2026 – 10:00 AM EST | 7:30 PM IST

Download User registration canvas app

DOWNLOAD USER REGISTRATION POWER APPS CANVAS APP

Download a fully functional Power Apps Canvas App (with Power Automate): User Registration App