SEO
Seven Ways to Remove Duplicate Content in Joomla
In the previous article we looked at where duplicates come from and how to find them. This one is about removing them. Every site is different, so treat these as seven tools rather than seven steps — most sites need two or three of them.
All of this assumes SEF URLs and URL rewriting are enabled in Global Configuration → Site. On Joomla 6 that is the default for new installations.
1. Start with Joomla's own routing settings
Before installing anything, check three settings in Global Configuration → Site → SEO:
- Search Engine Friendly URLs — on.
- URL Rewriting — on, with
htaccess.txtrenamed to.htaccess(or the equivalent nginx rules). - Remove IDs from URLs — this is the one people miss. With it off, the same article is reachable both with and without its numeric ID.
Joomla's modern router also has a strict mode that returns a 404 instead of rendering an article under an unexpected path. Turning it on removes an entire class of duplicates at the source rather than patching them afterwards.
2. robots.txt
The file ships with Joomla, lives in the site root and is served at /robots.txt. It tells crawlers what not to request. A single line clears out a lot of noise:
Disallow: /*?
That covers print views, ?tmpl=component variants, RSS feed links, on-site search result pages and pagination parameters. Whether you prefer that or an explicit rule per pattern is a matter of taste.
Two cautions. A very permissive robots.txt is treated as allowing everything, and a blanket rule can easily block something you need — your sitemap, for instance. If so, allow it back explicitly:
Allow: /sitemap.xml
Also remember what robots.txt does not do: it prevents crawling, not indexing. A URL that is linked from elsewhere can still appear in results as a bare link. To keep a page out of the index, use the meta tag in point 5.
3. rel="canonical"
The canonical link element tells a search engine which URL of a set is the real one. It is the right tool for near-duplicates — pages that differ only by sort order, items per page, or a tracking parameter. Pick one canonical URL, point the variants at it, and the variants stay out of results while their signals consolidate.
Joomla does not emit one for you. The core SEF plugin adds a canonical only when an alternative domain is configured in its options, and that tag simply repeats the current URL — query parameters and all — which is precisely what you were trying to consolidate. So for anything beyond the trivial case you emit it yourself, from a template or a small system plugin:
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
$app = Factory::getApplication();
$doc = $app->getDocument();
$doc->addHeadLink(Uri::base() . 'news/my-article', 'canonical', 'rel');
4. 301 redirects
Use a permanent redirect when a document still exists but has moved. Search engines transfer the URL's accumulated signals to the new address instead of treating it as a new page.
The classic Joomla case is the front page being reachable both at / and at /index.php, plus the alias of the Home menu item:
Redirect 301 /index.php https://example.com/
And the equally classic www to non-www consolidation:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
For one-off moves you do not need to touch .htaccess at all — Joomla's Redirects component records 404s and lets you map each old URL to a new one from the administrator.
5. The robots meta tag
To keep a page out of the index reliably, serve it with:
<meta name="robots" content="noindex, follow">
This is stronger than a robots.txt rule, because the crawler has to fetch the page to see it — which is exactly why it works when a blocked-but-linked URL would otherwise show up.
Per-article, set it in the Publishing tab under Robots. For a whole view, add a condition in your template. To keep search result pages out, for example:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$option = $app->getInput()->getCmd('option');
if ($option === 'com_finder') {
$this->setMetaData('robots', 'noindex, follow');
}
The same trick in component.php covers print and modal views in one go.
6. Removing URLs from the webmaster panels
When something is already indexed and you want it gone quickly, request removal directly: the Removals tool in Google Search Console, and the equivalent page in Yandex Webmaster. This is a temporary measure — it hides the URL for a few months. Pair it with one of the fixes above, or the page comes back.
7. The X-Robots-Tag header
The header does what the meta tag does, but at the HTTP level, which makes it the only option for non-HTML files — PDFs, images, generated exports:
<FilesMatch "\.pdf$">
Header set X-Robots-Tag "noindex, follow"
</FilesMatch>
There are more ways to deal with duplicates than there are sites with the problem. What matters is understanding what each one does — blocking a crawl, keeping a page out of the index, or consolidating signals onto one URL — because those are three different outcomes and choosing the wrong one is how people end up deindexing pages they wanted to keep.