Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use self-hosted fonts face using NextJS?

Fonts using NextJS

I have read different topics about how to use self-hosted fonts with NextJS.

What I got [ wait ] compiling ... when I did:

@font-face {
    font-family: 'montserrat';
    src: url('./mypath/Montserrat-Medium.woff2') format('woff2'),
        url('./mypath/Montserrat-Medium.woff') format('woff'),
        url('./mypath/Montserrat-Medium.ttf') format('truetype'),
        url('./mypath/Montserrat-Medium.svg#Montserrat-Medium') format('svg');
}

No error, or else just compiling... I've read ( stackoverflow/57590195) which says we should use a static path like

@font-face {
    font-family: 'font';
    src: url('./static/fonts/Montserrat-Medium.woff2') format('woff2');
}

but that solution does not work at all. It almost seems to work fine, because the error (or the compelling waiting) stops. But if you look closer your font is not loaded.

Then I tried fontfaceobserver, I understood quickly that the problem would be the same. Because you have to use font-face and you cannot use it with NextJS.

After I downloaded next-font I have read the doc and looked at the github exemples.

Here is my next.config.js inspired of theirs.

const withSass = require('@zeit/next-sass');
const withCSS = require("@zeit/next-css");
const withFonts = require('next-fonts');

module.exports = withFonts(
    withCSS(
        withSass({
            enableSvg: true,
            webpack(config, options) {
                config.module.rules.push({
                    test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
                    use: {
                        loader: 'url-loader',
                        options: {
                            limit: 100000
                        }
                    }
                });
                return config;
            }
        })
    )
);

My path to fonts public/static/fonts.

And here is how I tried to use it.

...
function MainIndex() {
    ...
    return (
        <>
        ...
        <style jsx>{`
                @font-face {
                    font-family: 'Montserrat';
                    src: url('./static/fonts/Montserrat-Medium.ttf');
                }
                h1 {
                    font-family: 'Montserrat';
                }
        `}</style>
        </>
    )
}
...

Solutions I found

  • ✗ https://github.com/bramstein/fontfaceobserver 456 KB
  • ✗ https://github.com/rohanray/next-fonts 1.89 MB
  • ? The dangerouslySetInnerHTML could work but it's not the best solution I guess. (I didn't try it)
  • ✗ url('./static/fonts/font.woff2')

Read more one the github issue

EDIT:

I tried to adapt what Jesper We did.

I have created /public/static/fonts/fonts.css and /public/fonts/allMyfont.ttf then I imported in _var.scss to use it with sass variable @import "/public/static/fonts/fonts.css"; import style.scss my var $font and import "my/path/style.scss" to my index.js (compling for ever)

After I tried a closer way still /public/static/fonts/fonts.css with my fonts in the same folder. Then in my index.js. But that one does nothing.

Here the code in live CodeSandBox

like image 681
crg Avatar asked May 20 '20 09:05

crg


People also ask

How do I import a Google font into Nextjs?

Create a new page under /pages directory named _document. js file and add the following code there. Also, the crossorigin is renamed to crossOrigin="true" because we are writing jsx and not plain HTML here. Well, now this will download the desired font for us.


1 Answers

This is what I usually do:

  1. Put the fonts in public/static somewhere

  2. In the same folder as the fonts put a CSS file where the fonts are declared

CSS file example /public/fonts/style.css:

@font-face {
    font-family: 'Italian No1';
    src: url('ItalianNo1-Black.eot');
    src: url('ItalianNo1-Black.eot?#iefix') format('embedded-opentype'), url('ItalianNo1-Black.woff2') format('woff2'), url('ItalianNo1-Black.woff') format('woff');
    font-weight: 900;
    font-style: normal;
}

[UPDATE] For recent versions of NextJS the proper place to import the CSS file is in an import statement in _app.js (See docs).


Older answer:

Import this css in _document.js (docs):

render() {
    return (
        <Html>
            <Head>
                <link href="/fonts/style.css" rel="stylesheet"/>
            </Head>

            <body>
                <Main/>
                <NextScript/>
            </body>
        </Html>
    )
}
like image 98
Jesper We Avatar answered Sep 29 '22 05:09

Jesper We