I'm building a React app using material-ui styled-components with TypeScript.
I'm trying to use a custom font with my styled components, but I'm struggling to get it to work.
First thing I did was I created a globalStyles.ts
file createGlobalStyle
:
import { createGlobalStyle } from "styled-components";
export const theme = {
primaryBlue: "#0794B4",
secondaryBlue: "#043157",
primaryWhite: "#fff"
};
const GlobalStyle = createGlobalStyle`
@font-face {
font-family: pala;
src: url("./assets/pala.ttf") format('truetype');
font-weight: normal;
font-style: normal;
}
html {
font-size: 10px;
}
`;
export default GlobalStyle;
I added the ThemeProvider
and the GlobalStyle
to my app:
import React, { Component } from "react";
import "./App.css";
import NavBar from "./components/NavBar";
import { ThemeProvider } from "styled-components";
import GlobalStyle, { theme } from "./globalStyles";
class App extends Component {
render() {
return (
<ThemeProvider theme={theme}>
<div className="App-header">
<NavBar title="MyCompany" />
<GlobalStyle />
</div>
</ThemeProvider>
);
}
}
export default App;
And then I tried to use this font from within my styled component:
import React, { PureComponent } from "react";
import styled from "styled-components";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
export const StyledAppBar = styled(AppBar)``;
export const StyledToolbar = styled(Toolbar)``;
export const StyledTypography = styled(Typography)`
&& {
font-family: pala;
font-size: 10rem;
color: ${props => props.theme.primaryWhite};
}
`;
export interface Props {
title: string;
}
export class NavBar extends PureComponent<Props> {
render() {
return (
<StyledAppBar>
<StyledToolbar>
<StyledTypography>{this.props.title}</StyledTypography>
</StyledToolbar>
</StyledAppBar>
);
}
}
export default NavBar;
The styles for the color and the font size are correctly applied, but the custom font is not. Do I somehow have to add the custom font to the ThemeProvider
and use it via props.theme.font
? Or am I doing something wrong?
To declare a custom font with styled-components createGlobalStyle:
@font-face
declaration using tagged template literals.Here's your globalStyles.ts
:
// globalStyles.ts
import { createGlobalStyle } from "styled-components";
// 1. import the font
import pala from "./assets/pala.ttf";
export const theme = {
primaryBlue: "#0794B4",
secondaryBlue: "#043157",
primaryWhite: "#fff"
};
// 2. interpolate it using tagged template literals
const GlobalStyle = createGlobalStyle`
@font-face {
font-family: pala;
src: url(${pala}) format('truetype');
font-weight: normal;
font-style: normal;
}
html {
font-size: 10px;
}
`;
export default GlobalStyle;
If you want to learn more about tagged template literals in styled-components, Max Stoiber (who created styled-components) wrote a really nice article about it.