What is a 301 redirect and how do you set one up? (.htaccess, Nginx).
A 301 redirect is the method of announcing, through the server response, that an address has permanently moved to another address; the browser takes the visitor to the new address, and Google learns the new address as the primary one. It is set up with one line in the .htaccess file on Apache, a return line on Nginx, and a _redirects line or a redirect rule on Cloudflare.
A 301 redirect is the basic tool for not losing the value of an old address when a site is redesigned or a page’s address changes. This guide answers the “how” question: which line is written on which server, which mistakes are made most often, and how to tell whether a redirect really works. The choice between permanent and temporary redirects is covered in the 301 vs. 302 comparison; its place in a site migration in the migration checklist. If you are moving all the addresses of a site, this part of the job is the core of the website redesign and migration service.
What does a 301 redirect do?
Instead of a page, the server answers a request for the old address with a short response: status code 301 and the new address. On seeing this response, the browser requests the new address; the visitor usually does not notice the step in between. On Google’s side, a 301 is a strong signal that the target address is the primary (canonical) address. Google’s documentation distinguishes 301 and 308 as permanent and 302, 303 and 307 as temporary redirects; the temporary ones give only a weak signal that the target is the primary address.
The redirect should be done on the server. An instant refresh placed inside the page (meta refresh, 0 seconds) and changing the address with JavaScript can also be interpreted by Google as permanent redirects, but both require the page to load first, and the JavaScript one depends on the page being rendered. If you have the choice, a server redirect always comes first.
How do you set up a 301 redirect with .htaccess on Apache?
If your site runs on an Apache server — a common situation on shared hosting — the redirect is written into the .htaccess file in the site’s root directory. There are two ways. The Redirect directive is for simple matches: it sends requests beginning with the path on the left to the address on the right. RewriteRule captures patterns with a regular expression; it is used when the address structure changes wholesale.
- # Single page: old address → new address
- Redirect 301 /hakkimizda.html https://
www.example.com /kurumsal / - # Folder: every address under /blog/, with the rest of its path, goes under /yazilar/
- Redirect 301 /blog/ https://
www.example.com /yazilar / - # Pattern: /urun/NAME → /urunler/NAME/
- RewriteEngine On
- RewriteRule ^urun
/([a-z0-9-]+) / ?$ https:// www.example.com /urunler /$1 / [R=301,L]
Three details are often missed. First: if you write no code on the Redirect line, Apache sends a 302, i.e. a temporary redirect; 301 or the word permanent must be written explicitly. The R flag in RewriteRule also produces a 302 if written without a code. Second: Redirect is a prefix match; the /blog/ line catches every address beginning with /blog/ and appends the rest of the path to the target. If that is what you want, it is a shortcut; if not, it also moves addresses you did not expect. Third: inside .htaccess, the RewriteRule pattern does not see the leading slash; according to Apache’s documentation, a pattern beginning with ^/ never matches in this context. That is why the pattern starts with ^urun/.
How do you write a 301 redirect on Nginx?
Nginx does not read .htaccess; the redirect is written into the server or location block of the server configuration and takes effect when the configuration is reloaded. For a single address, use location and return; for a pattern, rewrite.
- # Single page
- location = /hakkimizda.html { return 301 https://
www.example.com /kurumsal /; } - # Pattern: /urun/NAME → /urunler/NAME/
- rewrite ^
/urun /([a-z0-9-]+) / ?$ https:// www.example.com /urunler /$1 / permanent;
On Nginx, too, the default is temporary: if only an address is written on the return line, a 302 is sent; if redirect is written instead of permanent on the rewrite line, it is again a 302. For a permanent redirect, write the code or the permanent flag explicitly.
How do you set up a 301 redirect on Cloudflare?
On Cloudflare there are three ways. If the site is published as static files on Cloudflare Pages or Workers, one rule per line is written in the _redirects file at the root: source, target, code. If only Cloudflare’s network sits in front of the site, the redirect rules in its dashboard are used. The third way is for a Worker to produce the redirect response in its own code; this is what this site does.
- # _redirects — source · target · code
- /hakkimizda.html /kurumsal/ 301
- /urun/* /urunler/:splat 301
According to Cloudflare’s documentation, the default in the _redirects file is 302 if no code is written; here too, 301 must be written explicitly. One more detail: the rules in this file apply only to static file responses, not to responses produced by a Worker’s own code. If your site has both a Worker and _redirects, do not write rules without knowing which request falls to which.
What are the most common 301 redirect mistakes?
- Not writing the code. In all three environments a redirect without a code defaults to 302; a permanent move looks temporary.
- Sending everything to the homepage. Google reads redirects of addresses without an equivalent to the homepage like error pages; the right answer is 404 or 410 (404 error guide).
- Building chains. Old address → intermediate address → new address. Google’s crawler follows at most 10 hops, but the site move documentation recommends keeping chains to at most three hops. Details in the redirect chain entry.
- Building loops. If two rules redirect to each other, the page never opens; Search Console reports this as a redirect error.
- Leaving internal links on the old address. The redirect works, but every click on your own site passes through an unnecessary step.
- Removing the redirect too early. Google recommends keeping it in place for at least one year.
How can you tell whether a redirect works?
Opening the old address in a browser and seeing the new page is not enough: the browser follows the chain silently, does not show the code and may keep permanent redirects in its own cache. A proper test asks three questions at once: is the code of the first response 301, is the address reached at the end of the chain the one in the map, and does that address return 200? This is asked separately for every line in the map.
How is 301 used on this site?
This site’s redirects run on the server side, in the code of the Worker running on Cloudflare. They do two jobs. First, every request to the non-www domain is sent with a 301 to the www address, with path and query unchanged. Second, a small alias table connects old addresses to their new ones.
The most instructive line in that table came from a service page that was split in two in September 2026. The old address carried two separate search intents on one page and was indexed. We set up the redirect not to the services list but to the new page that carries the body of the old page one to one: Google expects the closest equivalent for an old address, and a list page is not that equivalent.
On the measuring side we were wrong twice, and both were measurement errors, not product errors. In the first version, the verification tool followed the redirects and reported the 200 behind them; a working redirect looked broken. When we changed the tool to read the first hop, the hop it caught this time was not our redirect but the first hop from the non-www address to the www address. That is how it became clear that the right measure is the end of the chain: does the old address drop the reader on the right page? Since then the tool checks the destination address and that the destination really differs from the requested address — if the redirect were never set up, the destination would be the same as the requested address and would pass silently.
The proof of a redirect is not the status code but the address it arrives at.
Consolidating the http and non-www versions on the same domain is a separate job; it is explained in the HTTPS and www redirect guide.
If you don’t want to lose traffic while relaunching your site, website redesign and migration inventories the old addresses, builds a chain-free 301 map and monitors the site for 90 days after the move.