The admin panel's icon font refuses to load, throwing a 404 along with the full body of the font file. The result looks like this:

The request, as seen in Postman.

Broken icon font :(

I don't know nginx well, but we recently added a change to the config to categorically lock down cross-domain font usage where suddenvalleydevelopment.com is our primary domain and balboatowers.com is another one authorized to use fonts. Relevant lines:

map $http_origin $cors_permitted_domain {
    default suddenvalleydevelopment.com;
    .suddenvalleydevelopment.com $http_origin;
    .balboatowers.com $http_origin;

location ~* \.(otf|ttf|eot|woff)$ {
    add_header "Access-Control-Allow-Origin" "$cors_permitted_domain";
    add_header 'Vary' 'Origin';

I'm pretty sure this created the problem you see above, but I don't understand how and therefore how to fix it. We know that Craft stores its own font files at craft/app/resources/fonts, and not in public/admin/resources/fonts like you'd expect from the request.

How does Craft get its icon font (Craft.woff, etc.) to the browser, and why would the CORS provision interfere with that?

  • Just to verify your theory, if you remove the CORS stuff, does it work again?
    – Brad Bell
    Mar 31 '15 at 21:55
  • I'm not able to change the nginx config (and can't run the same one locally), but I did drop the files into public/admin/resources/fonts and that works. Not exactly scientific, but that's as close as I could get to isolating the problem.
    – Matt Stein
    Mar 31 '15 at 21:57
  • I've seen this before, though I don't remember when or where. Have you scoured the Google+ Community?
    – Lindsey D
    Mar 31 '15 at 21:58
  • Per Daniel Stein in this thread... "I experienced the same glitch when uploading the Craft directory in ASCII mode (using Transmit). Switching to 'auto' and re-uploading fixed the issue."
    – Lindsey D
    Mar 31 '15 at 22:01
  • I think it would be helpful if you test your domains in the location itself instead of outside like this thread demonstrates.
    – Natetronn
    Mar 31 '15 at 22:21

The request for the craft font needs to be rewritten, since the actual file is (usually) outside of the public web root. Usually, this will be handled by the location block in your nginx configuration that rewrites requests to index.php. After you added the location block that adds the CORS header, though, all requests for font files are processed by this block only (see this thread for more on location priority). nginx only processes one location block pr request, it doesn't "add them up". The best solution would probably be to make the location block for adding the CORS headers more specific, so that the regexp doesn't match the Craft fonts.

Here's an example on what I did on a previous project where the fonts were inside my /assets folder:

location ~* ^/assets/.*\.(?:eot|ttf|woff)$ {
   add_header Access-Control-Allow-Origin *;
  • Thanks for this answer! You were right, and we ended up taking a slightly different approach (adding try_files instead of excluding Craft fonts) to fix the problem.
    – Matt Stein
    Apr 3 '15 at 17:55

André was right that the font-specific location block needed adjustment, and in this case the block specifically needed help figuring out how to process font files outside the web root. Rather than adjust the rule to ignore Craft's fonts, we ended up adding try_files $uri $uri/ @rewrites; after setting the response headers...

location ~* \.(otf|ttf|eot|woff)$ {
    add_header "Access-Control-Allow-Origin" "$cors_permitted_domain";
    add_header 'Vary' 'Origin';

    try_files $uri $uri/ @rewrites;

I had lots of help getting here, but my understanding is that the location block processed the font request but wasn't properly serving Craft's control panel fonts because nginx locations need to cascade sufficiently for that to happen. As André noted, the font location block was matched for the request so it lost its ability to creatively serve assets that work fine in other location blocks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.