question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Font family theme styles not working with Next.js + MUI

See original GitHub issue

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

I’ve been trying to track down why theme font overrides don’t appear to be working for me – I’m not even sure if this is Next or MUI that’s causing the problem, but the behaviour is as described below. I’ve found a couple issues that cover similar issues, but all the solutions suggest using overrides in the theme declaration, a property that appears to no longer exist in V5.

Problem:

All my <Typography /> blocks, irrespective of variant, are still defaulting to using Robot, Helvetica, Arial, sans-serif fonts. The overrides I’ve declared are in the CSS hierarchy, but get overridden by variant-specific styles. Take for example, a body1 typography block that renders:

<p class="MuiTypography-root MuiTypography-body1 css-1nmo5nr-MuiTypography-root">My text</p>

The styles that apply, in reverse hierarchical order are:

.MuiTypography-body1 {
    font-size: 1rem;
    font-family: "Roboto", "Helvetica", "Arial", sans-serif;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: 0.00938em;
}

MuiTypography-root {
    margin: 0;
}

.css-1nmo5nr-MuiTypography-root {
    margin: 0;
    font-weight: 400;
    font-family: Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif;    /* <-- Here's the font I'm trying to apply */
    font-size: 1rem;
    line-height: 1.5;
    font-weight: 700!important;
}

So you can see that the MuiTypography-body1 style is taking precedence here.

Theme

I’m correctly wrapping my app in a ThemeProvider block like so (I know it’s working because all other theme properties work, and Lato does work for Buttons and other elements, as well as colors and overrides):

...
import { ThemeProvider } from "@mui/material/styles";
import myTheme from "../theme/appTheme";
import CssBaseline from "@mui/material/CssBaseline";

function MyApp({ Component, emotionCache = clientSideEmotionCache, pageProps }) {
  return (
      <React.StrictMode>
        <UserProvider>
          <CacheProvider value={emotionCache}>
            <ThemeProvider theme={myTheme}>
              <CssBaseline />
              <Component {...pageProps} />
            </ThemeProvider>
          </CacheProvider>
        </UserProvider>
      </React.StrictMode>
    );
}

And my theme looks like this (some stuff removed for brevity, but all to do with custom button variants).

import {
  createTheme,
  responsiveFontSizes,
  Theme,
  alpha,
  darken,
  lighten } from "@mui/material/styles";
import { red, grey } from '@mui/material/colors';

declare module "@mui/material/styles" {
  interface Palette {
    base: any;

  }
  interface PaletteOptions {
    base: any;
  }
}

declare module "@mui/material/Button" {
  interface ButtonPropsVariantOverrides {
    principal: true;
  }
}

const PRIMARY_MAIN = "#666";
const PRIMARY_LIGHT = #aaa;
const PRIMARY_DARK = "#111";
const WHITE = "#FFFFFF";
const FONT_FAMILY = [
      "Lato",
      "-apple-system",
      "BlinkMacSystemFont",
      '"Segoe UI"',
      "Arial",
      "sans-serif",
    ].join(",")

// Create a theme instance.
let myTheme: Theme = createTheme({
  palette: {
    primary: {
      main: PRIMARY_MAIN,
      light: PRIMARY_LIGHT,
      dark: PRIMARY_DARK,
      contrastText: "#fff",
    },
    secondary: {
      main: grey["900"],
    },
    base: {
      main: grey["100"],
      dark: grey["300"],
    },
    error: {
      main: red["A400"],
    },
  },
  typography: {
    fontFamily: FONT_FAMILY,  // <-- According to docs, this should be working?
    fontWeightRegular: 500,
    h1: {
      fontWeight: 700,
      fontSize: "4rem",
      "@media (max-width:375px)": {
        fontSize: "2.5rem",
      },
    },
    h2: {
      fontWeight: 700,
      fontSize: "3.2rem",
    },
    h3: {
      fontWeight: 700,
    },
    h4: {
      "@media (max-width:375px)": {
        fontSize: "1.2rem",
      },
    },
    body1: {
      fontWeight: 400,
    },
  },
  components: {
    MuiCssBaseline: {
      styleOverrides: {
        html: {
          overflowX: "hidden",
        },
        body: {
          overflowX: "hidden",
        },
        // ^ Also tried @font-face, @global: { @font-face } here
      },
    },
    MuiButton: {
      styleOverrides: {
        root: {
          fontWeight: 700,
          lineHeight: 2,
          letterSpacing: 0.3,
          textTransform: "none",
          fontSize: "1rem",
          borderRadius: 5,
          whiteSpace: "nowrap",
          padding: "0.2rem 1.2rem 0.3rem",
        },
        text: {
          "&:active": {
            backgroundColor: PRIMARY_LIGHT,
          },
        },
      },
    },
  },
});

export default responsiveFontSizes(myTheme);

#10552 was the closest I could find to the issue, but the solution proposed is:

const theme = createMuiTheme({
  typography: {
    fontFamily: "Product Sans",
  },
  overrides: {
    MuiTypography: {
      body1: {
        color: purple[500],
      },
      subheading: {
        color: purple[500],
      },
    }
  }
});

…which I’ve already tried, and also overrides is not valid according to ESLint (TypeScript) so I suspect that’s V4 syntax?

The only lead I have is that I’m using Next’s font loading by adding a <style> tag to the document instead of loading using @font-face inside the MUI theme – this seems to be the Next-recommended way of loading CDN fonts. I don’t think the order the font is loading is the problem though, because it does work for Buttons and anything that isn’t in a <Typography> block.

...
<Head>
  <title key="title">{title}</title>
  <meta name="description" content={description} key="description" />
  <link
          href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,400;1,700;1,900&family=Oxygen+Mono&display=swap"
          rel="stylesheet"
  />
  <link rel="icon" href={favicon} />
</Head>
...

Also worth noting that in order for any styles applied in the overriding style block (.MuiTypography-body1), I have to use !important, even when using sx. For example:

<Typography
  fontWeight='700 !important'
  sx={{
    fontSize: '1.1rem !important',
  }}
>Some text</Typography>

Expected behavior 🤔

Typography should correctly handle the global style and inherit from the font family declared in the typography object of custom themes.

Steps to reproduce 🕹

(See details from problem statement – simply create a custom theme with the details above and wrap a Next.js app in <ThemeProvider>.

Context 🔦

Currently I have to use !important to override the font styles, which means I need to use !important underneath for any local overrides.

Your environment 🌎

`npx @mui/envinfo`
  System:
    OS: macOS 12.1, M1 Max
  Binaries:
    Node: 17.3.1 - /opt/homebrew/bin/node
    Yarn: 1.22.17 - /opt/homebrew/bin/yarn
    npm: 8.4.1 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 98.0.4758.80 (Official Build) (arm64)
  npmPackages:
    @emotion/react: ^11.7.1 => 11.7.1 
    @emotion/styled: ^11.6.0 => 11.6.0 
    @mui/base:  5.0.0-alpha.64 
    @mui/icons-material: ^5.2.5 => 5.2.5 
    @mui/material: ^5.2.7 => 5.2.8 
    @mui/private-theming:  5.2.3 
    @mui/styled-engine:  5.2.6 
    @mui/system:  5.2.8 
    @mui/types:  7.1.0 
    @mui/utils:  5.2.3 
    @types/react: ^17.0.38 => 17.0.38 
    react: ^17.0.2 => 17.0.2 
    react-dom: ^17.0.2 => 17.0.2 
    typescript: ^4.5.4 => 4.5.4 

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
aderchoxcommented, Feb 27, 2022

I’m having the same issue and I’m using v5. I have created a sandbox to reproduce this in a minimal example: codesandbox. Or maybe I have made a mistake, what I’ve done there is based on this page of the documentation. Will you please have a look @mnajdova ?

UPDATE: No problem anymore, it works now. Here are the important mistakes I’d made: 1. I hadn’t used CssBaseline. I thought it was optional like using CSS reset! 2. I missed a comma between local('Nunito') and url(${Nunito}) format('woff) in src part.

0reactions
brandonscriptcommented, Jun 14, 2022

Proved that because it relies on v4 styles, when you install both v5 and v4, the v4 styles clobber the v5 styles.

This should not be a problem: see https://mui.com/x/react-data-grid/migration-v4/#using-mui-core-v4-with-v5

I can’t believe I missed this reply, thank you so much!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Loading fonts to customize Material-UI theme in Next.js not ...
Create a theme.js file for material ui and add your font to Typography : import { createMuiTheme } from '@material-ui/core/styles'; const ...
Read more >
Basic Features: Font Optimization - Next.js
CSS and font files are downloaded at build time and self-hosted with the rest of your static assets. No requests are sent to...
Read more >
Self-hosted fonts with Next.js and Material UI
1. Get a fresh next.js project up and running · 2. Install Material UI · 3. Locate your font-files · 4. Use your...
Read more >
Typography - Material UI - MUI
The theme provides a set of type sizes that work well together, and also with the layout grid. Font family. You can change...
Read more >
3 ways to add custom fonts to your MUI project - LogRocket Blog
Then, we'll add some UI components to work within our App.js folder: ... const theme = createMuiTheme({ typography: { fontFamily: ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found