Styling the navigation and using next/font
Now that our Navigation is working, we will add a few touches of color and use next/font to add a custom web font to our project
When using next/font, you can use any font available on google fonts or use your own local font(s), the best part about using next/font is that it will optimize the loading of the font and make sure that there are zero layout shifts, also when using next/font we are self-hosting the font(s), which means we will NOT need to make an external network request to fetch the font, which will decrease loading times but also increase privacy as NO request is made to google servers
There is one optimization you can see when you deploy on vercel, Next.js will add a link element, with the rel
attribute set to preload
, to your pages <head>
element. This <link>
will tell the browser to preload your font (which will decrease the loading time when getting the font):
When I run the website in production mode locally (to run a production build locally you can use commands npm run build
and then npm run start
), I can NOT see the preload optimization (using Next.js 14.2.11). I'm not sure this is a bug, but I found the Next.js Issue #62332 which seems to be related. I also tried Next.js 15 and there the problem seems to be fixed, I can even see the <link>
element that preloads the font(s), when I run the project in development
next/font with an open source font
Because we are using the font for our navigation, let's start by editing our layout.tsx
file (that is in the app
folder) and import the font from there:
Line 4: we import the font called Kablammo from next/font, you can find Kablammo on google fonts
Lines 11 to 16: we set some options for the font:
- like what subset do we want to use, in our case latin
- the CSS variable (--font-kablammo) we want to use for the font
- the (font-)weight that we will we use
- the display strategy defines what happens during the period when the font is still getting fetched and not ready to be used, Next.js sets it to swap by default, so if you chose swap as in this example you could also just not set it or if you prefer to let the browser chose the display strategy then use auto as value, as described on the chrome developer "font-display" page when you chose auto most browsers will use a technique similar to block, meaning that for a short period of time, the browser will use an invisible fallback font face (to avoid layout shifts) and then when the font is ready it will swap in the font
Because the fonts are fully typed, you can just type an option name and will get a list of values that you can choose from
Line 24: we add the font style to our HTML element
In the last chapter of the Next.js "font optimization" documentation, there is a very import information about how Next.js caches fonts at build time, quote:
Every time you call the localFont or Google font function, that font is hosted as one instance in your application. Therefore, if you load the same font function in multiple files, multiple instances of the same font are hosted.
So if you have a font that you need in multiple pages it is probably best to load it in the layout and not load the same font in several different pages; have a look at the Next.js "font optimization" documentation where they list several options you can use to avoid having multiple instances of the same font file in your Next.js cache; this is important because if you have multiple instances of the font it would mean that the browser will load the font multiple times, instead of just once
next/font with a local font (optional)
I'm not going to deep dive into this, but just know that if you prefer using a local font that you downloaded in the past, you can do that too using next/font
Here is a simple example of how to add a local font to our layout.tsx
file:
Line 4: instead of importing a google font from next/font we are this time importing localFont function from next/font
Lines 11 to 16: we replace the previous code, with new code that uses the localFont function, the options we use are similar to those we used previously, the only difference is that we replace the subsets with an src option, as src you should set a value that is the path to the local font, assuming it is located inside of your public
folder, so as our font has an src set to ./assets/fonts/myFont.woff
tells next/font that we have stored our local myFont.woff
font file in /public/assets/fonts
Line 24: same as before, we add the font style to our HTML element
Navigation CSS module
Next, we are going to add a stylesheet for our Navigation component and use the new font for the navigation items
Create a new navigation.module.css
file in the /components/header
folder and insert the following content:
Line 17: we use the --font-kablammo variable we defined when setting the options for the font in the layout.tsx
file
The final step is to edit our Navigation.tsx
file in the /components/header
folder and start using the styles we just created, like so:
Line 6: we import the new CSS Module containing the Navigation component stylesheet
Lines 28 / 34 / 43 and 49: we use the 3 CSS rules, the .active
rule will be used to make the Navigation entry that matches the current pathname bold, and the .navigation
rule uses position fixed so that the navigation bar will always stay on top and finally the .link
rule adds the new Kablammo font all the links of the navigation
There is one more change we need to do, because we made the navigation to have a fixed position, it is now as if it was not part of the document anymore, meaning it will NOT take up space anymore, as it will be floating above the content. This will cause the page content to move up and eventually be under the navigation
This is why we will edit our global.css
file and edit the body class:
Lines 36 to 37: we add a padding-top
property and set its value to the same size as the height of the navigation, this will ensure that when the page has loaded, there is no content displayed under the navigation because the content of the body will have been pushed down a bit (later when scrolling the content will move under the navigation)
Now launch the dev server if it isn't already running (using the npm run dev
command), then open your browser and go to the project's homepage at http://localhost:3000/
to see the styled navigation which is using our custom font instead of the default browser font, for yourself
Congratulations 🎉 you now have a much better-looking navigation component and learned how to use next/font
If you liked this post, please consider making a donation ❤️ as it will help me create more content and keep it free for everyone