URL Rewriting
mod_rewrite's syntax to the practical patterns URL rewriting is actually used for in real sites -- clean URLs, redirects after a site restructure, and enforcing canonical addresses.In this page:
Clean URLs for a Framework Front Controller
Most modern frameworks (Laravel, Symfony, Django when served through a proxy) route every request through a single entry file. A rewrite rule sends any request that doesn't match a real file or directory to that entry point instead: checking %{REQUEST_FILENAME} isn't an existing file or directory with RewriteCond, then rewriting everything else to index.php (or the equivalent) so the framework's own router takes over from there.
Redirecting an Old Site Structure
After a site redesign, old URLs often need to keep working -- an SEO and user-experience necessity, not an optional nicety. Individual Redirect directives handle a handful of one-off moved pages; a RewriteRule with capture groups handles a whole pattern at once, e.g. mapping every old /articles/123 URL to a new /blog/123-post-title scheme via a lookup, or a simpler pattern-based transformation.
Enforcing One Canonical URL
Search engines treat example.com, www.example.com, and even the same page reachable over both HTTP and HTTPS as separate, competing URLs unless you tell them otherwise. A RewriteCond/RewriteRule pair that redirects any non-www request to www. (or vice versa -- pick one and stay consistent) is standard practice, alongside the HTTPS-forcing rule from the mod_rewrite lesson.
Rewrite vs. Redirect
It's worth being deliberate about which one a rule actually needs: an internal rewrite (no [R] flag) changes what Apache serves without the browser's address bar changing at all -- right for a clean-URL front controller. A redirect ([R=301] or [R=302]) sends the browser an actual new address to go to -- right for telling both users and search engines that a URL has permanently moved.
Example: A framework front-controller rewrite plus canonical www redirect
RewriteEngine On
# Force www.
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
# Front controller: send anything that isn't a real file/dir to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
{# Flagged by hand after confirming a runner can't handle this example
(a shell command / go.mod file stored as a TopicExample, a language
feature the configured runner version doesn't support, or output
that blows a runner's sandbox limit) -- see TopicExample.norun.
Never render the run button for these, regardless of language,
since it would just fail at execute_code (or worse, hang the
Judge0 queue on a submission that can never finish cleanly). #}
- Using an internal rewrite when a real redirect was needed (or the reverse), leaving the browser's address bar showing the wrong URL, or search engines never learning a page moved.
- Using a 302 for a permanent move, so search engines keep the old URL indexed instead of transferring its ranking to the new one.
- Writing a front-controller rewrite that also intercepts requests for real files (like images or CSS), which then get routed to the application instead of served directly.
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: