Rewrite and redirect dynamic url with .htacces - .htaccess

Ok so my website has a dynamic url like this web.com/?city=London I want to change it to web.com/London
While I found the code for rewrite i'm struggling to find one that changes and immediatly redirects people to url in that format.

Well, you could do this:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} (?:(.*)&)city=([^&]+)(.*)
RewriteRule ^(index.php)?$ %2?%1%3 [R,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.(js|css|jpe?g?|png|gif)$
RewriteCond %{REQUEST_URI} !^index.php
RewriteRule ([^/]+) index.php?city=$1 [L,QSA]
The first part is responsible for rewriting the original URLs to the "pretty" format and redirect the browser to it
Note that the first part only actually rewrites empty uri and "index.php" (assuming thats your directory index file).
The second part, rewrites the request "back" to index.php?city=London, and then serves the newly created request by a sub-request (hiding the real url from the browser).
However, note that this results in an unnecessary redirects of the browser, so instead of relying heavily on part 1 of this scenario, you should consider reconstructing the urls within the server-side application, so they will appear in the "correct" form to begin with.

Related

htaccess dynamic url redirect

I have the following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
I tried the following
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
And a couple of other solutions, nothing is working here. Can someone help me to go in the right direction?
Update:
This is my current .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
Redirect 301 "/en/download-app" "/download-app"
Please keep your htaccess file in your root and have it in following way.
Please clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
OR in case you don't have Rules to handle non-existing files/directories then use following Rules set. Please make sure either use above OR following Rules set one at a time only.
RewriteEngine ON
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?:expert)/([^-]*)-(.*)$ $1-profile?id=$1&locale=$2 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ /index.html [L]
I have following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
You would need to do something like the following at the top of your .htaccess file, before your existing directives (order is important):
RewriteCond %{QUERY_STRING} (?:^|&)id=([^&]+)
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
This captures the value of the id URL parameter (in the %1 backreference) regardless of where it appears in the query string and discards all other URL parameters. I'm assuming you don't specifically need to match locale=en?
Note that the regex subpattern ([^&]+) (the id value) only matches something, not nothing. If the URL parameter is empty (ie. id=&locale=en) then no redirect occurs.
The QSD flag is necessary to discard the original query string.
Test first with a 302 (temporary) redirect to avoid potential caching issues. And clear your browser cache before testing. Only use a 301 (permanent) redirect if this really is intended to be permanent.
To redirect the specific URL /expert-profile?id=<name>&locale=en to /expert/<name>, ie. the id parameter is at the start of the query string and is followed by locale=en only then you can (and should) be more specific in the condition. For example:
RewriteCond %{QUERY_STRING} ^id=([^&]+)&locale=en$
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
This is close (providing you placed the rule at the top of the file), however, this tries to preserve the other URL parameters, ie. locale=en and whatever else, to create another query string - which you've not stated in your requirements.
Aside: The existing answers are assuming you are wanting to internally rewrite (URL rewrite) the request in the other direction, ie. from /expert/john-doe to /expert-profile?id=john-doe&locale=en. This is probably due to how questions of this nature are notoriously miswritten and this is often the real underlying intention. However, you've made no mention of this here and a URL of the form /expert-profile is not a valid endpoint - so it wouldn't really make sense to "rewrite" the URL in that direction. (?)
If you want it rewritten, capture the name (.+) and insert it into the target $1
RewriteRule ^expert/(.+)$ /expert-profile?id=$1&locale=en [L]
And don't use flag R|redirect here, unless you really want a redirect.---
To redirect from expert-profile?id=john-doe to expert/john-doe, capture the id (.+?) from the query string and insert it in the substitution URL %1
RewriteCond &%{QUERY_STRING}& &id=(.+?)&
RewriteRule ^expert-profile$ /expert/%1 [R,L]
When everything works as it should, you may replace R with R=301 (permanent redirect).
Don't use both rules together. If you do, it will result in an endless redirect loop and finally give a "500 Internal Server Error".
Unrelated, but never test with R=301!

How can I instruct Apache to apply different URL rewriting rules based on a query variable in the requested URL?

I have a set of rules in a .htaccess file that redirects all requests to index.php, but this is interfering with AJAX requests that need to access the requested file directly.
I am trying to resolve this by appending ?ajax=true to all AJAX request URLs, and creating a rule that says "all URLs ending in ?ajax=true should be processed directly".
Here is my .htaccess file currently:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^ajax=true$
RewriteRule ^(.*)$ index.php?params=$1 [NC]
My AJAX request URL would be as follows:
http://www.example.com/process_ajax.php?ajax=true
No luck so far.
I think you are close with using a negative RewriteCond but the syntax could be a bit off. Try using parentheses like in my example below.
At first, I would use a wildcard value for the GET parameter like .* so you can focus on targeting the correct key. Once it's working you can test again for getting the right value, presumably true.
Try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !(ajax=.*)$
RewriteRule ^(.*)$ index.php?params=$1 [NC]

htaccess redirect domain.com/index.php?page=home to domain.com/home

What is the code for a simple redirect rule in htaccess that make this change :
domain.com/index.php?page=home => domain.com/home
From page=home, home is a dynamically generated page slug.
Also when on domain.com/somepage, output of echo $_GET['page'] should be "somepage"
I hope this will help you:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?page=$1
The RewriteConds makes sure that you aren't trying to access a real page (if you do so, the url will not be rewritten)
The RewriteRule mets every url like http://domain.com/somepage with or without an ending slash (but not domain.com/somefolder/somepage)
In this example the url displayed to the user doesn't change, if you want so you have to add [R=301] behind the RewriteRule.

htaccess and mod_rewrite using multiple querystrings

I am currently using htaccess to rewrite a single querystring to it's page name using the following and it's working fine...
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# Rewrites urls in the form of /parent/child/
# but only rewrites if the requested URL is not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /index.php?page=$1 [QSA]
My issue is that I am now trying to implement additional querystrings on top of the original. I can successfully access the page as /property-listing&property=12-Langworthy-Royston-Grove
However I would like to be able to rewrite the &property= to just be a forward slash, so essentially remove the additional querystring parameter, while maintaining the normal rewriting rules if no additional querystring parameters are passed.
Thanks for any help,
Matt.
Try adding this rule before last:
RewriteRule ^(.+)&property=(.*)$ /index.php?page=$1/$2 [L,QSA]
However note, that this will only work if &property= is part of URI (in the example you shown it is), because it is only the URI which is the subject of rewriting rule, not query-string.

htaccess directory to file redirect problem

I’m trying to use the following .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^images/
RewriteRule (.*) view.php?picid=$1 [L]
RewriteRule ^/user/(.*)$ /users.php?user=$1
I want two things to happen: Whenever someone requests /1234, it redirects to /view.php?picid=1234, and also when someone visits /users/bob, it redirects to /users.php?user=bob.
My code however, doesn’t seem to be working correctly.
There are several ways to do that. Here’s one that should work:
RewriteRule ^user/(.+)$ users.php?user=$1 [L]
RewriteRule ^([0-9]+)$ view.php?picid=$1 [L]
The first rule will catch any request that’s URI path begins with /user/ followed by one or more arbitrary characters. And the second will catch any request that’s URI path begins with / followed by one or more digits.
The initial problem with your rules is that the RewriteRule with (.*) will match everything.
If you do not want it to match a URL with a slash in it (such as users/bob), try ^([^/]*)$
Secondly, after a URL is rewritten, the new URL goes through your rules again. If you want to avoid matching something that has already been rewritten once, you should add a condition like
RewriteCond %{REQUEST_URI} !\.php

Resources