This tutorial shows an example of how a .htaccess file should look like when you need to enable GZip, allow using CDN with webfonts, and set custom expiry headers. You can also check out the magnificent .htaccess file included with HTML5 BoilerPlate.

Important Note

This should all be at the very top of your .htaccess file. If you already have the lines listed under Section 1, you need to remove them.

The .htaccess file can also be used to define a list of “cacheable items” For example, set anything that is not png, jpg, gif, css, js to “no cache”. This way, if you ever serve your full domain through CDN, only certain files will be cached. Please note that using a full domain (www.domain.com) as a CDN url is only available to Enterprise/Contract clients.

############################################################################################
#Section 1
RewriteEngine On
IndexIgnore *
Options +FollowSymLinks -Multiviews -Indexes
############################################################################################
# ----------------------------------------------------------------------
# CORS-enabled images (@crossorigin)
# ----------------------------------------------------------------------
# Send CORS headers if browsers request them; enabled by default for images.
# developer.mozilla.org/en/CORS_Enabled_Image
# blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
# hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
# wiki.mozilla.org/Security/Reviews/crossoriginAttribute
<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    # mod_headers, y u no match by Content-Type?!
    <FilesMatch "\.(gif|png|jpe?g|svg|svgz|ico|webp)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS
    </FilesMatch>
  </IfModule>
</IfModule>
# ----------------------------------------------------------------------
# Webfont access
# ----------------------------------------------------------------------
# Allow access from all domains for webfonts.
# Alternatively you could only whitelist your
# subdomains like "subdomain.example.com".
<IfModule mod_headers.c>
  <FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css|css)$">
    Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>
############################################################################################
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
############################################################################################
# Deflate files to fasten the loading
<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
    AddOutputFilterByType DEFLATE application/x-httpd-php text/html text/xml text/plain text/css text/javascript application/javascript application/x-javascript image/jpeg image/jpg image/png image/gif font/ttf font/eot font/otf
</IfModule>
<IfModule mod_headers.c>
    # properly handle requests coming from behind proxies
    Header append Vary User-Agent
</IfModule>
<IfModule mod_deflate.c>
    # Properly handle old browsers that do not support compression
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    # Explicitly exclude binary files from compression just in case
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|pdf|swf|ico|zip|ttf|eot|svg)$ no-gzip
</IfModule>
############################################################################################
# Protect .htaccess
<Files .htaccess>
        order allow,deny
        deny from all
</Files>
############################################################################################
# Header Expiry
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|webp|swf)(\.gz)?(\?.*)?$">
        Header set Expires "Thu, 23 Aug 2222 00:00:00 GMT"
        Header unset ETag
        FileETag None
</FilesMatch>
###########################################################################################
  • Lee Booker

    If I wanted to not serve one file from MAXCDN, how would I do this?

  • Ivan Dabic

    Hi Lee!
    I assume that your plan is to isolate some resources and never ask them from MaxCDN at all. If that is the case, you need to reject that particular file to be rewritten on your end (Origin side). Since there are quite a few scenarios how you can use CDN with, I will focus on the case with plugin used to implement CDN.
    Your plugin has the main logic for CDN implementation and, therefore, that is the place where you can dictate what goes from CDN and what won’t. For example, W3TC plugin for WordPress sites has an option called “Rejected files list” where you enter file path you don’t want to pull from CDN. WP Super Cache and CDN linker have an option called “Exclude if substring” where any substring of a file in question can be used as matching sequence to remove a file from being pulled through CDN.

    Feel free to send us an email to support@maxcdn.com if you had any further questions or concerns.

  • http://twelvetwo.net/ Clay Asbury

    Surely, there must be a way to centrally deny or prevent certain file types from being
    cached from within MaxCDN zone settings. Fiddling with each site’s
    .htaccess, W3 Total Cache CDN settings, listing paths and adding
    wildcards is a consistent waste of time – and ALWAYS unique to each
    site.

    • Ivan Dabic

      Hi Clay,

      For sure. However, it would require a paid feature called EdgeRules where you can define caching rules on granular basis. Now, depending on the scenario (and I’ve seen MANY) it can be more suitable to use htaccess or Edge Rules and it’s all completely arbitrary because, not all use cases a re the same.
      To answer your question short, you can prevent caching of some files on CDN using Edge Rules but, if you are able to manipulate all of your WP (or other) installations it is a better way to do it because, the plugin that implements CDN on a site contains the main logic of CDN implementation. You can decide not to pull certain files from CDN or to add new files manually. Whereas, if you decide to use Edge Rules, you are still trying to use CDN but, we are preventing the caching of those.
      If you should have any further questions or concerns we can carry the discussion via support@maxcdn.com.

      • http://twelvetwo.net/ Clay Asbury

        Thanks, Ivan. I chatted yesterday with Sanja on your support team and was able to get it resolved. Since my server is using nginx, I had to add a directive to server from within Plesk. I wrote up a brief blog post about it here: http://twelvetwo.net/troubleshooting-caching-web-icon-fonts-maxcdn/

        You guys are awesome. Thanks for a great product and a great support team!

        • Ivan Dabic

          Hey Clay,

          That is awesome 🙂 Love to hear that. Will go through your blog asap and, you can let us know if there is anything else we can do for you,

          Best!