Jacki
Jacki

Reputation: 672

React load fonts dynamically from the backend

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

Upvotes: 1

Views: 4299

Answers (1)

Zirek
Zirek

Reputation: 523

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';
`

Upvotes: 2

Related Questions