Custom component with custom fonts

I am trying to create a custom component that loads custom fonts. If I load the fonts via the Dash app itself, i.e. add the necessary .css files with @font-face definitions and font files, it works. However, if I move the font definition CSS and the font file to a custom component, it no longer works. Has anyone tried to do something similar? Did you get it to work? How?

If I use fonts available online and use a link in the font definition (rather than bundling the font with the app/component), everything works just fint.

Hello @Emil,

I have something where I add a custom set of css files.

Are you importing directly into the component? I ended up importing it into the index.js, and made sure it was at the same level as the index.js.

1 Like

I tried both directly into the component, and via the index.css approach. In both cases, I am able to get the .css working (e.g. changing font color), but not the fonts.

I guess the problem lies somewhere in the url mapping and/or how the font files are served.

Does it give any import errors in the console?

I ran into issues when trying to dynamically import packages.

Have you looked here:

Here looks promising:


It looks like the main thing is to not just import into the index.css but also import the fonts themselves into the index.js.

I dont’ see any errors on the console. I can also see from the files generated, that the font files are getting bundled with the Python code,

image

Yes, those were actually some of the guides that I consulted to get started. For the 3-way links I can’t use approaches 1&2, as the fonts are proprietary, so I am using approach 3.

@Emil,

Just to confirm, you are importing a .ttf file?

I’m asking because I’ll take a look at and see if I can get something to work using it the same way.

Also, are you using the cookie-cutter dash component?

I am using .woff files, but I wouldn’t expect the fileformat to matter. I have started from the TypeScript template. Besides this issue, it’s a great template. I am already considering to rewrite dash-leaflet with it - but that would take me some time…

1 Like

Who has time to reinvent the wheel. Haha.

I’ll have to check it out.

I got it!

OMG… Haha :stuck_out_tongue:

^^ This helped

structure:
image

index.css:

@font-face{
    font-family: Comfortaa;
    src: local('Comfortaa'),
    url(../assets/fonts/comfortaa-normal-normal.ttf) format('truetype');
    font-weight: normal;
}

@font-face{
    font-family: Comfortaa;
    src: local('Comfortaa'),
    url(../assets/fonts/comfortaa-bold-normal.ttf) format('truetype');
    font-weight: bold;
}

.testing {
    font-family: Comfortaa;
    font-size: 25px;
}

index.js:

import '../assets/fonts/comfortaa-normal-normal.ttf';
import '../assets/fonts/comfortaa-bold-normal.ttf';

index.ts:

import Testing from './components/Testing';
import './components/index.css';
import './components/index.js';

export {
    Testing
}

additional module rules in webpack.config.js (additional npm npm install file-loader --save-dev):

{
                    test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
                    use: [
                      {
                        loader: 'file-loader',
                        options: {
                          name: '[name].[ext]',
                          outputPath: 'fonts/'
                        }
                      }
                    ]
                  }

usage.py:

import testing
import dash
from dash import html

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        testing.Testing(id='component', children='testing-font', className='testing'),
        testing.Testing(id='component_two', children='testing-no-font')
    ]
)


if __name__ == '__main__':
    app.run_server(debug=True, port=1234)

result:
image

Awesome! Could you provide a link to the repo where you got it working?

Sure, here you go:

I know, I messed up with the cookie-cutter, haha. XD

1 Like

Haha, yes, it looks like something went wrong with the cookie cutter :laughing:. I tried cloning your repo, setting up the Python env, installing packages via npm, and running the example. However, it doesn’t seem to work for me,

Do you have an assets folder with the assets next to your app.py file?

Nope, its under the ts folder.

Strange that it doesn’t work on my system. And you don’t get any console errors?

Wait… it might be because I have it downloaded on my computer… but I wouldnt think that would be the case because it wasnt working before hand…

Let me try with maybe a random font…

That might be. I can see you includedsrc: local('Comfortaa') in the font definition, I think that will cause a load from your local system, if the font exists. Could you try without that part (and/or try with another font)?

Yeah… no go. :frowning:

Even then, it still looks like it’s trying to load from a path that is externally viewable.

So, not entirely sure what the benefits of trying to get it working this way is.

@Emil,

So, I got somewhere, I’m thinking you need to add the routing in the _init_.py for the path that is trying to load. Since this doesn’t happen automatically.

I could get it to show the path was working, but was getting an error for it not being able to decode the downloaded font. Which means that the font was transmitted in a format that was unexpected or the file wasn’t loaded at all and I just made the path work. Haha.