Utilize Webpack to load custom fonts using font-face technique

My attempt to implement a font in my CSS file using @font-face is unsuccessful as the font fails to load. Here is an overview of my directory structure:

https://i.sstatic.net/D2QPK.png

In the webpack.config.js, I have set up the loader for fetching fonts.

var path = require('path');
var webpack = require('webpack');

module.exports = {
  devtool: 'eval',
  entry: [
    "./index.js"
  ],
  output: {
    path: __dirname+"/build",
    filename: "main.js"
  },
  plugins: [
    new webpack.NoErrorsPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  module: {
      loaders: [
          { test: /\.js$/, loaders: ['react-hot', 'babel-loader'], exclude: /node_modules/ },
          { test: /\.jsx?$/, loaders: ['react-hot', 'babel-loader'], exclude: /node_modules/ },
          { test: /\.svg$/, loader: "raw" },
          { test: /\.css$/, loader: "style-loader!css-loader" },
          { test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file?name=src/css/[name].[ext]'}

      ]
  }
};

The CSS file contains the following font definition:

@font-face {
  font-family: 'Darkenstone';
  src: url('./Darkenstone.woff') format('woff');
}

body {
  background-color: green;
  font-size: 24px;
  font-family: 'Darkenstone';
}

Despite everything else functioning correctly, the font fails to load.

Answer №1

My search for a solution ended when I switched from file-loader to url-loader. Make sure you have url-loader installed to handle the job effectively.

{ test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }

Answer №2

As stated in Webpack's Documentation, it is necessary to make adjustments to your webpack.config.js file in order to handle font files effectively. This involves adding a specific loader for font files, as shown below:

{
   test: /\.(woff|woff2|eot|ttf|otf)$/i,
   type: 'asset/resource',
  }

This configuration will ensure that webpack can process various types of font files. The final version of the webpack.config.js file will resemble the following structure.

const path = require('path');
module.exports = {
       entry: './src/index.js',
       output: {
         filename: 'bundle.js',
         path: path.resolve(__dirname, 'dist'),
       },
       module: {
         rules: [
           {
             test: /\.css$/i,
             use: ['style-loader', 'css-loader'],
           },
           {
             test: /\.(png|svg|jpg|jpeg|gif)$/i,
             type: 'asset/resource',
           },
          {
            test: /\.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
         ],
       },
     };

After setting up the loader and importing the fonts into your entry file (e.g. ./src/index.js), you can easily utilize them by declaring an @font-face. Just like images, webpack will recognize the local url(...) directive associated with fonts.

Answer №3

In order to resolve the issue with webpack 4, I made the following adjustments:

       {
         test: /\.svg$/,
         use: ['svg-loader']
       },
       {
         test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
         use: ['file-loader']
       }
       { test: /\.(png|woff|woff2|eot|ttf|svg)$/, use: ['url-loader?limit=100000'] }

I opted to replace svg-loader and file-loader with url-loader

This is how my app.scss file appears now:

$fa-font-path: '~font-awesome/fonts';
@import '~font-awesome/scss/font-awesome';

$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import '~bootstrap-sass/assets/stylesheets/bootstrap';

And in my app.js, I include the app.scss:

import './app.scss';

As a result of these modifications, this is the updated webpack configuration:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpackConfig = require('./webpack.config');

module.exports = {
  entry: {
    app: './client/app/app.js'
  },
  devtool: 'source-map',
  mode: 'development',
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Development',
      template: 'client/index.html'
    })
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
        ],
      },
      { test: /\.(png|woff|woff2|eot|ttf|svg)$/, use: ['url-loader?limit=100000'] }
    ]
  }
};

Answer №4

After upgrading from Webpack 4.x.x to the latest version 5.52.1, I encountered some issues with my font faces.

When I looked at the content of my exported files like .woff, .woff2, and .ttf, it appeared something like this:

export default __webpack_public_path__ + "glyphicons-halflings-regular.woff2";

To resolve the problem, I decided to completely remove the previous file-loader configuration. It seemed that the files were being processed multiple times, leading to errors.

Before:

...
module: {
    rules: [
        {
            test: /\.(png|jpg|gif|ico|woff|woff2|ttf|svg|eot)$/,
            use: {
                loader: 'file-loader',
                options: { 
                    name: '[name].[ext]',
                    useRelativePath: true
                }
            }
        },
        {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                {
                    loader: 'css-loader',
                    options: { url: false }
                }
            ]
        }
    ]
}
...

After:

...
module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                {
                    loader: 'css-loader',
                    options: { url: false }
                }
            ]
        }
    ]
}
...

For more details, visit https://webpack.js.org/guides/asset-modules/

Answer №5

After some experimentation, I finally found a solution that worked for me when using regular CSS on a Node.js/webpack build. I wanted to share it here in case it can help others facing the same issue in the future.

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: "babel-loader",
        options: {
          presets: ["@babel/preset-env"],
        },
      },
    },
    {
      test: /\.html$/,
      exclude: /node_modules/,
      use: "html-loader",
    },
    {
      test: /\.(png|svg|jpg|jpeg|gif)$/i,
      type: "asset/resource",
      generator: {
        filename: "assets/[name][ext][query]",
      },
    },
    {
      test: /\.(woff|woff2|eot|ttf|otf)$/i,
      type: "asset/resource",
      generator: {
        filename: "fonts/[name][ext][query]",
      },
    },
  ],
},

To make this setup work, don't forget to add the necessary import statements in your .js file:

// Example of importing images
import "../../assets/icon-16.png";
import "../../assets/icon-32.png";

// Example of importing fonts
import "../../Fonts/opensans-regular-webfont.eot";
import "../../Fonts/opensans-regular-webfont.svg";

Finally, update your .css file to reference the newly created dist/fonts directory:

@font-face {
  font-family: 'open_sansregular';
  src: url('fonts/opensans-regular-webfont.eot');
  /* Additional font sources */
}

html,
body {
    font-family: open_sansregular !important;
}

Don't forget to build the project after making these changes.

Answer №6

Encountered a similar issue myself. In this scenario, the font's 'src' attribute was displaying src="[object Module]".

The fix involved disabling esModule in webpack:

{
  test: /\.(png|jpe?g|gif|svg|ttf|woff|otf)$/,
  use: [
    {
      loader: 'file-loader',
      options: {
        name: '[name].[contenthash].[ext]',
        outputPath: 'static/img',
        esModule: false // <- this line
      }
    }
  ]
}

For more details, check out this link.

Answer №7

To configure webpack in my webpack.config.ts file, I had to make sure of two key things: Webpack was set up to handle font files using the following code snippet:

module: {
  rules: [
    {
      test: /\.(woff|woff2|eot|ttf|otf)$/i,
      type: 'asset/resource',
    }
  ]
}

Additionally, I needed to include css-loader for webpack to interpret @font-face and url() declarations, along with style-loader to inject the CSS into the Document Object Model (DOM).

module: {
  rules: [
    {
      test: /\.(woff|woff2|eot|ttf|otf)$/i,
      type: 'asset/resource',
    },
    {
      test: /\.css$/i,
      use: [
        'style-loader',
        'css-loader'
      ]
    },
  ]
}

Following this setup, I edited my index.css file located under src folder (mine was named Exo) as follows:

@font-face {
  font-family: "Exo";
  src: local(Exo), // Also used in css
    url('./fonts/exo-v20-latin/exo-v20-latin-regular.woff2') format('woff2'),
    url('./fonts/exo-v20-latin/exo-v20-latin-regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

 html, body {
  font-family: Arial, Helvetica, sans-serif;
 }

I recommend using woff formats as they are compatible with most modern web browsers.

Don't forget to import your CSS file into your main app index.js file:

import './index.css';

Finally, remember to run a build command to ensure these files are included in your build/dist/public directory (or any custom build folder you've specified).

npm run build

OR

yarn run build

This approach worked well for me. Hopefully, it proves helpful for you too!

Answer №8

Consider updating the loader:

{test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file?name=[name].[ext]'}

Additionally, include publicPath: 'build/' in your output configuration.

Answer №9

By upgrading the webpack version to 4.42.0 from 4.20.2, I successfully resolved the issue of my code not loading the desired font.

const URL_LOADER_LIMIT = 8192

module.exports = () => ({
  module: {
    rules: [
      {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/',
              limit: URL_LOADER_LIMIT
            }
          }
        ]
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/',
              limit: URL_LOADER_LIMIT,
              mimetype: 'application/font-woff'
            }
          }
        ]
      },
      {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/',
              limit: URL_LOADER_LIMIT,
              mimetype: 'application/octet-stream'
            }
          }
        ]
      },
      {
        test: /\.mp3$/,
        use: ['file-loader']
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              outputPath: 'images/',
              name: '[name].[ext]',
              limit: URL_LOADER_LIMIT,
              mimetype: 'image/svg+xml'
            }
          }
        ]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              outputPath: 'images/',
              name: '[name].[ext]',
              limit: URL_LOADER_LIMIT
            }
          }
        ]
      }
    ]
  }
})

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

Create the transformation matrix for the Autodesk model

Can someone provide information about the following two matrices and their purposes? placementTransform (1 x 12) refPointTransform (1 x 16) I believe they may be related to translating (Tx, Ty, Tz) or rotating (Rx, Ry, Rz) 3D objects, but I am unsure du ...

Setting up a basic node.js + socket.IO + Express server from scratch

After setting up a basic node.js socket.IO server, I quickly realized it was not sufficient for handling webpages with script tags. This led me to explore express, a straightforward web framework for node.js. While going through the express documentation ...

Troubleshooting the failure of implementing react hooks useState within a material-ui Tab container

Recently, I have been experimenting with implementing react-hooks useState in material-ui/tabs component. While I have been successful in using the handleChange function, I am eager to explore and master the use of hooks in this scenario. Interestingly, my ...

Switching a component from controlled to uncontrolled input

I'm currently in the process of building a website using graphql and apollo with a react front end. One issue I've encountered is that when the site admin tries to update content for specific sections of pages, I keep seeing this error in the con ...

The input text in the Typeahead field does not reset even after calling this.setState

As I work on creating a watchlist with typeahead functionality to suggest options as the user types, I encountered an issue where the text box is not resetting after submission. I attempted the solution mentioned in this resource by calling this.setState( ...

Step-by-step guide on building a MongoDB strict schema for nested documents, allowing any string key with values limited to arrays of ObjectIDs, mapped to a typescript interface named SchemaForMongo:

I am currently working with Nest.js and endeavoring to establish a stringent schema for the TypeScript code provided below: interface SchemaForMongo { [key: string]: ObjectID[] } const invalidDocumentProperty_1: SchemaForMongo = ...

Verifying the existence of an optional property on my component using Jest

One of the props in my component is called jsonpayload, and it is optional. Here's how it looks in the interface: export interface props { jsonpayload?: payload[] onclick: () => void; } My Jest file: const test_prop: dummy_props ...

Transforming a C# Web Application into NodeJS using Express Framework

Can anyone share their experiences, tips, or challenges encountered when converting a C# ASP.NET MVC N-Tier Web Application? I'm seeking some insights before diving into the conversion process myself. Does anyone have any real-world examples of succe ...

Implement a function in JavaScript to sum quantities for identical JSON objects

I am looking to calculate the total quantity for each category. var items = [ { cat: 'EK-1',name:"test",info:"mat", quantity: 3}, { cat: 'EK-2', name:"test2",info:"na ...

What is the reason behind asp:Textbox occasionally appending "text" to the CSS class in the final HTML output?

Here's the code snippet: <asp:TextBox ID="txtAddress" CssClass="s175" runat="server" MaxLength="30" placeholder="Street"></asp:TextBox> After rendering, it looks like this: <input name="ctl00$LeftColumnContent$txtAddress" type="text" ...

Error encountered during compilation of a TypeScript file using tsc command in Terminal

Error encountered while running the TypeScript compiler: - Cannot find name 'IterableIterator' in core-js. - Cannot find name 'Iterable' in core-js. - Cannot find name 'PropertyKey' in core-js. - Cannot find name 'Symbol& ...

Modifying CSS content attribute in real-time

A colleague of mine has rented a webshop from a company. They have the option to select different templates and are also able to customize the CSS and add Javascript snippets. They reached out to me for help with making some modifications, but there's ...

Encountering a 'MODULE_NOT_FOUND' error following an upgrade of the playwright version

I am currently in the process of developing an automated test suite using Cucumber, Java, and Playwright. I have utilized a template from github.com/akshayp7/playwright-java-cucumber as my starting point. Upon updating Playwright to the latest version in ...

Creating a TypeScript declaration for the Cypress configuration file

When attempting to transition a setup-helper file to a ts definition, I encountered the following error message: Property 'domainName' does not exist on type 'Config' The error is related to this specific line of code: const { domainNa ...

What is the process for updating the Git Hash in a npm package.json within a Git project?

Is there a way to specify an exact git hash in the dependencies of a Github project's package.json, while also making it easy to upgrade at a later time? Here is how my current package.json looks: { "name": "my fabulous app", "version": "1.0.0", ...

When running NPM install, an error is thrown with the message: "internal/modules/cjs/loader.js:800

I experimented with various solutions, but none of them seem to be effective. In an attempt to resolve the issue, I took the step of removing the node_modules directory along with the package-lock.json file. Following that, I attempted to execute $ npm in ...

Should I save exclusive items as an object or an array?

In the process of creating a compact online store system with MongoDB integration, there is an order table set up to house various items. Each individual item possesses a unique trait known as code. The dilemma arises when deciding on how the data should ...

CSS - Placeholder styling not being effective when selectors are grouped

Why is Chrome successful at executing this code: .amsearch-input::-webkit-input-placeholder { color: red; } <input class="amsearch-input" placeholder="It works!" /> ...while it doesn't work in other browsers: .amsearch-input::-we ...

Tips for Incorporating a WordPress Blog Page into a Next.js Path Using a Node.js Back-end

I am currently working on a Next.js project and I have a specific requirement to display a WordPress page for blog posts within the application. Essentially, I want to showcase relevant blog information on the 'blogs' route by integrating a WordP ...

Passing data between API requests in Node.js

I have a functional prototype, but I believe there is room for improvement in its structure. The project is an innovative Weather application created using React, Node/Express, and the OpenWeather API. In essence, the lat and lon values from the initial AP ...