Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a client that strongly prefers to disable .htaccess files because they like to set the Apache configurations themselves. However, they still want SEO-friendly URLs.

Is there a way to have custom permalinks with no .htaccess file? My research thus far seems to indicate this is not possible, but perhaps one of brilliant developers knows how the seemingly impossible can be possible. Thanks in advance!

share|improve this question
2  
Can you (or ask them to) modify the httpd.conf file? –  Gelatin Aug 28 '10 at 23:22
    
If it is absolutely impossible to have custom permalinks without an .htaccess file, then I'll give them their alternatives: 1) no SEO-friendly URLs or 2) SEO-friendly URLs and an htaccess file. Those are the only viable options I currently see, but if I'm incorrect, I would love to be corrected. :) –  Mike Lee Aug 28 '10 at 23:45

3 Answers 3

up vote 10 down vote accepted

Hi @Mike Lee:

To answer your question it is helpful to understand how everything works.

Apache Serves URLs that Match Files and Directories

Apache is designed to serve files explicitly matched by URL, or to serve the index.php found in a directory when the directory is explicitly matched.

But Apache Can Serve URLs Matched by Regex with mod_rewrite

If you want Apache to match URLs for where there are no real directories (the case with WordPress and pretty permalinks) then you must have some way to tell Apache how to handle URLs differently. And that's exactly what mod_rewrite was designed to allow; it gives server administrators the ability to set rules for matching URLs using regular expressions. Those rules route the result to other URLs, often including actually .PHP files and sometimes with URL parameters passed. Ultimately the rules specify that actual files get loaded.

And mod_rewrite is Configured with Either .htaccess or httpd.conf

To configure mod_rewrite you can only do it inside .htaccess or within the httpd.conf file or one of the files it includes, like potentially httpd-vhosts.conf. Actually I'm surprised if you client has the skills to control Apache that they don't know this already.

WordPress Always Uses the Same Simple .htaccess File

Moving on to what WordPress does, when you set permalinks WordPress writes the following to the .htaccess file, assuming it is writable (and in this first example assuming your website site is served from the root):

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Caveat: When Your WordPress Front Page Directory is Not Root

If your site is instead served from /blog then the .htaccess file written would look like this:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>

WordPress Routes All Non-File/Directory Matching URLs to index.php

So as you can see, the only thing WordPress uses .htaccess for is to map any URL to the domain to /index.php (or /blog/index.php in the 2nd example) except when a URL matches an actual file (such as an .jpg/.gif/.png image, a .css stylesheet, a .js script, etc.) or when it matches an actual directory (which as far as I know is not relevant in a standard WordPress install.)

In PHP WordPress Parses $_SERVER['REQUEST_URI'] To Decide What to Load

Inside its PHP code WordPress grabs the value of $_SERVER['REQUEST_URI'] which contains the full URL request sans the domain and scheme (i.e. scheme is http or https) and it then parses the value to determine what URL was requested and thus what pages it should load.

Bypassing .htaccess? Get Apache to Load Virtual URLs (but good luck with that!)

So if you want to somehow bypass .htaccess your job would be to get Apache to respond to an arbitrary URL then load WordPress and set $_SERVER['REQUEST_URI'] to be the URL path plus parameters; IOW spoofing it but in a good way. That said, I know if know of no ways that are not overly complicated to do that.

Embedding /index.php/ (Maybe?!?)

Even though *Chris_O* is correct about prepending /index.php/ to your URLs I cringe whenever I see that. It adds 10 characters to every URL making them longer and less meaningful to search engines but far worse makes them less sharable and looks cryptic to users. Sorry Chris I know you meant well, but ugh!

Create Real Directories for Every URL (Maybe?)

One way to get pretty permalinks without touching Apache would be to write a script that would generate an actual directory for every URL that you want and then store an index.php there that would load WordPress. Of course that would be huge effort for tiny benefit and it would require the server to have write access which has to be worse than using an .htaccess file.

I hate to admit but this is what I did circa 1998 with an .ASP-based website when IIS didn't support URL rewriting (and even today it's still a real PITA!) It was an ugly hack, was a pain to maintain and I hated it but the URLs sure were great for both users and for SEO!

Best Solution? Add Rewrite Rules to httpd.conf

Back to what's probably your best the solution, and @Simon Brown actually recommended it; add your rewrite rules to httpd.conf or one of the include files like httpd-vhosts.conf (which is how Apache is configured at localhost on my Mac.) Add the following directive making sure to change the directory to match the directory for your site:

<Directory "/home/example_user/public_html/">
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</Directory>

Bonus! With Lockdown Comes Performance Too

This last option should eliminate any .htaccess and put control back in their hands. Even better it's slightly more performant since httpd.conf is only loaded once when Apache starts but .htaccess files are loaded and parsed on every URL request!

P.S. One more thing to consider would be to front-end Apache with a caching server like Nginx which I believe is becoming a best practice for high-traffic WordPress sites that really need to be performant. It might take green field tweaking because I don't think most people have been using Nginx to do the URL rewriting for Apache but if that direction interests you here are some links to pursue:

share|improve this answer
    
Thank you for the extremely helpful & thorough answer, as always! The client is leaning towards modifying the httpd.conf, and that's most probably what we'll end up doing. The performance boost is a good bonus tip too! –  Mike Lee Aug 31 '10 at 18:10
    
@Mike Lee: Yes, it's always nice when you can say "You really should do it this way and, oh-by-the-way you get better performance if you do!" I find that often sways them. :) –  MikeSchinkel Aug 31 '10 at 18:23
    
I want to get my company to jump on the NGINX bandwagon. It really is a fine piece of softwares. I set it up for a small site I was creating, and SNAP was it fast! –  Dan Gayle Aug 22 '11 at 16:33

Permalinks without mod_rewrite

Without an .htaccess file or modifying your httpd.conf file the best you can do is pathinfo permalinks. Pathinfo permalinks are the same as pretty permalinks except they start with index.php.

To use pathinfo permalinks put index.php/ at the start of your custom permalink structure:

/index.php/%postname%/

See the Codex article for more information.

share|improve this answer
    
@Chris_O: I don't want to be a jerk and down vote so I won't but I must say I really cringe when I see people use this solution. I know you were just trying to help given the stated constraints but in my mind this approach is user hostile, retards social sharing and worse makes it look like amateurs set up the site. But then I did start the blog a blog.welldesignedurls.org several years ago so I have a bit of an ideological bent against such things. :) –  MikeSchinkel Aug 29 '10 at 4:52
    
@Chris_): Just to be clear, my comments were aimed at the solution, not at you; you are great! Just wanted you to know that. :) –  MikeSchinkel Aug 29 '10 at 4:58
    
No offense taken. Just offering the only solution I know of that doesn't use .htaccess or httpd.conf. Agreed that it is not ideal but I would rather use it over example.org/?p=123 if it were my ONLY choice. –  Chris_O Aug 29 '10 at 5:18
    
I agree this isn't the ideal way to go, but I appreciate the suggestion as an alternative. And much better than example.org/?p=123 ! –  Mike Lee Aug 31 '10 at 18:07

Back in the Bad Old Days, WordPress needed to write a new config file every time you changed the permalink structure. In modern setups, the RewriteRules are unchanging:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

All requests for non-existant files (ie. a custom permalink path that doesn't match a file on the filesystem) gets passed through index.php, and $_SERVER['REQUEST_URI'] tells PHP what was actually requested. Your client can set the rewrite rules in httpd.conf or .htaccess, and you won't need to modify it as you tweak the permalink structure.

Some plugins do attempt to modify .htaccess themselves, or ask you to modify the file. This solution may not be for everybody, but it's worth considering.

share|improve this answer
    
Thanks for the answer. The client is leaning towards modifying the httpd.conf right now. –  Mike Lee Aug 31 '10 at 18:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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