Skip to content

Instantly share code, notes, and snippets.

@knowler
Last active February 21, 2024 17:03
Show Gist options
  • Save knowler/d74f1cdfa0d80a63910b554998eec112 to your computer and use it in GitHub Desktop.
Save knowler/d74f1cdfa0d80a63910b554998eec112 to your computer and use it in GitHub Desktop.
Fontsource with Remix (pre-1.7.3)

Fontsource with Remix

Fontsource is designed to work with projects that bundle their CSS. You import their stylesheet and the bundler will place the fonts in your build directory and the CSS file will have the correct URL for the @font-face src.

Remix doesn’t bundle CSS and so while you can import their CSS file and add it to your links, the URL to font will be incorrect. It is still possible to use Fontsource with Remix. We just need to create our own @font-face declaration with the correct URL to the font (ideally, one that benefits from Remix’s asset fingerprinting). There’s a bit of manual set up, but once that’s done, you can serve the font on your site and benefit from updates for the font.

  1. Install your font:
    npm install --save @fontsource/montserrat
  2. Create a directory for fonts in your the app directory so that you can fingerprint the font assets for long term caching. Run the following from your project root.
    mkdir app/fonts
  3. Link the files directory of the font to the your app/fonts directory. Run the following from your project root.
    ln -s node_modules/@fontsource/montserrat/files app/fonts/montserrat
  4. In the layout that you need the font, import the font file you want. It’s a sym-link so autocomplete won’t work unfortunately.
    import montserratVariableFontLatin from '~/fonts/montserrat/montserrat-latin-variable-wghtOnly-normal.woff2`;
  5. Define the @font-face using the font asset URL that we imported. We have to use a <style> element to include this as we cannot set the URL as a custom property since they cannot be accessed in @font-face declarations. Take a look at the corresponding CSS file in the @fontsource Node module to know what to set here (especially for the unicode-range and font-weight).
    const montserratFontFaceDeclaration = `
      @font-face {
        font-family: 'Montserrat', sans-serif;
        font-style: normal;
        font-display: swap;
        font-weight: 100 900;
        src: url(${montserratVariableFontLatin}) format('woff2');
        unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
      }
    `;
    <head>
      <style dangerouslySetInnerHTML={{__html: montserratFontFaceDeclaration}} />
    </head>
@jgentes
Copy link

jgentes commented Nov 18, 2022

Thanks for the tip @jondcallahan - I can confirm that works!

@nikitapashinsky
Copy link

Thank you so much for this ❤️

@okerx
Copy link

okerx commented Dec 27, 2023

consider the following solution if you have bunch of css imports across the project,

// root.tsx
import { cssBundleHref } from '@remix-run/css-bundle';
import { LinksFunction } from '@remix-run/server-runtime';

import '@fontsource/lato/index.css';
import 'another-external-file.css'

export const links: LinksFunction = () => [
  ...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : []),
];

simply import any css file anywhere and it'll be added to your bundle :)

@Skoob1905
Copy link

Any help with this !! None of the solutions here are working for me :/

@jondcallahan
Copy link

@Skoob1905 If you're using remix as a vite plugin then you can just

// root.tsx
import "@fontsource-variable/inter";

@ayuhito
Copy link

ayuhito commented Feb 21, 2024

Any help with this !! None of the solutions here are working for me :/

There's an official guide too: https://fontsource.org/docs/guides/remix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment