Example HTTP Response
HTTP/1.1 301 Moved Permanently
Location: https://new-site.com/page- Website restructured with new URLs
- Domain name changed
- Page permanently relocated
What does this mean?
We've moved! Like forwarding your mail after moving to a new house. Update your bookmarks!
Technical Definition
The URL of the requested resource has been changed permanently. The new URL is given in the response.
RFC Says
"The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs."
Plain English:
The resource has permanently moved to a new address. Update your bookmarks and links - this is the new home forever. Search engines will transfer SEO value to the new URL.
"Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request."
Plain English:
Important caveat: Due to old browser behavior, a POST request might become a GET request after following a 301 redirect. If you need to preserve the HTTP method (keep POST as POST), use 308 instead.
Common Misinterpretation
Many developers don't realize that 301 can change POST to GET. This is historical behavior from early HTTP implementations. Use 308 (Permanent Redirect) when method preservation matters, such as for API endpoints.
Ready-to-use code for returning this HTTP status in your application:
// Express.js
app.get('/example', (req, res) => {
res.status(301).json({
error: 'Moved Permanently',
message: 'Your error message here'
});
});
// Native HTTP
const http = require('http');
http.createServer((req, res) => {
res.writeHead(301, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
error: 'Moved Permanently',
message: 'Your error message here'
}));
}).listen(3000);- The resource URL has changed permanently and will never return
- You want search engines to update their index to the new URL
- Consolidating multiple URLs to a canonical URL for SEO
- Note: May change POST/PUT requests to GET (use 308 to preserve method)