warning http
HTTP 301 Moved Permanently
Understanding HTTP 301 Moved Permanently - the requested resource has been permanently moved to a new URL and all future requests should use the new URL.
What It Means
HTTP 301 Moved Permanently indicates that the requested resource has been assigned a new permanent URI. Any future references to this resource should use the new URI returned in the Location header.
Search engines will transfer the SEO ranking from the old URL to the new URL, making this the preferred redirect for permanent URL changes.
Important caveat: Browsers may change POST requests to GET requests when following a 301 redirect. Use 308 if you need to preserve the HTTP method.
Common Causes
- A website has moved to a new domain
- URL structure has been permanently changed
- Pages have been consolidated or reorganized
- Enforcing HTTPS by redirecting from HTTP
- Redirecting from
wwwto non-www(or vice versa) - Old API versions redirecting to new endpoints
How to Fix
Nginx Configuration
# Redirect a single page
server {
listen 80;
server_name example.com;
location /old-page {
return 301 https://example.com/new-page;
}
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
Apache (.htaccess)
# Redirect a single page
Redirect 301 /old-page https://example.com/new-page
# Redirect entire domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]
Express.js
app.get('/old-page', (req, res) => {
res.redirect(301, '/new-page');
});
// Redirect all HTTP to HTTPS
app.use((req, res, next) => {
if (!req.secure) {
return res.redirect(301, `https://${req.headers.host}${req.url}`);
}
next();
});
Client-side handling
// fetch follows redirects automatically
const response = await fetch('https://example.com/old-page');
console.log(response.url); // https://example.com/new-page
console.log(response.redirected); // true
Best practices:
- Use 301 only for permanent moves — use 302 or 307 for temporary redirects
- Always set the
Locationheader with the new URL - Avoid redirect chains (A -> B -> C); redirect directly to the final URL