Learn how to enable pretty URLs with .htaccess using Apache mod_rewrite. Follow this step by step guide to configure clean URLs and prevent 404 errors on your PHP website.
Pretty URLs make your website easier to read, easier to share, and better for search engines. Instead of using a URL like this:
https://example.com/page.php?id=10
You can display a cleaner URL like this:
https://example.com/page/10
Apache handles this with the mod_rewrite module and a .htaccess file. When the rewrite rules are configured correctly, visitors can access clean URLs while your PHP application continues to work normally. Apache 2.4 continues to use mod_rewrite for this purpose, and the rewrite rules below follow the current documentation.
Prerequisites
Before you begin, make sure you have:
- Apache web server installed
mod_rewriteenabled.htaccesssupport enabled withAllowOverride All- A PHP website or application
- Access to your website's document root
Step 1: Enable the Rewrite Module
On Ubuntu or Debian, enable the rewrite module by running:
sudo a2enmod rewrite
Restart Apache to apply the change.
sudo systemctl restart apache2
Step 2: Allow Apache to Read .htaccess
Open your Apache Virtual Host configuration.
sudo nano /etc/apache2/sites-available/000-default.conf
Inside the <Directory> section, make sure it looks similar to this:
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
Save the file and restart Apache again.
sudo systemctl restart apache2
Without AllowOverride All, Apache ignores rewrite rules stored inside .htaccess.
Step 3: Create or Edit the .htaccess File
Move to your website directory.
cd /var/www/html
Create the file if it does not already exist.
nano .htaccess
Step 4: Add Rewrite Rules
Paste the following configuration into your .htaccess file.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
Save the file.
How This Works
RewriteEngine On
Enables Apache's rewrite engine.
RewriteCond %{REQUEST_FILENAME} !-f
Checks whether the requested file exists. If it exists, Apache serves the file normally.
RewriteCond %{REQUEST_FILENAME} !-d
Checks whether the requested directory exists. If it exists, Apache opens the directory normally.
RewriteRule ^(.*)$ index.php [L,QSA]
Sends every remaining request to index.php.
Because existing files and directories are excluded first, images, CSS files, JavaScript files, downloads, and other assets continue to work correctly. This approach is recommended for front controller applications and helps avoid common 404 issues.
Step 5: Read the Requested URL in PHP
When a visitor opens:
https://example.com/products/laptop
PHP can read the requested path like this:
<?php
$request = trim($_SERVER['REQUEST_URI'], '/');
echo $request;
Output:
products/laptop
You can then split the URL into sections and load the correct page.
<?php
$url = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
print_r($url);
Output:
Array
(
[0] => products
[1] => laptop
)
Example URL Routing
| URL | Processed By |
|---|---|
| /about | index.php |
| /contact | index.php |
| /products/laptop | index.php |
| /blog/how-to-install-nginx | index.php |
| /images/logo.png | Image served directly |
| /css/style.css | CSS served directly |
Common Reasons for 404 Errors
mod_rewrite is not enabled
Verify it is enabled.
apache2ctl -M | grep rewrite
You should see:
rewrite_module
AllowOverride is disabled
Check your Virtual Host configuration and confirm:
AllowOverride All
Incorrect Rewrite Rule
Use this rule for most PHP applications.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
File Permissions
Ensure Apache can read your website files.
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
Apache Configuration
After making changes, verify the configuration.
sudo apache2ctl configtest
Expected output:
Syntax OK
Restart Apache.
sudo systemctl restart apache2
Test Your Pretty URLs
Create a simple index.php file.
<?php
echo "Pretty URLs are working!";
Now visit:
https://example.com/about
https://example.com/services
https://example.com/blog/my-first-post
Each request should load through index.php without showing a 404 page.
Tips for Reliable URL Rewriting
- Keep only one
.htaccessfile in your application root whenever possible. - Exclude existing files and directories before sending requests to
index.php. - Restart Apache after changing server configuration.
- Run
apache2ctl configtestbefore restarting Apache. - Keep all application routing inside
index.phpfor easier maintenance. - Use
RewriteBaseonly when your application is installed in a subdirectory or served through an Alias. For websites installed directly in the document root, it is usually not required.
Conclusion
Pretty URLs give your website a cleaner structure and make navigation easier for visitors and search engines. With Apache mod_rewrite, AllowOverride All, and the correct .htaccess rules, you can route requests through a single entry point while serving existing files normally. This setup helps your application deliver clean URLs consistently without causing unnecessary 404 errors.

