The Original Vision
In 1998, Tim Berners-Lee—inventor of the World Wide Web—wrote an essay titled "Cool URIs Don't Change." It remains one of the most important pieces on web architecture.
"What makes a cool URI? A cool URI is one which does not change. What sorts of URIs change? URIs don't change: people change them."
— Tim Berners-Lee, 1998
The essay makes a deceptively simple argument: when you publish a URL, you make a promise. That URL is a permanent name for a resource. When you change or delete it, you break that promise and damage the web.
The Web as a Tapestry
The web is built on links. Every hyperlink is an act of trust—the author believes the destination will exist when readers click it. When links break:
- Citations become dead ends
- Bookmarks become useless
- Search results lead nowhere
- The web's interconnected knowledge graph fragments
What Causes URLs to Break?
Berners-Lee identifies several common causes of link rot, all of which are choices made by people—not technical necessities.
Technology in the URL
URLs that expose implementation details break when technology changes:
// These URLs reveal technology that will eventually be replaced: /cgi-bin/search.pl?q=widgets /scripts/catalog.asp?id=123 /products.php?category=5 /api/v1/servlet/ProductServlet // When you migrate from PHP to Node, from .NET to Go, // every one of these URLs breaks
Author Name or Status
Organizing by author or department creates fragility:
// What happens when Sarah leaves the company? /~sarah/research/2024/paper.html /users/sarah/documents/report.pdf // What happens when departments reorganize? /marketing/campaigns/summer-2024.html /engineering/docs/api-guide.html
Subject Classification
Taxonomies change, but URLs shouldn't:
// "Smartphones" didn't exist as a category in 2005 /electronics/phones/smartphones/iphone.html // What was once "new media" is now just "media" /content/new-media/podcasts/ // Topics get reclassified as understanding evolves /science/astronomy/pluto-planet.html // Oops
File Extensions
Extensions leak implementation and constrain the future:
// Today it's HTML, tomorrow it might be: // - Server-rendered from a database // - Generated by a static site builder // - Dynamically assembled /about-us.html /about-us.htm /about-us.shtml /about-us.php
Arbitrary Reorganization
The most common cause: someone decides to "clean up" the URL structure:
// Original (worked for years) /products/widgets // "Improved" version (breaks all existing links) /catalog/items/widgets /shop/products/widgets /store/catalog/widgets-and-gadgets
Designing URLs That Last
A URL should be as permanent as a book's ISBN or a building's street address. Here's how to design for longevity.
Principle 1: Omit Technology
Never put implementation details in URLs:
// Bad: Technology visible /cgi-bin/products.pl /servlet/ProductDisplay /products.aspx // Good: Technology hidden /products /products/widgets /catalog/2024/widgets
Your URL should work whether your site is built with PHP, Rails, Django, Next.js, or technology that doesn't exist yet.
Principle 2: Omit Ownership
Don't organize by who created or manages content:
// Bad: Organizational structure visible /marketing/press-releases/2024 /engineering/blog/new-api /~jsmith/papers/research.html // Good: Organized by content, not creator /press/2024 /blog/new-api /research/papers/machine-learning
Principle 3: Use Dates Carefully
Dates in URLs make sense for time-bound content:
// Good: Blog posts are inherently dated /blog/2024/11/new-feature-announcement // Good: News articles are dated /news/2024/11/27/product-launch // Bad: Documentation version shouldn't be a date /docs/2024/api-reference // Will this be invalid in 2025? // Better: Version numbers or "latest" /docs/v2/api-reference /docs/latest/api-reference
Principle 4: Use Semantic Paths
URLs should describe the resource, not how to get it:
// Bad: Describes the action/mechanism /getProduct?id=123 /search?category=electronics&sort=price /display/article/456 // Good: Describes the resource /products/123 /products/electronics /articles/456
Principle 5: Plan for Decades
When designing a URL structure, ask: "Will this still make sense in 20 years?"
// Likely to survive: /products/widget-pro /articles/introduction-to-web-development /help/getting-started // Unlikely to survive: /featured/hot-new-items-fall-2024 /trending/viral-content /flash/interactive-demo
When URLs Must Change
Sometimes change is unavoidable. When it is, handle it responsibly.
Use Permanent Redirects
HTTP 301 (Moved Permanently) tells browsers and search engines where content has moved:
// Server configuration (Apache .htaccess)
Redirect 301 /old-page.html /new-page
// Server configuration (nginx)
location /old-page.html {
return 301 /new-page;
}
// Server code (Node.js/Express)
app.get('/old-page.html', (req, res) => {
res.redirect(301, '/new-page');
});
A 301 redirect:
- Preserves bookmarks (browsers learn the new location)
- Transfers SEO value to the new URL
- Maintains links from external sites
- Keeps citations working
Maintain Redirects Forever
The redirect from old to new should last as long as the new page exists. "Cleaning up" old redirects breaks links just as badly as deleting pages.
// Redirect chain over years: // 2010: /products/widget → (original) // 2015: /products/widget → /catalog/widgets (moved) // 2020: /catalog/widgets → /shop/widgets (moved again) // All three URLs should still work in 2024 // Old links from 2010 might still be out there
Handle Content Removal
When content is genuinely removed (not moved), use HTTP 410 (Gone):
// 404: Not Found (might never have existed, temporary error)
// 410: Gone (definitely existed, permanently removed)
// Server code
app.get('/discontinued-product', (req, res) => {
res.status(410).send('This product has been discontinued.');
});
410 tells search engines to remove the page from indexes, while 404 might be retried.
Archive Rather Than Delete
Instead of removing old content:
// Instead of deleting:
DELETE /blog/2018/outdated-article
// Archive it with a note:
/blog/2018/outdated-article
<!-- Banner: "This article is from 2018 and may be outdated.
See /blog/2024/updated-article for current information." -->
Archived content with dates and context is still valuable. Broken links are not.
Real-World Examples
Good: Wikipedia
Wikipedia URLs are remarkably stable:
// Simple, semantic, technology-free: https://en.wikipedia.org/wiki/URL // Underscores for spaces (consistent convention) https://en.wikipedia.org/wiki/Tim_Berners-Lee // Redirects for common misspellings and aliases https://en.wikipedia.org/wiki/WWW → redirects to World_Wide_Web
Wikipedia article URLs from 2004 still work today.
Good: W3C Specifications
W3C uses dated URLs for specifications:
// Specific version (permanent) https://www.w3.org/TR/2023/REC-css-color-4-20231107/ // Latest version (redirects to current) https://www.w3.org/TR/css-color-4/
Both patterns are useful: dated URLs for citations, "latest" for general reference.
Bad: Government Sites
Government sites often reorganize with every administration change:
// Links from 2016 → broken by 2020 // Links from 2020 → broken by 2024 // Critical civic information becomes inaccessible
Bad: Corporate Rebrands
When companies rebrand, URLs often break entirely:
// Company renames: Acme Inc → Apex Corp // Old URLs (broken): https://acme.com/products https://acme.com/support/docs // No redirects set up // All external links, bookmarks, and citations break
Implementation Strategies
URL Mapping Layer
Separate your URL structure from your internal file organization:
// Don't serve files directly:
/var/www/html/products/electronics/phones/widget-pro.html
// Use a routing layer:
/products/widget-pro → renders from database
→ or loads /templates/product.html
→ or serves /content/widget-pro.md
This decouples URLs from storage, allowing internal reorganization without breaking public links.
Redirect Registry
Maintain a permanent record of all URL changes:
// redirects.json (or database table)
{
"redirects": [
{
"from": "/old/path",
"to": "/new/path",
"date": "2024-03-15",
"reason": "URL structure redesign",
"permanent": true
}
]
}
// This registry should be:
// - Version controlled
// - Never have entries removed
// - Automatically applied by the server
URL Linting
Add URL quality checks to your development process:
// Check for anti-patterns:
function lintUrl(url) {
const issues = [];
// Technology in URL
if (/\.(php|asp|jsp|cgi)$/i.test(url)) {
issues.push('Avoid file extensions');
}
// Implementation details
if (/servlet|handler|controller/i.test(url)) {
issues.push('Avoid implementation terms');
}
// User paths
if (/\/~\w+\/|\/users?\//i.test(url)) {
issues.push('Avoid user-based paths');
}
return issues;
}
URL Monitoring
Regularly check that your URLs still work:
// Automated link checking // Run periodically (weekly/monthly) // Check: // - Internal links between pages // - Links from external sites (via search console) // - Redirect chains (detect long chains) // - 404 rates (sudden spikes indicate problems)
The Broader Philosophy
Berners-Lee's essay reflects a deeper philosophy about the web.
The Web as Shared Space
When you publish a URL, you're not just creating a page—you're adding an address to a shared namespace. That address becomes part of the web's infrastructure:
- Search engines index it
- People bookmark it
- Other sites link to it
- Researchers cite it
- Archives preserve it
Breaking a URL affects everyone who relied on it, not just you.
Stewardship vs Ownership
You don't truly "own" your URLs in isolation. You're a steward of part of the web's address space. Good stewardship means:
- Planning for permanence
- Redirecting when necessary
- Archiving rather than deleting
- Considering external dependencies
The Cost of Convenience
Breaking URLs is often done for short-term convenience:
- "It's easier to start fresh"
- "No one uses those old pages"
- "Our new CMS works differently"
- "The redesign requires new URLs"
These choices trade the web's long-term health for immediate convenience. The accumulated damage of millions of such decisions has created today's link rot crisis.
"There are no reasons at all for changing URIs. You can think of some. But the costs should be high for any decision to change URIs. I mean, the effort should be to make them design them and not change them."
— Tim Berners-Lee
Further Reading
- Cool URIs don't change — Tim Berners-Lee's original essay (W3C)
- Architecture of the World Wide Web, Volume One — W3C's URI design principles
- URL as UI — Jakob Nielsen's perspective on readable URLs