How can I use Local fonts in theme UI in next JS?

2.5k views Asked by At

I am building an app with the next JS using [theme-UI][1]. But in my project, I have to use local fonts or custom fonts. But I have no idea how can I do that. Here is my theming

    const theme = { 
     fonts: {
        body: 'CircularBlack',
        heading: 'CircularBlack',
        monospace: 'Menlo, monospace',
      },

Here is theming-

export default {
    fonts: {
        body: "fufu", //text
        heading: "fufu", //boxShape
        monospace: "fufu", //header
    }
    styles: {
        root: {
            p: 0,
            m: 0,
            background: 'primary',
            cursor: 'default',
            position: 'relative',
            overflowX: "hidden",
            fontFamily: "body",
        }
    },
}

Here I use fonts name in fonts object and I call it into root element. [1]: https://theme-ui.com/

3

There are 3 answers

0
jebbie On

Get the .woff and .woff2 files for the fonts you want to integrate from the web (e.g. https://www.cufonfonts.com/font/menlo)

Put these files into a folder like my-next-app/public/fonts/menlo.woff2 - anything in the public folder inside a next js app will be statically served - just make sure to copy these files too onto your webserver if your hosting it manually.

Afterwards you need to integrate the fonts in a way - with basic CSS like:

  @font-face {
    font-family: Menlo;
    font-weight: 300;
    font-style: normal;
    font-display: swap;
    src: url("/fonts/Menlo-Monospace.woff2")
      format("woff2"),
      url("/fonts/Menlo-Monospace.woff")
      format("woff");;
  }

I don't know theme-ui so i cannot say where these @font-face definitions should be integrated.. We do it in a global-styles.css which we just integrate with a custom pages/_app.tsx file (https://nextjs.org/docs/advanced-features/custom-app)

Now you should be fine to use the font anywhere in your application, also in your theme-ui as you already have written.

0
MBCoder On

You should be able it to your Global css like this:

import React from "react";
import { Global, css } from "@emotion/core";
import { ThemeProvider } from "theme-ui";
import theme from "../components/theme";

const App = ({ Component, pageProps }) => {
  return (
    <ThemeProvider theme={theme}>
      <Global
        styles={css`
          "*": {
            boxsizing: "border-box";
          }
          html,
          body {
            width: 100%;
            height: 100%;
          }
          figure {
            margin: 0;
          }
          @font-face {
            font-family: "Circular";
            src: url("/fonts/circular/circular-light.woff2") format("woff2");
            font-style: normal;
            font-weight: 300;
            font-display: swap;
          }
          @font-face {
            font-family: "Circular";
            src: url("/fonts/circular/circular-bold.woff2") format("woff2");
            font-style: normal;
            font-weight: 700;
            font-display: swap;
          }
          @font-face {
            font-family: "Circular Mono";
            src: url("/fonts/circular/circular-mono.woff2") format("woff2");
            font-style: normal;
            font-weight: 400;
            font-display: swap;
          }
          @font-face {
            font-family: "Cambon";
            src: url("/fonts/cambon/cambon-bold.woff2") format("woff2");
            font-style: normal;
            font-weight: 700;
            font-display: swap;
          }
        `}
      />
      <Component {...pageProps} />
    </ThemeProvider>
  );
};

export default App;
0
Faizan  Arif On

firstly, Get the .woff and .woff2 files for the fonts you want to integrate from the web .

Put these files into a folder like

next-app/public/fonts/menlo.woff2

Note: "its must be in public folder"

  • anything in the public folder inside a next js app will be statically served - just make sure to copy these files too onto your web-server if your hosting it manually.

Afterwards you need to install "@emotion/react" npm package then integrate the fonts in a way - with basic CSS like:

_app.js:

/** @jsxImportSource theme-ui */
import { Global, css } from "@emotion/react";
import { ThemeProvider } from 'theme-ui';
import theme from 'theme';

function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider theme={theme} >
      <Global
        styles={css`
        @font-face {
          font-family: "SF Pro";
          src: url('fonts/SFPRODISPLAYMEDIUM.woff') format("woff");
          font-style: normal;
          font-weight: 300;
        }
      @font-face {
        font-family: "SF Pro";
        src: url('fonts/SFPRODISPLAYREGULAR.woff') format('woff');
        font-style: normal;
        font-weight: 400;
      }
      @font-face {
        font-family: "SF Pro";
        src: url('fonts/SFPRODISPLAYBOLD.woff') format("woff");
        font-style: normal;
        font-weight: 600;
      }
    `}
      />
      <Component {...pageProps} />
    </ThemeProvider>
  )
}

export default MyApp

in theming part insert these,

export default {
    fonts: {
        body: "SF Pro",
        heading: "SF Pro",
        monospace: "SF Pro"
    },
    fontWeights: {
        body: 400,
        heading: 600,
        primary: 300
    },
    styles: {
        root: {
            p: 0,
            m: 0,
            bg: 'light',
            cursor: 'default',
            position: 'relative',
            overflowX: "hidden",
            fontFamily: 'body',
            minHeight: "100%",
            overflowX: "hidden"
        }
    },

}