Recently, I needed to install a custom font in a site using Remix Run front end framework. The documentation that Chakra has regarding fonts did not work for me. So if it doesn't work for you, here's how to do that.
This guide should also work if you are not using Chakra UI and only want to use css styling.
In this example I am using a self hosted font and using the Chakra theme to style the <Text>
and <Heading>
tags. But you can also add a class in the css file to fontstyle any text.
Go to Google Web Fonts Helper and choose the font you need. Raleway is the font used as the example in this guide.
Download the font files. If you choose modern browsers, you will get .woff and .woff2 files.
Place these files inside a new "raleway" folder: app/public/fonts/raleway
Create a .css file. For instance: index.css located in app/styles directory. Inside this css file, place the
@font-face
code from the fonts helper.
Optional: you can also specify a new css class so that you can style any text with this font.
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
src: local(''),
url('/fonts/raleway/raleway-v26-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/fonts/raleway/raleway-v26-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
.raleway {
font-family: "Raleway";
}
}
Chakra UI uses themes. Make a new theme.tsx file, in your /app directory for example.
import { extendTheme, theme as defaultTheme } from "@chakra-ui/react";
const theme = extendTheme({
...defaultTheme,
colors:{
...defaultTheme.colors,
},
fonts:{
heading: "'Raleway', sans-serif;",
body: "'Raleway', sans-serif;",
},
})
export default theme
In the entry point of the application, root.tsx file (where the ChakraProvider tag is), add the theme to the tag.
export default function App() {
return (
<Document>
<ChakraProvider theme={theme}>
<CSSReset/>
<Outlet />
</ChakraProvider>
</Document>
);
}
Import the css file into the file for the webpage you want to style. Use the links() function.
import styles from "~/styles/index.css";
import {
Links,LiveReload,Meta,Outlet,Scripts,ScrollRestoration,useCatch,
useLoaderData
} from "remix";
import { Heading, Text } from '@chakra-ui/react'
export const links = () => {
return [{ rel: "stylesheet", href: styles }];
};
If you use the Chakra UI <Heading>
or <Text>
tag (corresponding to the heading: and body: in the theme.tsx) the font should be the custom font family displaying on the webpage.
// app/routes/index.tsx
export default function Index() {
return (
<>
<div>
<h1 className="raleway">ABCDEFG Test of Font using
className
</h1>
<Heading>ABCDEFG Test of Font from Heading</Heading>
<Text>ABCDEFG Test of font from text</Text>
</div>
</>
If you created a css class, you can also see your custom font by using the className, e.g. <p className='raleway'>Test</p>
For reference I have put the full app/root.tsx and app/routes/index.tsx below.
root.tsx
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useCatch,
useLoaderData
} from "remix";
import type { MetaFunction } from "remix";
import { Box, ChakraProvider, CSSReset, Heading } from '@chakra-ui/react'
import theme from "~/theme";
export const meta: MetaFunction = () => {
return { title: "New Remix App" };
};
export default function App() {
return (
<Document>
<ChakraProvider theme={theme}>
<CSSReset/>
<Outlet />
</ChakraProvider>
</Document>
);
}
function Document({
children,
title = "App title"
}: {
children: React.ReactNode;
title?: string;
}) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<title>{title}</title>
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === "development" && <LiveReload />}
</body>
</html>
);
}
export function ErrorBoundary({ error }: { error: Error }) {
return (
<div>
<Document title='Error!'>
<ChakraProvider >
<Box>
<Heading as='h1'>There was an error</Heading>
</Box>
</ChakraProvider>
</Document>
</div>
)
}
export function CatchBoundary() {
let caught = useCatch()
return (
<Document title={`${caught.status} ${caught.statusText}`}>
<ChakraProvider>
<Box>
<Heading as='h1'>
{caught.status} {caught.statusText}
</Heading>
</Box>
</ChakraProvider>
</Document>
)
}
index.tsx
import styles from "~/styles/index.css";
import {Links,LiveReload,Meta,Outlet,Scripts,ScrollRestoration,useCatch,useLoaderData} from "remix";
import { Box, Center, ChakraProvider, Circle, CSSReset, Heading, Text, ThemeProvider } from '@chakra-ui/react'
export const links = () => {
return [{ rel: "stylesheet", href: styles }];
};
export default function Index() {
return (
<>
<div>
<h1 className="raleway">ABCDEFG Test of Font using className</h1>
<Heading>ABCDEFG Test of Font from Heading</Heading>
<Text>ABCDEFG Test of Font from Text</Text>
</div>
</>
);
}
Top comments (4)
Nice one! This helped me get this working with Remix and Tailwind.
Got stuck with tailwind & remix
I'm recently trying to user JoyUI with RemixV2. But, there is no documentation available to integrate JoyUi with remix. I have tried to install JoyUi and use the components. But, as a new I couldn't do it.
Did you ever tried JoyUi with Remix?
Thank you for writing this piece. It was exactly what I needed to get my custom font into Chakra.