.htaccess Deprecation and Alternatives
WP Engine does not support the .htaccess file and has deprecated it in order to increase website performance and to match industry trends. If your site used custom .htaccess directives outside of the default WordPress rules (such as redirects, headers, or access rules) they can be converted using the guidance provided in this article.
This article includes overviews of alternatives for common .htaccess directives, including explanations of what each directive does, links to more information on the web, and examples of how to implement each rule type by alternative.
What is the .htaccess file and why was it deprecated?
PHP servers are used to execute the code that WordPress runs on. The .htaccess is a PHP configuration file that a web admin can use to tell the server how to interact with a website. It can control any number of things on a site-by-site basis, like how your URLs are formed or restricting access to a directory.
The .htaccess file has performance implications on sites leveraging an Apache backend server. As .htaccess files are read recursively, this can lead to file system reads on every page load on your site. On smaller sites this doesn’t lead to a big impact, but as the number of directories on a site gets larger, there is an impact those file system crawls have on performance. You can read more about the recommendations around this in “When (not) to use .htaccess files” from Apache.org.
Most importantly, .htaccess files tie our architecture to Apache as a backend web server. As new exciting technologies arise, and open up new features and performance we’d like to make available to our customers, it becomes paramount to break that dependency as we evolve as a Digital Experience Platform. We’re incredibly excited at the evolution, and the velocity we’ll be able to deliver as part of this change in the future.
We recognize the overhead this will have on our customers as they prepare for upgrades. We believe it’s in the best interest of our customers to deprecate and remove .htaccess support going forward. We’ve been committed to smoothing out the transition period, and have made platform changes as we’ve encountered challenges. If you’re in a situation where you don’t know the best course of action, or believe that the .htaccess is the only manner in which to accomplish your goals, please do not hesitate to reach out to our Support team. They’ll be able to help ease this transition, and raise issues to our development teams to address the shortcomings this deprecation creates.
While our data suggests only a small amount of customers leverage the .htaccess feature, we recognize that there are those that have relied on this functionality. We’re committed to continually smoothing this transition, and will be more than happy to assist with recommendations and alternatives. We suggest reviewing our list of alternatives below and testing any changes on a Staging or Development environment first.
While our Support team does not support PHP or code development, if you have any questions or concerns about this change, please reach out to our Support team at any time.
Default WordPress .htaccess Directives
By our analysis, most WP Engine websites will not need to make any changes as they are using a default WordPress version of the .htaccess. Default WordPress rewrites will be handled by WP Engine automatically at the server level.
If your .htaccess file contains only default content, no changes need to be made. You can find the default .htaccess files used for WordPress here.
If your .htaccess file contains content beyond the default WordPress state, see the alternatives below.
Directive Alternatives Overview
If your site is using .htaccess directives outside of the default WordPress rules (above), we have put together a list of recommended alternatives.
Directive | Purpose | Alternative |
---|---|---|
Deny from all | Restrict access |
|
Allow from all | Allow access |
|
Rewrites | Forces redirects and rewrites |
|
SetHandler | Specifies how to handle certain file types |
|
Option-indexIgnore* | Prevent directory browsing |
|
mod_ Headers | Header tweaking |
|
AddType | Adds MIME type support for app type |
|
Caching | Sets cache expirations |
|
Security | Disable PHP processing in plugin(s). |
|
Access Rules
Managing access rules can be done from your User Portal as an alternative to placing these rules in the .htaccess. All websites on WP Engine automatically have this Web Rules page enabled. Learn more about managing web rules here.
Below are examples of how to translate the following .htaccess directives into Access Rules.
- rewrite_deny
- Rewrite with status code 403 by creating a DENY access web rule.
- satisfy
- This directive is only used when a particular area of your site is restricted by a combination of client IP address and user/password authentication.
- Password protection for WordPress paths can be done via plugins instead.
- Protection for all paths (served by NGINX) is not yet supported.
Redirects and Rewrites
If your site had redirect rules in the .htaccess, they should be relocated in order to remain both functional and optimized. It is always recommended to consolidate as many rules as possible using RegEx regardless of the number of redirects needed or how they are applied.
Fewer Than 1000 Redirects
- Redirects can be added to WP Engine’s Nginx configuration
- Add redirects through the User Portal
- Bulk import redirects by contacting WP Engine Support
- Add redirects rules to the Redirection plugin
- Manage redirects in Yoast SEO Premium‘s redirect manager
More Than 1000 Redirects
- Importing redirects into the WP Engine Nginx configuration will not be efficient at this quantity, due to bloating and overhead.
- We suggest loading redirects into the Redirection plugin or, if you’re using Yoast SEO, manage redirects in Yoast Premium
Bulk Migrate Redirects from the .htaccess
All of the recommended redirect alternatives allow the bulk import of Apache (.htaccess-formatted) redirects. This means importing existing redirects from the .htaccess can be done quickly and easily, and does not require redirects be moved one at a time. Simply copy the rules from your .htaccess file, then import using the guide:
- Bulk import redirects to the WP Engine Nginx configuration
- Bulk import redirects to Redirection plugin
- Bulk import redirects to Yoast Premium redirect manager
Rewrite Rules
Redirects and rewrites can be added to your WP Engine configuration using either Redirect Rules or Rewrite Rules. Below are examples of alternatives when using the Web Rules Rewrite Rules.
- redirect
- https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirectmatch
- Can be added as a Redirect Rule or a Rewrite Rule
- rewritebase_not_root
- https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
- The Web Rules Engine does not have the concept of a document root, so you’ll need to add the new “base” in the destination RegEx URL. For example:
- Action: internal
- Source: ^/index\.html
- Destination: /myapp/welcome.html
- rewrite_arbitrary_status
- Not Supported.
- rewrite_cond_existing
- https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond In the .htaccess this may appear as:
- RewriteEngine On
- RewriteCond %{HTTP_USER_AGENT} “=ROBOT-UA” [OR]
- RewriteCond %{HTTP_USER_AGENT} “=EVIL-ROBOT-UA”
- RewriteRule “^/index\.html$” “bot.html”
- Note the presence of the
[OR]
. Web Rule Conditionals are AND’ed together, so in order to replicate this you will need to duplicate the rule 2 times, each with the respective condition. Converted to a Rewrite Rule this may look like the following example:
- Rule 1:
- Action: internal
- Source: ^/index.html
- Destination: bot.html
- Conditions:
- Type: Header
- Operator: Equals (=)
- Name: User-Agent
- Value: ROBOT-UA
- Rule 2:
- Action: internal
- Source: ^/index.html
- Destination: bot.html
- Conditions:
- Type: Header
- Operator: Equals (=)
- Name: User-Agent
- Value: EVIL-ROBOT-UA
- https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond In the .htaccess this may appear as:
- rewrite_cond_notexisting
- https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
- ENV, REMOTE_ADDR, HTTPS, REQUEST_SCHEME, etc.
- Not supported.
- rewrite_missing
- Not Supported.
- rewrite_not_index
- Converted to a Rewrite Rule this may look like the following example:
- Action: internal
- Source: ^/index.php
- Destination: /blah.php
- Converted to a Rewrite Rule this may look like the following example:
- rewrite_redirect
- https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
- This rule the RewriteRule directive to perform a 3xx redirect. In the .htaccess it may appear as:
- RewriteRule (.*) https://www.example.com/$1 [R=301,L]
- The presence of the
L
flag in this case means this should be the first rewrite rule if there are multiple rewrite rules. As a Rewrite Rule this may appear as:- Action: permanent
- Source: (.*)
- Destination: https://www.example.com/$1
WordPress Features
Below are examples of how to translate the following .htaccess directives using WordPress features.
- browsermatch
- https://httpd.apache.org/docs/current/mod/mod_setenvif.html#browsermatch
- Implement a check in PHP around the User-Agent Header ($_SERVER[‘HTTP_USER_AGENT’]) and set an env if it matches.
- env
- Can access through $_ENV
- php_flag / php_value
- Certain php config values can be changed at runtime using the ini_set() function. Reference: https://www.php.net/manual/en/configuration.changes.modes.php
- requestheader
- https://httpd.apache.org/docs/current/mod/mod_headers.html#requestheader
- Instead, use the WordPress send_headers hook.
- Get and modify request headers with PHP ($_SERVER[‘HTTP_MY_HEADER’])
- setenv
- https://httpd.apache.org/docs/2.4/mod/mod_env.html#setenv
- Can be done in wp-config.php using define or through $_ENV
WP Engine Platform Features
Below are examples of how to translate the following .htaccess directives into existing WP Engine Platform features.
- errordocument
- require
- https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require
- This is used for access control, typically for basic authentication, when combined with .htaccess directives like:
- AuthType Basic
- AuthName “Restricted Area”
- AuthUserFile /path/to/.htpasswd
- Require valid-user
- The Password Protection Feature can be used when controlling access to the entire site.
- The below .htaccess rule is similar to a Deny All rule, which could be created in the Web Rules Engine instead.
- Require all denied
- Typically used in conjunction with:
- <IfModule mod_authz_core.c>
- Require all denied
- </IfModule>
- In an .htaccess file in a directory like /wp-content/uploads/dlm_uploads/.htaccess to deny all access to that directory.
- Password protecting specific directories or URLs is not supported.
NEXT STEP: Learn how to test and upgrade to a new PHP version