Ways to incorporate unique fonts into a Next.js application residing under a subdirectory of a domain

Currently, I have a Next.js application deployed on a sub-path of a domain (for example example.com/my-next-js-app). To handle bundle scripts and styles, I utilized the Next.js configuration like so:

const isProd = process.env.NODE_ENV === 'production';
module.exports = {
  basePath: isProd ? '/my-next-js-app' : '',
};

When it comes to images, I've developed a function that appends a prefix to the image URL if it's in a production environment.

export function getAssetUrl(path: string) {
  return process.env.NODE_ENV === 'production' ? `${MAIN_URL}${path}` : path;
}

However, managing fonts poses a bit of a challenge. My custom font faces are defined within the styles/globals.css file as shown below:

@font-face {
  font-family: 'MyCustomFont';
  font-style: normal;
  font-weight: 400;
  src: url('/fonts/MyCustomFont-Regular.ttf') format('truetype');
  font-display: swap;
}

@font-face {
  font-family: 'MyCustomFont';
  font-style: normal;
  font-weight: 700;
  src: url('/fonts/MyCustomFont-Bold.ttf') format('truetype');
  font-display: swap;
}

@font-face {
  font-family: 'MyCustomFont';
  font-style: italic;
  font-weight: 700;
  src: url('/fonts/MyCustomFont-BoldItalic.ttf') format('truetype');
  font-display: swap;
}

As a result, upon deployment, the fonts will not reside in the root public folder but rather at

example.com/my-next-js-app/fonts/MyCustomFont-xxx.ttf
.

Answer №1

The challenge was successfully resolved by developing a component that contains the font face styles within an inline style attached to the <head> element using the assistance of Head from the library next/head. This strategy allows for the utilization of the function getAssetUrl() based on the appropriate asset URL.

import Head from 'next/head';
import React from 'react';
import { getAssetUrl } from '../lib/assets';

export default function CustomFontFaces() {
  return (
    <Head>
      <style
        dangerouslySetInnerHTML={{
          __html: `
            @font-face {
              font-family: 'MyCustomFont';
              font-style: normal;
              font-weight: 400;
              src: url('${getAssetUrl('fonts/MyCustomFont-Regular.ttf')}') format('truetype');
              font-display: swap;
            }

            @font-face {
              font-family: 'MyCustomFont';
              font-style: normal;
              font-weight: 700;
              src: url('${getAssetUrl('fonts/MyCustomFont-Bold.ttf')}') format('truetype');
              font-display: swap;
            }

            @font-face {
              font-family: 'MyCustomFont';
              font-style: italic;
              font-weight: 700;
              src: url('${getAssetUrl('fonts/MyCustomFont-BoldItalic.ttf')}') format('truetype');
              font-display: swap;
            }
          `,
        }}
      />
    </Head>
  );
}

Answer №2

Switch to next/fonts today! By using next/font, your fonts will be optimized automatically (even custom ones) and eliminate the need for external network requests, leading to enhanced privacy and performance. Learn more here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging the Mutation hook for updating information on a Graphql server

Recently, I encountered an issue while utilizing the useMutation hook in React Native to update data on my server within a project I'm working on. The file where I'm implementing this hook is attached for reference. I've also included a scr ...

What could be causing me to consistently receive a 0 value despite my collection having content stored within it?

How can I retrieve the value of dropVolume and use it in another method after executing my getAllDropsVolumePerDate(date) function? Each time I try to access dropVolume, it returns a value of 0. dropVolume = 0; getAllDropsVolumePerDate(date: string) { ...

The CSS dropdown menu appears in a horizontal layout rather than vertical

** body { background-color: #9cb4c0; background-size: 100% 100%; } .div-1 { float: right; padding: 20px 10px; } h2 { text-align: right; ...

The mysterious height phenomenon when setting the width of a list item with jQuery

Consider a basic ul and li setup similar to this: <div id="middle"> <ul> <li> <a> bridal </a> </li> //.... </ul> </div ...

avoiding repetition of mouseup event firing

After perusing multiple inquiries on similar matters, I am under the impression that my issue lies in propagation through numerous DOM elements. Despite this, I am still facing the problem of my Ajax function triggering multiple times when the mouseup even ...

Adjust the width of an HTML input using the Bootstrap 5 form-control class

Is it possible to set the width of an input using Bootstrap's form-control or input-group classes? In the example below, each input should have a width based on its maxlength attribute: <link href="https://cdn.jsdelivr.net/npm/<a href="/cd ...

Error message "MODULE_NOT_FOUND occurring post typescript transpilation"

Upon building my typescript app and starting the app.js, I encountered this error: node:internal/modules/cjs/loader:1050 throw err; ^ Error: Cannot find module 'controllers' I suspect that the issue lies in how I am using import/export stat ...

What is the best way to trigger a single function with two events on separate elements?

I currently have two functions that trigger on different events (click and blur) when interacting with separate elements. Is there a way to merge these two functions so that the same function is executed when clicking a button or losing focus on an input ( ...

What is the best way to retrieve a value from async/await functions?

async function fetchNetworkStatus() { const network = await Network.getConnection(); setConnection(network.isConnected); console.log(connectionStatus); if (network.isConnected) { return true; } else { ...

Heroku failing to set cross-site cookie through the Set-Cookie Response Header

Despite working fine locally, I am facing issues with setting cookies on Heroku when making cross-site calls. This problem seems to be occurring specifically in Chrome and Safari, the two browsers I have tested so far. It could be due to either the cross-s ...

tips on requiring users to scroll to access content on a webpage in HTML

I'm completely new to coding in HTML and CSS, so please excuse any mistakes I may make. Currently, I am working on a website using HTML and CSS, and I want the user to scroll down in order to view the content that comes after the logo and tagline. Wh ...

What is the best way to configure React children to only allow for a single string input

When using this component: <Component>example string</Component> How can I avoid the Typescript error related to type children: "example string" causing an issue? The 'children' prop of this JSX tag expects type '&qu ...

Determine the remaining days until the end of the month using moment.js

I need help figuring out how to dynamically display or hide a link based on whether there are less than two weeks remaining in the current month using moment.js. Currently, my code snippet looks like this: if (moment().endOf('month') <= (13, ...

Troubleshooting: JavaScript not displaying date in HTML input field

Currently, I am developing a hybrid application that utilizes both AngularJS and Angular 8. In this project, I am using a datepicker to display dates fetched from an API. However, I've encountered an issue where the date is only properly displayed whe ...

Clicking on a raised button initiates a variety of functions

I am faced with an issue involving two components, RaisedButton and TableList. TableList returns selected rows which are then updated in the state (currentSelectedRows). RaisedButton simply logs the currentSelectedRows to the console. Here is the problem I ...

What steps should I take to resolve the violation of the 'react/no-unescaped-entities' ESLint rule in my code?

Here is the current code snippet: const func = () => { return ( <div > you're free </div> )} ESLint is flagging the line "you're free" with the error error HTML entities must be escaped react/no-unescaped-enti ...

Maintain Static Background while Allowing Photos to Scroll

Struggling with a design issue on my website www.kdoan.com. The Three JS background animation is not staying fixed while allowing project sections to scroll normally. It used to work perfectly, allowing users to scroll through all the photos. For instance ...

Controller Receives Null Parameter Following an Ajax Request

Let's set the scene: Imagine a user clicks on the Details button, triggering the JavaScript function, getPersonId to fetch the personId as intended. Identifying the problem: Upon selecting the personId, I pass it into an ajax call. The Id is passed ...

What is the method for accessing an app from a file other than server.js?

I am dealing with two different files: file1.js const app = express(); require('./file1/config/customConfigurations').customSettings() .then((settings) => { app.locals.customSettings = settings; console.log(app.locals.customSettings) ...

Admob React Native experiencing difficulties with displaying Google mobile ads (interstitial ads)

Encountered an error: TypeError: undefined is not a function (near '...interstitial.onAdEvent...') Currently utilizing npm i react-native-google-mobile-ads Your assistance is greatly appreciated. import React, { useState, useEffect } from " ...