React load fonts dynamically from the backend - css

I want to be able to choose font I wish to download from backend via select and then use it in my project. User can change fonts and download new ones. I have problem that if font is fixed in my css like this:
export const MainContent = styled.div`
#font-face {
font-family: 'Lobster';
src: local('Font Name'), local('FontName'),
url ('http://localhost/font/lobster') format('woff');
font-weight: bold;
font-style: normal;
font-display: swap;
};
font-family: 'Lobster';
`;
It is downloaded properly right after app starts and I can use it, however I don't want to have it fixed, tried few solutions so far like with WebFont:
import WebFont from 'webfontloader';
function App() {
enter code here
WebFont.load({
custom: {
families: ['Lobster'],
urls: ['http://localhost/font/${fontname'] <= used fixed lobster in this case
}
});
...
}
But it throws error like =
The resource from “http://localhost/font/lobster” was blocked due to MIME type (“font/ttf”) mismatch (X-Content-Type-Options: nosniff).
another idea was to send parameter which could replace for example lobster via props of styled component like
<MainContent fontName="lobsterTheSecond">
...
</MainContent>
However I don't really know how to pass props in #font-face as it keeps throwing errors.
Does anyone knows how can I add fonts dynamically from backend while app works? I'm out of ideas already

Not sure about WebFont but it can be done quite easy with styled components:
First of all don't pass it to your 'MainContent' but rather pass props with new font to your globalStyles and then do something like that:
const GlobalStyle = createGlobalStyle`
body {
#font-face {
font-family: 'Lobster';
src: `${props =>
url ('http://localhost/font/${props.fontName}')` format('woff');
font-weight: bold;
font-style: normal;
font-display: swap;
};
}
`
and pass it like:
function App() {
const [newFont, setNewFont] = useState('');
return (
<div>
<GlobalStyle fontName{newFont} />
<button onClick={() => setNewFont('myNewFont')>Click</button>
</div>
)
}
and then in your MainContent just use this font:
const MainContent = styled.div`
font-family: 'Lobster';
`

Related

How to load cutom fonts such as 'Tondo' using WbfontLoader?

I need to load fonts (.eot,.ttf etc) on demand as per the requirement.
WebFont.load({
custom: {
families: ['Font1'],
urls: ['css-path']
}
});
I am unable to do it using above approach.
One of the solution i found out to create style element and add the #font-face like this -
const cssStr = `
#font-face {
font-family: Tondo;
src: url(../static-assets/common/fonts/tondo/tondo-light-webfont.eot);
}`
const style = document.createElement('style');
style.innerHTML = cssStr;
document.head.appendChild( style );
Is there any better way to do it?

Custom font not loading in react direflow application

I have created a javascript direflow application. I am trying to load a local font but haven't been able to.
Below are the details and code snippets I have applied.
Folder Structure
font.css
#font-face {
font-family: 'MyLocalFont';
src: local('MyLocalFont'),
url('./fonts/MyLocalFont.woff') format('woff'),
url('./fonts/MyLocalFont.woff2') format('woff2');
}
direflow-components/testing-component/index.js
plugins: [
{
name: 'font-loader',
options: {
custom: {
families: ['MyLocalFont'],
urls: ['/fonts.css']
},
},
},
],
App.css
.header-title {
font-size: 34px;
color: #5781C2;
font-family: 'MyLocalFont';
}
The font files doesn't load. Please help.
Note: Built a react app using create-react-app there with #font-face changes the fonts load. Something with direflow is not working.
I resolved the issue seems like the plugin font-loader is not required. I removed it from direflow-components/testing-component/index.js.
Another change I made is removed the single quotes from the font-family.
App.css
.header-title {
font-family: MyLocalFont;
}

font-face are not working with rollup config - component library

I have custom component library written in React (rollup to build). I don't want to use createglobalstyle BCS its broke performance in an external project. I added CSS file with font-face (relative path) but these fonts are not working in external projects. Do u have any idea how to fix it?
src
components (folders)
index.css with
#font-face {
font-family: 'font1';
font-display: swap;
font-weight: 900;
src: url(assets/fonts/font1/heavy/heavy.woff2)
}
h1{
margin: 2.75rem 0 1.05rem;
font-family: 'font1';
font-weight: 400;
line-height: 1.15;
color:red;
}
Rollupconfig plugins :
[ postcss({
extract: false,
plugins: [autoprefixer]
}),
babel({
exclude: 'node_modules/**'
}),
localResolve(),
resolve({
browser: true
}),
commonjs(),
filesize(),
copy({
targets: [{ src: 'src/assets', dest: 'build' }]
}),
url({
// by default, rollup-plugin-url will not handle font files
include: ['**/*.woff', '**/*.woff2'],
// setting infinite limit will ensure that the files
// are always bundled with the code, not copied to /dist
limit: Infinity
}),
modulepreload({
prefix: 'fonts',
index: 'src/assets/fonts/font1/heavy/heavy.woff2',
})
];
When I use that library in external projects I see all style like color:red etc. but font-face is not working :(
I have the feeling that you just wrongly entered the source of your font.
Try something like this:
#font-face {
font-family: 'font1';
font-display: swap;
font-weight: 900;
src: url("../assets/fonts/font1/heavy/heave.woff2");
}

Ionic2 $font-family-base not working

The variable $font-family-base in Ionic2 is not working.
In the app.variable.scss file I added a new value to it, but the old value remains.
Other variables like $font-size-base is working fine
Those are my gulp tasks for building www:
gulp.task("fonts", function () {
return copyFonts({
src: [
"app/fonts/**/*.+(eot|ttf|woff|woff2|svg)"
]
});
});
gulp.task("sass", function () {
return buildSass({
sassOptions: {
includePaths: [
"node_modules/ionic-angular",
"node_modules/ionicons/dist/scss"
]
}
});
});
What am I missing?
That is my font-faces
#font-face {
font-family: "Maven Pro";
font-style: normal;
font-weight: 400;
src: local("Maven Pro"), local("Maven-Pro-Regular"), url("#{$font-path}/MavenPro-Regular.ttf") format("truetype");
}
#font-face {
font-family: "Maven Pro";
font-style: normal;
font-weight: 500;
src: local("Maven Pro Medium"), local("Maven-Pro-Medium"), url("#{$font-path}/MavenPro-Medium.ttf") format("truetype");
}
#font-face {
font-family: "Maven Pro";
font-style: normal;
font-weight: 700;
src: local("Maven Pro Bold"), local("Maven-Pro-Bold"), url("#{$font-path}/MavenPro-Bold.ttf") format("truetype");
}
#font-face {
font-family: "Maven Pro";
font-style: normal;
font-weight: 900;
src: local("Maven Pro Ultra Bold"), local("Maven-Pro-Regular-Ultra-Bold"), url("#{$font-path}/MavenPro-Black.ttf") format("truetype");
}
This font-faces are in my app.scss file which is referenced in my app.core.scss
app.core.scss:
// http://ionicframework.com/docs/v2/theming/
// App Shared Imports
// --------------------------------------------------
// These are the imports which make up the design of this app.
// By default each design mode includes these shared imports.
// App Shared Sass variables belong in app.variables.scss.
#import "../app";
#import "../users/sus/sus";
#import "../users/sus/home/home";
#import "../users/sus/subjects/german/german";
#import "../users/sus/subjects/math/math";
UPDATE:
If I do it using specific device sass variable i.e:
$font-family-md-base
$font-family-ios-base
$font-family-wp-base
Tha is a wird behavior, but I guess the $font-family-base has to be set in a specific order or file, what I still didn't figure out.
I've just asked Mike (from Ionic Team) and he told me:
$font-family-ios-base is for when it is on an ios device
And the same applies for
$font-family-md-base
and
$font-family-wp-base
But I think the key is that:
$font-family-base is when it's neither ios or md
I think this explains the behaviour you were talking about. So in your case you would need to change the value of that font in
$font-family-md-base
$font-family-ios-base
$font-family-wp-base
or any of them to make it work.

"__MSG_##extension_id__" doesn't work and webfonts don't load

I'm developing a Google Chrome Extension which is injecting a stylesheet into a specific website I defined in manifest.json.
In the stylesheet are webfonts included with #font-face and src: url("chrome-extension://__MSG_##extension_id__/assets/fonts/[...], but __MSG_##extension_id__ doesn't seem to work and webfonts like Font Awesome just end up still showing squares.
manifest.json
"manifest_version": 2,
"content_scripts": [
{
"matches": [
"http://[url].com/*"
],
"css": ["assets/css/main.css"]
}
],
"web_accessible_resources": ["assets/fonts/*", "assets/img/*"]
main.css
#font-face {
font-family: 'FontAwesome';
src: url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.eot?v=4.3.0");
src: url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.3.0") format("embedded-opentype"),
url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.woff2?v=4.3.0") format("woff2"),
url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.woff?v=4.3.0") format("woff"),
url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.ttf?v=4.3.0") format("truetype"),
url("chrome-extension://__MSG_##extension_id__/assets/fonts/fontawesome/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular") format("svg");
font-weight: normal;
font-style: normal; }
I've already tried hardcoding my Extension ID in the url and it worked on my iMac and displayed Font Awesome correctly, but when I switched to my Macbook and hardcoded the new Extension ID in, it doesn't work anymore, but I'm sure I've did nothing wrong, since I just needed to change the ID. Now I wanted to try __MSG_##extension_id__ but it also doesn't work. Another try to embed the fonts with Base64 also failed. My other webfonts are Roboto and Open Sans included the same way.
It's like the Chrome Extension can't access to the fonts.
I saw the last comment on the question, Same problem 4 years later :D.
I am sure almost everyone already finds out the solution or they have got the things done in their way. But I think this will help others as the same question is being asked again and again.
Answer
const urlFontAwesomeWebFontEot = chrome.runtime.getURL('assets/fonts/fontawesome/fontawesome-webfont.eot')
const urlFontAwesomeWebFontSvg = chrome.runtime.getURL('assets/fonts/fontawesome/fontawesome-webfont.svg')
#font-face {
font-family: 'FontAwesome';
src: url(${urlFontAwesomeWebFontEot});
src: url(${urlFontAwesomeWebFontSvg}) format("svg");
font-weight: normal;
font-style: normal; }
I just created variables for two URLs but you can create as per your requirements.
chrome.runtime.getURL API help to get resource's absolute URL pointing extension
References
Google Chrome extension relative path
https://developer.chrome.com/docs/extensions/reference/runtime/#method-getURL
I extend Dinesh's answer - there is the code that is ready to be pasted into js file:
const urlFontAwesomeWebFontEot = chrome.runtime.getURL('assets/fonts/fontawesome/fontawesome-webfont.eot')
const urlFontAwesomeWebFontSvg = chrome.runtime.getURL('assets/fonts/fontawesome/fontawesome-webfont.svg')
const newFontStyleSheet = document.createElement("style");
newFontStyleSheet.textContent = `
#font-face {
font-family: 'FontAwesome';
src: url(${urlFontAwesomeWebFontEot});
src: url(${urlFontAwesomeWebFontSvg}) format("svg");
font-weight: normal;
font-style: normal; }
`;
document.head.appendChild(newFontStyleSheet);
Just follow below steps:
Lets assume we have a font in fonts folder:
\fonts
font.woff
manifest.json
update your manifest.json with
...
"web_accessible_resources": [
"fonts/*"
],
...
in CSS file provide url chrome-extension://__MSG_##extension_id__/fonts/font.woff
If you don't provide web_accessible_resources permissions, request for font will be blocked (since manifest version 2 including ver 2).
References:
https://developer.chrome.com/docs/extensions/mv2/manifest/web_accessible_resources/
https://developer.chrome.com/docs/extensions/reference/i18n/

Resources