In modern web development, creating brand-specific themes is a common requirement, especially for multi-brand applications. Themes help maintain consistency and brand identity across components and pages. With Styled-Components, a popular library for styling in React, implementing themes becomes both elegant and manageable.
In this article, we’ll explore how to create and apply themes for different brands using Styled-Components in ReactJS with TypeScript for robust typing and scalability.
What Are Styled-Components?
Styled-Components is a library that allows you to write CSS-in-JS, enabling developers to style React components with tagged template literals. By leveraging this approach, styles are scoped to components and can dynamically adapt based on props or themes.
Why Use Themes?
Themes in Styled-Components allow you to define a set of reusable style values, such as colors, typography, and spacing. This is particularly useful for:
Multi-Brand Applications: Switching between different brands with distinct visual identities.
Dark and Light Modes: Implementing mode-specific styles.
Scalability: Centralized management of design tokens for consistent styling.
Setting Up Themes with Styled-Components and TypeScript
1. Installing Dependencies
First, install Styled-Components in your React project:
npm install styled-componentsFor TypeScript projects, install the typings as well:
npm install --save-dev @types/styled-components2. Define Theme Interfaces
Define a theme.d.ts file to provide TypeScript with information about your theme structure:
// theme.d.ts
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
colors: {
primary: string;
secondary: string;
background: string;
text: string;
};
fonts: {
body: string;
heading: string;
};
}
}3. Create Theme Objects
Move your themes into a utils/themes.ts file, ensuring they conform to the DefaultTheme interface:
import { DefaultTheme } from 'styled-components';
export const lightTheme: DefaultTheme = {
colors: {
primary: '#3498db',
secondary: '#2ecc71',
background: '#ffffff',
text: '#333333',
},
fonts: {
body: 'Arial, sans-serif',
heading: 'Georgia, serif',
},
};
export const darkTheme: DefaultTheme = {
colors: {
primary: '#9b59b6',
secondary: '#e74c3c',
background: '#2c3e50',
text: '#ecf0f1',
},
fonts: {
body: 'Arial, sans-serif',
heading: 'Georgia, serif',
},
};
export const brandATheme: DefaultTheme = {
colors: {
primary: '#ff5733',
secondary: '#ffc300',
background: '#f1f1f1',
text: '#333333',
},
fonts: {
body: 'Roboto, sans-serif',
heading: 'Poppins, sans-serif',
},
};
export const brandBTheme: DefaultTheme = {
colors: {
primary: '#1abc9c',
secondary: '#16a085',
background: '#ecf0f1',
text: '#2c3e50',
},
fonts: {
body: 'Lato, sans-serif',
heading: 'Montserrat, sans-serif',
},
};
export const brandCTheme: DefaultTheme = {
colors: {
primary: '#e67e22',
secondary: '#d35400',
background: '#fdfdfd',
text: '#7f8c8d',
},
fonts: {
body: 'Open Sans, sans-serif',
heading: 'Raleway, sans-serif',
},
};4. Create a Theme Switcher Utility
Move reusable logic for switching themes into utils/themeSwitcher.ts:
import { lightTheme, darkTheme, brandATheme, brandBTheme, brandCTheme } from './themes';
import { DefaultTheme } from 'styled-components';
export const getThemeByName = (themeName: string): DefaultTheme => {
const themes: Record<string, DefaultTheme> = {
light: lightTheme,
dark: darkTheme,
brandA: brandATheme,
brandB: brandBTheme,
brandC: brandCTheme,
};
return themes[themeName] || lightTheme;
};5. Wrap Your Application with ThemeProvider
Update your App.tsx to use TypeScript and the new utility functions:
import React, { useState } from 'react';
import { ThemeProvider } from 'styled-components';
import { getThemeByName } from './utils/themeSwitcher';
import GlobalStyles from './GlobalStyles';
import Home from './Home';
const App: React.FC = () => {
const [themeName, setThemeName] = useState<string>('light');
const changeTheme = (name: string) => {
setThemeName(name);
};
return (
<ThemeProvider theme={getThemeByName(themeName)}>
<GlobalStyles />
<button onClick={() => changeTheme('light')}>Light Theme</button>
<button onClick={() => changeTheme('dark')}>Dark Theme</button>
<button onClick={() => changeTheme('brandA')}>Brand A Theme</button>
<button onClick={() => changeTheme('brandB')}>Brand B Theme</button>
<button onClick={() => changeTheme('brandC')}>Brand C Theme</button>
<Home />
</ThemeProvider>
);
};
export default App;6. Create Global Styles
Ensure your global styles use the DefaultTheme interface:
import { createGlobalStyle } from 'styled-components';
const GlobalStyles = createGlobalStyle`
body {
margin: 0;
padding: 0;
background-color: ${({ theme }) => theme.colors.background};
color: ${({ theme }) => theme.colors.text};
font-family: ${({ theme }) => theme.fonts.body};
}
h1, h2, h3, h4, h5, h6 {
font-family: ${({ theme }) => theme.fonts.heading};
}
`;
export default GlobalStyles;7. Style Components with Theme Values
Access theme values directly in your styled components:
import React from 'react';
import styled from 'styled-components';
const Container = styled.div`
padding: 20px;
`;
const Button = styled.button`
background-color: ${({ theme }) => theme.colors.primary};
color: ${({ theme }) => theme.colors.text};
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: ${({ theme }) => theme.colors.secondary};
}
`;
const Home: React.FC = () => {
return (
<Container>
<h1>Welcome to the Themed App</h1>
<Button>Click Me</Button>
</Container>
);
};
export default Home;Conclusion
Theming with Styled-Components and TypeScript ensures type safety and scalability in your application. By centralizing theme logic and using utilities for reusable functionality, you can maintain a clean and efficient codebase. Try it out and make your React applications adaptable to multiple brands effortlessly!

