Fonts not found with nested routes in react-router
Asked Answered
I

3

7

I'm using React, React-Router and Webpack (with webpack-dev-server) and I'm having trouble loading custom fonts on nested routes.

Everything works fine on my shallow routes like /user, /group, etc., but when I have a nested route like /group/user, the custom fonts don't get loaded (404 error).

The Webpack build puts all the fonts in the root level as expected (with filenames like 7f690e503a254e0b8349aec0177e07aa.ttf), and when showing a route like /user, the fonts are loaded properly.

However, when in a nested route like /group/user, the browser tries to load the fonts from a URL like /group/7f690e503a254e0b8349aec0177e07aa.ttf, which doesn't exist.

I think that somewhere the font is assumed to be a relative path, but I don't know where.

How can I make the font paths be absolute paths rather than relative? Or is there another way to fix this?

Not sure if it matters, but I've defined my fonts as shown below in my styles.less file:

// Main font(s)
@font-face {
  font-family: 'Lato-Regular';
  src: url('../fonts/Lato-Regular.ttf') format('truetype');
}
Idle answered 29/12, 2015 at 0:38 Comment(0)
T
8

In this case a possible solution is to add the base element to your pages. The base element allows you to specify a base URL to be used throughout the document for relative URL addresses. For example setting:

<base href="http://www.youdomain.com/">

then you know that all relative paths should be relative to the root of your domain.

Twilley answered 29/12, 2015 at 1:16 Comment(2)
Thanks! I added <base href="/"> to my index.html and now the fonts are loaded as expected! This is definitely not something I knew and forgot. I didn't know that <base> even existed.Idle
I'd still like to know where the relative URL is coming from though.Idle
M
3

I had the same problem using webpack and react router 4. I solved it by switching from file-loader to url-loader in webpack.config.json.

Working Module - Loader:

{ test: /\.(otf|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'url-loader?name=./Scripts/dist/[name].[ext]' }
Mingy answered 16/10, 2017 at 11:6 Comment(0)
M
0

As you are using less, the most practical way for you to fix it would be configuring base paths, so that the code generation would produce an absolute path according to your configuration.

Please check the less documentation here: http://lesscss.org/usage/.

Metachromatism answered 29/12, 2015 at 0:45 Comment(2)
Thanks, but I'm pretty sure that it's not less causing the problem here. Webpack transforms the fonts and stores them all at the root under new names. It's on the browser side somewhere that it's deciding to lookup the font relative to the current nested route URL.Idle
You should check the actual generated CSS file - because browser doesn't load "*.less" JavaScript, it loads what the packer generated for it. You got relative path in your output CSS, for sure.Metachromatism

© 2022 - 2024 — McMap. All rights reserved.