Not able to load .ttf in React - reactjs

It throws DOM EXCEPTION
styles file
import { fontUrls1 } from './Fonts/Amaranth-Bold.ttf';
const GlobalStyle = createGlobalStyle`
#font-face {
font-family: 'Amaranth-Bold';
src: url('${fontUrls1}') format('truetype');
}
body {
font-family: 'Amaranth-Bold';
}
body.fontLoaded {
font-family: 'Amaranth-Bold' ;
}'
My app.js file
const openUberMoveLightObserver = new FontFaceObserver('Amaranth-
Bold',{});
Executing this line throws an error.
openUberMoveLightObserver.load().then(() => {
document.body.classList.add('fontLoaded');
});
Uncaught (in promise) DOMException

You don't need to import fonts to add into styles....
You can do this just passing url to the fonts
like this.....
export const MyFonts = createGlobalStyle`
#font-face {
font-family: 'Metropolis';
src: url(/static/fonts/Metropolis-ExtraLight.ttf);
src: url(/static/fonts/Metropolis-Light.ttf);
src: url(/static/fonts/Metropolis-LightItalic.ttf);
src: url(/static/fonts/Metropolis-Medium.ttf);
src: url(/static/fonts/Metropolis-Regular.ttf);
src: url(/static/fonts/Metropolis-SemiBold.ttf);
}
`;
OR
export const MyFonts = createGlobalStyle`
#import url('/static/fonts/Metropolis-ExtraLight.ttf');
#import url('/static/fonts/Metropolis-Light.ttf');
#import url('/static/fonts/Metropolis-LightItalic.ttf');
#import url('/static/fonts/Metropolis-Medium.ttf');
#import url('/static/fonts/Metropolis-Regular.ttf');
#import url('/static/fonts/Metropolis-SemiBold.ttf');
`;
you can use this font by importing inside your component
import React from 'react';
import MyFonts from './MyFonts';
function Example(){
return (
<div>
<MyFonts />
....
</div>
)
}
export default Example

You need to add a specific loader to load the font. For example if you are using webpack then you can use url-loader as below:
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
exclude: path.resolve(__dirname, "node_modules"),
use: [
{
loader: "url-loader",
options: {
prefix: "font",
limit: 10000,
mimetype: "application/octet-stream"
}
}
] }

Related

Error during bundle: Error: Unexpected character '' (Note that you need plugins to import files that are not JavaScript)

I added font to react typescript project after that I try to build but its showing error
Error during bundle: Error: Unexpected character '' (Note that you need plugins to import files that are not JavaScript)
Adding font using styled-components and loader using is url-loader
fonts work fine in system and no error while run.
Font extension is ttf. Below is my style file using styled-component
import IBMPlexSansSemiBold from './fonts/IBMPlexSans/IBMPlexSans-SemiBold.ttf';
import IBMPlexSansBold from './fonts/IBMPlexSans/IBMPlexSans-Bold.ttf';
import { font} from './Fonts';
export const FontsIBM = createGlobalStyle`
#font-face {
font-family: ${font.DEFAULT.SEMI_BOLD};
src: local('IBMPlexSans-SemiBold'), local(${font.DEFAULT.SEMI_BOLD}),
url(${IBMPlexSansSemiBold}) format('truetype');
font-weight: 600;
font-style: normal;
}
#font-face {
font-family: ${font.DEFAULT.BOLD};
src: local('IBMPlexSans-Bold'), local(${font.DEFAULT.BOLD}),
url(${IBMPlexSansBold}) format('truetype');
font-weight: 700;
font-style: normal;
}
`;
This is how I config url-loader
const rootMain = require('../../../.storybook/main');
module.exports = {
...rootMain,
core: { ...rootMain.core, builder: 'webpack5' },
stories: [
...rootMain.stories,
'../src/lib/**/*.stories.mdx',
'../src/lib/**/*.stories.#(js|jsx|ts|tsx)',
],
addons: [...rootMain.addons, '#nrwl/react/plugins/storybook'],
staticDirs: ['../../../public'],
webpackFinal: async (config, { configType }) => {
// apply any global webpack configs that might have been specified in .storybook/main.js
if (rootMain.webpackFinal) {
config = await rootMain.webpackFinal(config, { configType });
}
//Font added using url-loader
config.module.rules.push({
test: /\.(ttf|eot|woff|woff2)$/,
loader: require.resolve('url-loader'),
options: {
name: '[name].[hash].[ext]',
},
});
// add your own webpack tweaks if needed
return config;
},
};

Add self hosted fonts in Material-UI with Next.js [duplicate]

This question already has answers here:
Self-hosted fonts using NextJS
(4 answers)
Closed 1 year ago.
I have a problem when I try to add self hosted font in Material UI 5 with Next.js. I got this error:
You may need an appropriate loader to handle this file type, currently
no loaders are configured to process this file. See
https://webpack.js.org/concepts#loaders (Source code omitted for this
binary file)
Even I have added file-loader in next.config.js here:
module.exports = {
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader'],
},
],
},
};
And this is my custom theme:
PS: my font name in local is BarcadeBrawl.ttf.
import { createTheme } from "#mui/material";
import { purple, blue } from '#mui/material/colors';
import BarcadeBrawl from '../assets/fonts/BarcadeBrawl.ttf'
export const theme = createTheme({
palette: {
primary: {
main: purple[500],
},
secondary: {
main: blue[500],
},
},
typography: {
fontFamily: 'BarcadeBrawl',
fontSize: 12,
},
components: {
MuiCssBaseline: {
styleOverrides: `
#font-face {
font-family: 'BarcadeBrawl';
font-style: normal;
font-display: swap;
font-weight: 400;
src: local('BarcadeBrawl'), local('BarcadeBrawl'), url(${BarcadeBrawl}) format('ttf');
unicodeRange: 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;
}
`,
},
},
});
Firstly, that's not how Webpack is configured in Next.js. Refer the official documentation on this - Custom Webpack Config. Secondly, file-loader is deprecated for Webpack v5 (the default for newer Next.js versions). Use asset modules instead.
So you probably need to do something like this:
// next.config.js
// https://webpack.js.org/guides/asset-management/#loading-fonts
module.exports = {
// other configs...
// future: { webpack5: true }, // -- not needed since Next.js v11.0.0
webpack(config) {
config.module.rules.push({
test: /\.(woff|woff2|eot|ttf|otf)$/i,
issuer: { and: [/\.(js|ts|md)x?$/] },
type: 'asset/resource',
});
return config;
},
};
Moreover, this is not necessary, you can simply store your fonts directory in public directory and use them. There is no need to import them. They can be directly referenced like /fonts/BarcadeBrawl.ttf. Refer: Static File Serving

NextJS and Storybook not rendering images and global styles

what is the best way to load global styles and images for Storybook in NextJS?
Below are the following Storybook files (config.js and scs-loader.scss and webpack.config.js)
webpack.config.js
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [require.resolve('babel-preset-react-app')],
},
});
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/,
loader: require.resolve('file-loader')
});
return config;
};
config.js
import '!file-loader!style-loader!css-loader!sass-loader!./scss-loader.scss';
import { configure } from '#storybook/react';
configure(require.context('../components', true, /\.stories\.(j|t)sx?$/), module);
scss.loader.scss
#import '../styles/global.scss';
Using the above config I can get a successful Storybook build however I do not see any global styles nor do I see any images referenced in global.scss
If i remove the file-loader in config.js as follows
import '!style-loader!css-loader!sass-loader!./scss-loader.scss';
import { configure } from '#storybook/react';
configure(require.context('../components', true, /\.stories\.(j|t)sx?$/), module);
I see this error.
Error: Can't resolve '/images/hero.jpg' in 'D:\dev\personal\nextjs-ts\.storybook'
If I then go and remove all the images from global.scss I can then load Storybook and I can see the global styles however I've lost all the images. I need to try and get images and global styles working in tandem. Thanks.
Here is an example of how the images are referenced in global.scss.
.hero {
width: 100%;
height: 800px;
background: url('/images/hero.jpg');
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}

Style sheet is not styling React Component

I searched for similar problems a lot but couldn't come up with a solution.
I integrated React.js with my working project. I am using Webpack.
Everything runs properly except styling.
I have Style.scss and I import this file in my react file. It compiles without an error but the actual style is not applying to the element.
The inline style works and other classes that are included normally also are fine.
Style.scss
.wtf {
font-weight: bold;
font-size: 40px;
}
Test.js
import React from 'react';
import '../Styles/Style.scss';
const style = {
border: 'solid 5px green'
};
export default class Test extends React.Component {
render() {
return (
<div style={style} className='wtf text-danger'>
Am I React.Component? And I am working too?
</div>
);
};
}
According to the snippet above, text-danger applies color red and border:solid 5px green works too, however, the style is specified in Style.scss is not working.
I checked compiled file and it seems like my scss style code exists there
This is the result in the browser
My webpack.config.js file content is below:
const path = require( 'path' );
module.exports = {
mode: 'development',
entry: {
rooms: './react-src/rooms/rooms.js',
tasks: './react-src/tasks/tasks.js'
},
output: {
filename: '[name].js',
path: path.resolve('../htdocs/react-dist')
},
module: {
rules: [
{
test: /\.scss$/,
use: [
// style-loader
{ loader: 'style-loader' },
// css-loader
{
loader: 'css-loader',
options: {
modules: true
}
},
// sass-loader
{ loader: 'sass-loader' }
]
},
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
}
};
Any idea what is the problem?
Solved
According to my example and my Webpack configuration, it was compiling styles so generating a new class name.
So, that huge token highlighted above is my actual class name which I have to use.
It can be imported as an Object so I can access class name as a property.
This is how it worked.
import React from 'react';
import style from '../Styles/Style.scss';
export default class Test extends React.Component {
render() {
return (
<div className={style.wtf}>
Am I React.Component? And I am working too?
</div>
);
};
}
if you modify your webpack config to:
{...
loader: 'css-loader',
options: {
modules: false
},
...}
you can use regular className property

Webpack react sass not understanding #functions

I have sample react app and using scss. I have 2 scss file:
Colour palette:
$_color-base-white: #FFF;
$_color-base-black: #000;
$_color-base-grey: #DCDCDC;
$_color-base-charcoal: #404040;
$_color-base-turquoise: #50E3C2;
$_color-base-red: #e3454f;
$_color-base-blue: #006DEF;
$_color-base-green: #009d2f;
$palettes: (
white: (
x-light: lighten($_color-base-white, 60%),
light: lighten($_color-base-white, 40%),
mid-light: lighten($_color-base-white, 10%),
base: $_color-base-white,
mid-dark: darken($_color-base-white, 10%),
dark: darken($_color-base-white, 40%),
x-dark: darken($_color-base-white, 60%)
)
);
#function palette($palette, $tone: 'base') {
#return map-get(map-get($palettes, $palette), $tone);
}
And then I have App.scss file inside React Component:
#import '../../assets/styles/colour_semantics';
.app-header {
color: $palettes(white, mid-light);
}
And App component looks like this:
import React, { Component } from 'react';
import './App.scss';
class App extends Component {
render() {
return (
<div className="app">
<h1 class="app-header">Hello World</h1>
</div>
);
}
}
export default App;
When using only defined colours like $_color-base-white in App scss everything is ok and working but when want to use $palettes:
index.js??ref--5-1!./node_modules/sass-loader/lib/loader.js??ref--5-2!./src/containers/App/App.scss:1 Uncaught Error: Module build failed:
$palettes: (
^
(white: (x-light: white,
Why can I not use functions? Webpack plugin config looks like this:
{
test: /\.(sass|scss)$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader", options: {
sourceMap: true,
importLoaders: 2
},
}, {
loader: "sass-loader" , options: {
sourceMap: true
},
}]
},
You are calling the list and not the function.
.app-header {
color: $palettes(white, mid-light);
}
Should be
.app-header {
color: palette(white, mid-light);
}

Resources