onedesign / generator-one-base

A foundation for One Design Company projects on the web.
Other
1 stars 1 forks source link

Default htaccess #59

Closed cmalven closed 7 years ago

cmalven commented 7 years ago

Maybe we should consider adding a more robust default htaccess file, at least for Craft sites. Something like the following should be pretty typical:

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Force https
  RewriteCond %{HTTP:X-Forwarded-Proto} !=https
  RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

  # Send would-be 404 requests to Craft
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
  RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

# ----------------------------------------------------------------------
# | Expires headers                                                    |
# ----------------------------------------------------------------------

# Serve resources with far-future expires headers.
#
# (!) If you don't control versioning with filename-based
# cache busting, you should consider lowering the cache times
# to something like one week.
#
# https://httpd.apache.org/docs/current/mod/mod_expires.html

<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 week"

  # CSS

    ExpiresByType text/css                              "access plus 1 month"

  # Favicon (cannot be renamed!) and cursor images

    ExpiresByType image/vnd.microsoft.icon              "access plus 1 week"
    ExpiresByType image/x-icon                          "access plus 1 week"

  # HTML

    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript

    ExpiresByType application/javascript                "access plus 1 month"
    ExpiresByType application/x-javascript              "access plus 1 month"
    ExpiresByType text/javascript                       "access plus 1 month"

  # Media files

    ExpiresByType audio/ogg                             "access plus 1 day"
    ExpiresByType image/bmp                             "access plus 1 day"
    ExpiresByType image/gif                             "access plus 1 day"
    ExpiresByType image/jpeg                            "access plus 1 day"
    ExpiresByType image/png                             "access plus 1 day"
    ExpiresByType image/svg+xml                         "access plus 1 day"
    ExpiresByType image/webp                            "access plus 1 day"
    ExpiresByType video/mp4                             "access plus 1 day"
    ExpiresByType video/ogg                             "access plus 1 day"
    ExpiresByType video/webm                            "access plus 1 day"

  # Web fonts

    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType font/eot                              "access plus 1 month"

    # OpenType
    ExpiresByType font/opentype                         "access plus 1 month"

    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 month"

    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/x-font-woff               "access plus 1 month"
    ExpiresByType font/woff                             "access plus 1 month"

    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 month"

</IfModule>

Might also want to consider force redirecting foo.com to www.foo.com (or vice versa)

brianjhanson commented 7 years ago

I would vote to keep the http -> https out of this or behind a conditional. I can see that tripping up some local development environments or potentially going unnoticed until the wrong time.

cmalven commented 7 years ago

I wouldn't even have a problem with including it but commenting it out. I think the goal here should mostly be that all "best practices" are in here from the start, so when it comes time to launch the site there's no question of what needs to happen in this file.

brianjhanson commented 7 years ago

I'm cool with that. We should also add a note (where is a harder question) about how this won't work with nginx, and which modules it requires (I think it's just rewrite and expires). Rewrite is required by Craft so we're probably good there, but expires isn't

mkornatz commented 7 years ago

I've added a few things to this:

  1. Install instructions
  2. Extended asset caching to 1 year (all assets should be versioned properly via URLs)
  3. Added some sample HTTPS rules
  4. Added some sample rewrite rules
  5. Sets $_SERVER['HTTPS'] PHP var when behind a load balancer
# Apache htacess file for Craft
# 
# Installation:
# 1. Enable mod_rewrite and mod_expires in Apache (`> a2enmod mod_rewrite && a2enmod mod_expires`)
# 2. Customize the domain names in rewrite rules as necessary 
# 3. Uncomment the rewrite rules you need enabled
# 4. Be sure that all assets are versioned properly. Browsers will cache assets for long periods

# ----------------------------------------------------------------------
# | Rewrite Rules - requires `mod_rewrite` to be enabled               |
# ----------------------------------------------------------------------
<IfModule mod_rewrite.c>
  RewriteEngine On

  # This will set the environment variable HTTPS to "on"
  # if the request is behind a load balancer which terminates SSL.
  # In PHP, you can access this via $_SERVER['HTTPS']
  SetEnvIf X-Forwarded-Proto https HTTPS=on

  # Force redirect to HTTPS
  # RewriteCond %{HTTP:X-Forwarded-Proto} !https
  # RewriteCond %{HTTPS} off
  # RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

  # Redirect non-www to www
  # RewriteCond %{HTTP_HOST} !^www.example.com [NC]
  # RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301,NC]

  # Redirect www to non-www
  # RewriteCond %{HTTP_HOST} ^www.example.com [NC]
  # RewriteRule ^(.*)$ https://example.com/$1 [L,R=301,NC]

  ###############################
  # Start: Specific URL Rewrites
  ###############################

  # Redirect 301 /my/path/to/doc.pdf https://s3.amazonaws.com/new/path/to/doc.pdf

  # RewriteCond %{REQUEST_URI} ^\/press\/releases\/.*\.aspx
  # RewriteRule (.+) /press/releases [L]

  #############################
  # End: Specific URL Rewrites
  #############################

  # Send would-be 404 requests to Craft
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
  RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

# ----------------------------------------------------------------------
# | Expires headers - requires `mod_expires` to be enabled             |
# ----------------------------------------------------------------------

# Serve resources with far-future expires headers.
#
# (!) If you don't control versioning with filename-based
# cache busting, you should consider lowering the cache times
# to something like one week.
#
# https://httpd.apache.org/docs/current/mod/mod_expires.html

<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS

    ExpiresByType text/css                              "access plus 1 year"

  # Favicon (cannot be renamed!) and cursor images

    ExpiresByType image/vnd.microsoft.icon              "access plus 1 week"
    ExpiresByType image/x-icon                          "access plus 1 week"

  # HTML

    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript

    ExpiresByType application/javascript                "access plus 1 year"
    ExpiresByType application/x-javascript              "access plus 1 year"
    ExpiresByType text/javascript                       "access plus 1 year"

  # Media files

    ExpiresByType audio/ogg                             "access plus 1 year"
    ExpiresByType image/bmp                             "access plus 1 year"
    ExpiresByType image/gif                             "access plus 1 year"
    ExpiresByType image/jpeg                            "access plus 1 year"
    ExpiresByType image/png                             "access plus 1 year"
    ExpiresByType image/svg+xml                         "access plus 1 year"
    ExpiresByType image/webp                            "access plus 1 year"
    ExpiresByType video/mp4                             "access plus 1 year"
    ExpiresByType video/ogg                             "access plus 1 year"
    ExpiresByType video/webm                            "access plus 1 year"

  # Web fonts

    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 year"
    ExpiresByType font/eot                              "access plus 1 year"

    # OpenType
    ExpiresByType font/opentype                         "access plus 1 year"

    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 year"

    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 year"
    ExpiresByType application/x-font-woff               "access plus 1 year"
    ExpiresByType font/woff                             "access plus 1 year"

    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 year"
</IfModule>
cmalven commented 7 years ago

One more thing that should be addressed here, and is possibly a good candidate for taking a hard position on that we stick with: www.foo.com or just foo.com? Most sites should probably pick one and redirect everything else, so this would be a good thing to bake into this if we can agree on what it should be.

mkornatz commented 7 years ago

@cmalven, I think that should be decided on a per-project basis. In my experience, clients often have a strong opinion about it. I included rules for both above, but commented them out.