When implementing custom fonts via @font-face in CSS, many developers encounter two major hurdles with Nginx:
- Correct MIME type configuration for various font formats
- Cross-origin resource sharing (CORS) requirements
The first step is ensuring Nginx serves fonts with proper Content-Type headers. While you've correctly added these to mime.types:
application/x-font-ttf ttf;
font/opentype otf;
application/vnd.ms-fontobject eot;
font/x-woff woff;
Modern best practices recommend updating these for newer formats:
font/ttf ttf;
font/otf otf;
font/woff woff;
font/woff2 woff2;
application/vnd.ms-fontobject eot;
Modern browsers require CORS headers for font loading from different domains. Your initial approach was correct in principle:
location ~* \\.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
}
The error you're seeing indicates Nginx can't locate the font files. This typically happens when:
- The location block overrides the root path
- The font files are not in the expected directory
- There's a missing root directive in your server configuration
Here's a complete working solution:
server {
listen 80;
server_name static.example.com;
root /var/www/static;
location / {
try_files $uri $uri/ =404;
}
location ~* \\.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET;
expires 365d;
access_log off;
}
}
For production environments, consider these additional optimizations:
location ~* \\.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
add_header Cache-Control "public";
expires 1y;
add_header Vary Accept-Encoding;
gzip_static on;
gzip_types font/woff2;
}
After making changes, always:
- Test configuration syntax:
nginx -t
- Reload Nginx:
nginx -s reload
- Verify headers:
curl -I https://yourdomain.com/fonts/yourfont.woff2
When implementing custom fonts via @font-face in modern web applications, developers often encounter two critical server configuration requirements:
- Correct MIME types for font files
- Proper CORS headers for cross-origin loading
Here's a complete solution that addresses both requirements in Nginx:
# In your nginx.conf or site configuration
http {
include mime.types;
# Extended MIME types for fonts (add to existing mime.types or include separately)
types {
font/woff2 woff2;
font/woff woff;
font/ttf ttf;
font/otf otf;
application/vnd.ms-fontobject eot;
}
server {
listen 80;
server_name yourdomain.com;
# Font serving location with CORS headers
location ~* \.(eot|ttf|woff|woff2|otf)$ {
add_header Access-Control-Allow-Origin *;
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri $uri/ =404;
}
}
}
1. Path Resolution Errors: The error message about missing files typically indicates incorrect path configuration. Ensure your location block either:
- Specifies an absolute path with root directive
- Uses alias for custom font directories
location /fonts/ {
root /path/to/your/webroot;
# OR use alias for non-standard paths
# alias /custom/font/path/;
}
2. MIME Type Conflicts: Some systems may have conflicting MIME type definitions. Verify with:
nginx -T | grep mime.types
For production environments, consider these enhancements:
location ~* \.(eot|ttf|woff|woff2|otf)$ {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET";
add_header Access-Control-Max-Age "3600";
add_header Vary "Origin";
# Enable gzip compression for woff2
gzip_static on;
gzip_types font/woff2;
# Security headers
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
expires 1y;
access_log off;
}
Verify your setup with these commands:
# Check MIME types
curl -I https://yourdomain.com/fonts/yourfont.woff2 | grep Content-Type
# Check CORS headers
curl -I -H "Origin: http://test.com" https://yourdomain.com/fonts/yourfont.woff2 | grep Access-Control
Remember to reload Nginx after configuration changes:
sudo nginx -t && sudo systemctl reload nginx