Dynamic vs static-looking URLs
Dynamic : https://example.com/product.php?id=12&cat=shoes
Static : https://example.com/product/id/12/cat/shoes
Compact : https://example.com/product-12-shoes.html
All three can show the same page. The static versions are easier to read, look more trustworthy when shared, and avoid the duplicate-URL problems that parameter order (?cat=shoes&id=12) can cause.
How the generated rule works
RewriteEngine On
RewriteRule ^product/id/([^/]+)/cat/([^/]+)/?$ product.php?id=$1&cat=$2 [L,QSA]
([^/]+)captures each value;$1,$2insert them into the real query string./?$accepts an optional trailing slash.[L]stops processing further rules;[QSA]keeps any extra query parameters.
This is an internal rewrite: the browser keeps showing the clean URL. It is not a redirect.
Do you still need this?
Modern CMSs (WordPress, Shopify, Laravel and others) already produce clean URLs. Rewriting is most useful for older custom PHP sites. Google can crawl parameter URLs fine — the real gains are readability, consistent URL formats and keyword-bearing paths. For the best result, use words rather than IDs: /shoes/trail-runner-x beats /product/id/12. Generate readable slugs with the URL Slug Generator.
Switching an existing site
- Add the rewrite rule so the new URLs work.
- Update internal links, canonicals and the sitemap to the new format.
- 301-redirect the old dynamic URLs to the new ones so existing rankings and backlinks carry over (see the Htaccess Redirect Generator).
- Verify with the Redirect Checker.
Frequently asked questions
Is URL rewriting the same as a redirect?
No. A rewrite happens inside the server and the browser keeps showing the clean URL. A redirect sends the browser to a different URL.
Do static URLs rank better than dynamic ones?
Not directly. Google can index parameter URLs, but clean, descriptive URLs are easier to read, share and keep consistent, which helps clicks and avoids duplicates.
Where do I put the RewriteRule?
In the .htaccess file in your website root on Apache, after RewriteEngine On and before any catch-all CMS rules.
What does [L,QSA] mean?
L means last rule — stop processing. QSA means query string append — keep any extra query parameters from the original request.
Does this work on nginx?
The concept does, but the syntax is different. nginx uses rewrite or try_files directives in its configuration instead of .htaccess.

