Self hosted font does not work on dev server - css

I'm having an issue, we needed to get rid of links to external resources in html file(as google api font and material icons). So I self hosted it, on localhost in network font is received and works fine, but on production stand there's even no requests in network to get this font.It seems that on production stand it doesn't event try to plug font or import css does not work in production.
Here's my index.css
#font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('KFOlCnqEu92Fr1MmWUlfBBc4AMP6lQ.woff2') format('woff2');
unicode-range: 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, U+FFFD;
}
body {
font-family: 'Roboto';
}
#font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url('MaterialIcons-Regular.ttf') format('truetype');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}
This is App.tsx:
import * as React from 'react';
import { Provider } from 'react-redux';
import { hot } from 'react-hot-loader/root';
import CssBaseline from '#material-ui/core/CssBaseline'; // CSS Reset
import { ThemeProvider } from '#material-ui/core/styles';
import NotifierProvider from 'components/NotifierProvider';
import { MuiPickersUtilsProvider } from '#material-ui/pickers';
import DateFnsUtils from '#date-io/date-fns';
import ruLocale from 'date-fns/locale/ru';
import { Router } from 'react-router';
import { initAxios } from 'security';
import store from '../../store';
import MainRouting from '../MainRouting';
import theme from './theme';
import history from '../../historyRouting';
import GlobalCss from '../GlobalCss';
import '../../assets/font/index.css';
// инициализируем аксиос с авторизацией
initAxios();
export const App: React.FC = () => (
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={ruLocale}>
<CssBaseline />
<Router history={history}>
<ThemeProvider theme={theme}>
<GlobalCss />
<Provider store={store}>
<NotifierProvider>
<MainRouting />
</NotifierProvider>
</Provider>
</ThemeProvider>
</Router>
</MuiPickersUtilsProvider>
);
export default hot(App);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
and maybe issue is in webpack, so here's my styles config:
module.exports = function () {
return {
module: {
rules: [
{
test: /\.(css|scss)$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
}
]
}
};
};
and coommon rules:
module.exports = function () {
return {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.(pdf|jpg|png|gif|ico|)$/,
exclude: /font/,
use: [
{
loader: 'url-loader?limit=20480&name=assets/img/[name]-[hash].[ext]',
options: {
esModule: false,
}
}
]
},
{
test: /\.svg$/,
use: ['#svgr/webpack', 'svg-url-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
exclude: /img/,
loader: 'file-loader?name=assets/font/[name].[ext]'
}
]
}
};
};
I guess paths are correct as it work on localhost.
please, help me, I spent hours to figure what's wrong...(

Finally fixed this problem!:) But maybe for someone who has the same issue it'll be helpful, because I spent whole day to figure this out.
Apparently there's a problem with "sideEffects": false in package.json file and you have to either delete this, either write "sideEffects": ["*.css"]. More information here

Related

How to override MUI default font roboto to custom font all over the website?

I'm already overriding globally but still its not overrides in some of the places, still I can see Roboto font especially on MUI select and autocomplete.
import { createTheme } from '#material-ui/core/styles';
// A custom theme for this app
const theme = createTheme({
typography: {
fontFamily: [
'DM Sans',
'sans-serif',
].join(','),
},
components: {
MuiCssBaseline: {
styleOverrides: `
#font-face {
font-family: 'DM Sans', sans-serif;
font-style: normal;
font-display: swap;
font-weight: 400;
src: url(https://fonts.googleapis.com/css2?family=DM+Sans) format('woff2');
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;
}
`,
},
},
});
export default theme;
Please have a look at this post which explains how to set up a font in your MUI theme and also has an example of how you can set it in a component (in case you want for a specific component) as an example.
https://stackoverflow.com/a/73476871/5376404
Also inspect the element that doesn't take the Roboto font to see what is overwriting it.
Hope it helps

Inlining fonts and images inside CSS files with Webpack5?

I need to import into my project some CSS files with Webpack 5 and I need to inline all these resources (it's a requirement sadly). Inside the CSS there are some fonts and images with relative URI, like this:
#font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Regular.ttf) format("truetype"); font-weight: normal;}
#font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Bold.ttf) format("truetype"); font-weight: bold;}
#font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Italic.ttf) format("truetype"); font-weight: normal; font-style: italic;}
#font-face { font-family: "MyFont"; src: url(./fonts/Roboto-BoldItalic.ttf) format("truetype"); font-weight: bold; font-style: italic;}
#font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(./fonts/material-icons.woff2) format('woff2'); }
#font-face { font-family: 'Material Icons Outlined'; font-style: normal; font-weight: 400; src: url(./fonts/material-icons-outlined.woff2) format('woff2'); }
* { font-family: "MyFont", "Roboto-Light", "Noto Sans CJK SC", "DejaVu Sans"; }
.UICheckbox { width:80px; height:89px; background-image:url("img/checkboxOFF.png"); background-repeat:no-repeat; }
.UICheckbox.checked { background-image:url("img/checkboxON.png"); }
Since I need to import as base64 the CSS files I cannot actually process automatically the resources found inside of them (contrary to how it is done with PostCSS or similiars).
My current webpack configuration is the following but it just ignores the url() statements:
{
test: /\.(png|jpg|gif)$/i,
type: "asset/inline",
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: "asset/inline",
},
{
test: /\.css$/i,
type: "asset/inline",
},
Is there a better way to handle this?
I found a solution that is not really generic or solid but does the job, at least in my case scenario.
The imports are relatives to a fixed source path so the idea is to read the resources found inside the url() rules and process it as DataURI in base64 encoding.
I found quite useful the use of datauri which provides a way to include data in-line as if they were external resources and manages the mimetypes automatically.
npm install datauri --save
Then I had to modify the generator handler inside webpack.config.js to process the resources manually exploiting the datauri package.
const path = require("path");
const Datauri = require("datauri/sync");
const EXTERNAL_ROOT_PATH = "./src/external/dev/";
module.exports = {
...
module: {
rules: [
{
test: /\.css$/i,
type: "asset/inline",
generator: {
dataUrl: (content) => {
content = content.toString();
// Get the resource paths inside the CSS url() rules
let asset_urls = [];
let match,
regex = /url\((.*?)\)/gi;
while ((match = regex.exec(content))) {
asset_urls.push(match[1]);
}
// console.log(asset_urls);
// Convert the resource to a DataURI and replace it inside url()
asset_urls.forEach((file_path) => {
// Sanitize the file path first
sanitized_file_path = file_path.replace(/[\"\']/g, "").replace(/^(?:\.\.\/)+/, "");
const data_uri = Datauri(path.join(EXTERNAL_ROOT_PATH, sanitized_file_path));
// console.log(data_uri.content); //=> "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
// console.log(data_uri.mimetype); //=> "image/png"
// console.log(data_uri.base64); //=> "iVBORw0KGgoAAAANSUhEUgAA..."
// console.log(data_uri.buffer); //=> file buffer
content = content.replace(file_path, data_uri.content);
});
return "data:text/css;base64," + Buffer.from(content).toString("base64");
},
},
},
],
},
};

How do you define #font-face in a CSSObject?

Suppose I have the following #font-face rule(s) and I want to put them as a CSSObject instead of a flat string.
#font-face {
font-family: 'Blah';
font-weight: 400;
font-style: normal;
src:
url('./Blah-Normal.woff2') format('woff2'),
url('./Blah-Normal.woff') format('woff');
}
#font-face {
font-family: 'Blah';
font-weight: 700;
font-style: bold;
src:
url('./Blah-Bold.woff2') format('woff2'),
url('./Blah-Bold.woff') format('woff');
}
...
How can I define it as a CSSObject? I'm trying to pass it over to Mui's MuiCssBaseline and it takes a CSSObject or string. I'd like to pass a CSSObject so that I could add more CSS styling on it more easily and easier to read. But right now it is just a flat string containing only the #font-face definitions.
// import { CSSObject } from '#mui/material';
// import { CSSObject } from '#emotion/styled';
import { CSSObject } from 'styled-components';
const BlahCSSObject = {
'#font-face': {
// magic?
src: [
// it definitely don't like the following format
url('./Blah-Bold.woff2') format('woff2'),
url('./Blah-Bold.woff') format('woff')
]
},
'#font-face': { // would cause dupe keys no?
...
},
...
} as CSSObject;
Thanks!
I think you can use css method from styled-components.
import { css } from 'styled-components'
const myOwnStyle = css`
#font-face {
// styles
}
`

Unable to match font weights with google fonts and react styled components

I'm trying the following style below. The issue is the actual result font-weight is no where close to the mock-up. How can I ensure I get the right style?
https://fonts.google.com/specimenTab?standard-styles#standard-styles
const LogoH1 = styled.span`
text-transform: uppercase;
font-family: 'Montserrat';
font-size: 50px;
font-weight: 900;
letter-spacing: -5px;
`
Design Tool (Adobe XD)
Result
I'm using Gatsby to connect the fonts:
plugins: [
{
resolve: `gatsby-plugin-google-fonts`,
options: {
fonts: [
`Montserrat`,
],
}
}
],
plugins: [
{
resolve: `gatsby-plugin-google-fonts`,
options: {
fonts: [
`Montserrat\:400,500,600,700,800,900`,
],
}
}],

Loading fonts with webpack

I'm trying to use custom fonts in a Project website with angular4.
This is my Project structure
This is my webpack.config.js
const isDevBuild = !(env && env.prod);
const sharedConfig = {
stats: { modules: false },
context: __dirname,
resolve: { extensions: [ '.js', '.ts' ] },
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.ts$/, include: /ClientApp/, use: ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
// Font Definitions
{ test: /\.svg$/, loader: 'url?limit=65000&mimetype=image/svg+xml&name=font/[name].[ext]' },
{ test: /\.woff$/, loader: 'url?limit=65000&mimetype=application/font-woff&name=font/[name].[ext]' },
{ test: /\.woff2$/, loader: 'url?limit=65000&mimetype=application/font-woff2&name=font/[name].[ext]' },
{ test: /\.[ot]tf$/, loader: 'url?limit=65000&mimetype=application/octet-stream&name=font/[name].[ext]' },
{ test: /\.eot$/, loader: 'url?limit=65000&mimetype=application/vnd.ms-fontobject&name=font/[name].[ext]' }
]
},
plugins: [new CheckerPlugin()]
};
This is my css with #font-face
#font-face {
font-family: "FuturaMaxiLight";
src: url('/fonts/FuturaMaxi/Futura-Maxi-Light.eot') format('embedded-opentype'), /*for IE */
url('/fonts/FuturaMaxi/Futura-Maxi-Light.ttf') format('truetype'), /* for CSS3 browsers */
url('/fonts/FuturaMaxi/Futura-Maxi-Light.woff') format('woff');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: "FuturaMaxiDemi";
src: url('/fonts/FuturaMaxi/Futura-Maxi-Demi.eot') format('embedded-opentype'), /*for IE */
url('/fonts/FuturaMaxi/Futura-Maxi-Demi.ttf') format('truetype'), /* for CSS3 browsers */
url('/fonts/FuturaMaxi/Futura-Maxi-Demi.woff') format('woff');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: "FuturaMaxiBold";
src: url('/fonts/FuturaMaxi/Futura-Maxi-Bold.eot') format('embedded-opentype'), /*for IE */
url('/fonts/FuturaMaxi/Futura-Maxi-Bold.ttf') format('truetype'), /* for CSS3 browsers */
url('/fonts/FuturaMaxi/Futura-Maxi-Bold.woff') format('woff');
font-weight: normal;
font-style: normal;
}
This is the error when I try like that
If I change the css and try to include a dot before the import.
1 dot gives errors.
2 dots breaks the app.
#font-face {
font-family: "FuturaMaxiBold";
src: url('./fonts/FuturaMaxi/Futura-Maxi-Bold.eot') format('embedded-opentype'), /*for IE */
url('./fonts/FuturaMaxi/Futura-Maxi-Bold.ttf') format('truetype'), /* for CSS3 browsers */
url('./fonts/FuturaMaxi/Futura-Maxi-Bold.woff') format('woff');
font-weight: normal;
font-style: normal;
}
Your loaders are specifying name=font/[name].[ext] and your css is looking at /fonts/FuturaMaxi/[name].[ext].
Try changing the loaders to use name=[path][name].[ext] or name=fonts/FuturaMaxi/[name].[ext]
You need resolve-url-loader to resolve the correct path in your build.
See https://github.com/bholloway/resolve-url-loader
Install resolve-url-loader
npm install --save-dev resolve-url-loader
Modify your Webpack CSS rule:
{
test: /\.css$/,
use: [
'to-string-loader',
isDevBuild ? 'css-loader' : 'css-loader?minimize',
'resolve-url-loader' // Add this
]
}
Use relative paths in your CSS files
#font-face {
font-family: "FuturaMaxiLight";
src: url('../fonts/FuturaMaxi/Futura-Maxi-Light.eot') format('embedded-opentype'), /*for IE */
url('../fonts/FuturaMaxi/Futura-Maxi-Light.ttf') format('truetype'), /* for CSS3 browsers */
url('../fonts/FuturaMaxi/Futura-Maxi-Light.woff') format('woff');
font-weight: normal;
font-style: normal;
}

Resources