Duplicate Content SEO in Nuxt · Nuxt SEO

[NuxtSEO](https://nuxtseo.com/ "Home")

- [Modules](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)
- [Tools](https://nuxtseo.com/tools)
- [Pro](https://nuxtseo.com/pro)
- [Learn SEO](https://nuxtseo.com/learn-seo/nuxt) [Releases](https://nuxtseo.com/releases)

[1.4K](https://github.com/harlan-zw/nuxt-seo)

[Nuxt SEO on GitHub](https://github.com/harlan-zw/nuxt-seo)

Learn SEO

Master search optimization

Nuxt

 Vue

[SEO Checklist](https://nuxtseo.com/learn-seo/checklist) [Pre-Launch Warmup](https://nuxtseo.com/learn-seo/pre-launch-warmup) [Backlinks & Authority](https://nuxtseo.com/learn-seo/backlinks)

[Mastering Meta](https://nuxtseo.com/learn-seo/nuxt/mastering-meta)

- [Titles](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/titles)
- [Meta Description](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/descriptions)
- [Image Alt Text](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/alt-text)
- [Social Sharing](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/open-graph)
- [Rich Results](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/rich-results)
- [Schema.org](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/schema-org)
- [Twitter Cards](https://nuxtseo.com/learn-seo/nuxt/mastering-meta/twitter-cards)

[ Controlling Crawlers](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers)

- [Robots Txt](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/robots-txt)
- [Sitemaps](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/sitemaps)
- [Robot Meta Tag](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/meta-tags)
- [Canonical Link Tag](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/canonical-urls)
- [HTTP Redirects](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/redirects)
- [Duplicate Content](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/duplicate-content)
- [llms.txt](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/llms-txt)

[ Routes & Rendering](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering)

- [URL Structure](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/url-structure)
- [Pagination](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/pagination)
- [Trailing Slashes](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/trailing-slashes)
- [Query Parameters](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/query-parameters)
- [Hreflang & i18n](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/i18n)
- [404 Pages](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/404-pages)
- [Dynamic Routes](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/dynamic-routes)
- [Internal Linking](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/internal-linking)
- [Programmatic SEO](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/programmatic-seo)
- [Rendering Modes](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/rendering)
- [Security](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/security)

[ Launch & Listen](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen)

- [Getting Indexed](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/going-live)
- [Google Search Console](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/search-console)
- [Core Web Vitals](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/core-web-vitals)
- [Indexing Issues](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/indexing-issues)
- [SEO Monitoring](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/seo-monitoring)
- [Site Migration](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/site-migration)
- [IndexNow](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/indexnow)
- [Debugging](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/debugging)
- [AI Search Optimization](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen/ai-optimized-content)

1. [Learn SEO for Nuxt](https://nuxtseo.com/learn-seo)
2.
3. [Controlling Crawlers](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers)
4.
5. [Duplicate Content](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/duplicate-content)

# Duplicate Content SEO in Nuxt

Duplicate content wastes crawl budget and splits ranking signals. Here's how to find and fix it with canonical tags, redirects, and parameter handling.

[![Harlan Wilton](https://avatars.githubusercontent.com/u/5326365?v=4)Harlan Wilton](https://x.com/harlan-zw)15 mins read Published Dec 17, 2025

What you'll learn

- [67.6% of websites](https://www.womenintechseo.com/knowledge/dealing-with-duplicate-content-canonicalization-in-detail/) have duplicate content issues, diluting ranking signals across multiple URLs
- Google doesn't penalize but picks which version to index (often not the one you want)
- Use 301 redirects for permanent moves, canonical tags for duplicates you need to keep

[67.6% of websites have duplicate content issues](https://www.womenintechseo.com/knowledge/dealing-with-duplicate-content-canonicalization-in-detail/). Same content at different URLs splits ranking signals and wastes crawl budget. Google picks which version to show, and it's often not the one you want.

[Google doesn't penalize duplicate content](https://developers.google.com/search/docs/advanced/guidelines/duplicate-content) unless you're deliberately scraping other sites. But it hurts SEO by diluting link equity across multiple URLs and confusing search engines about which page to rank.

## [Common Causes](#common-causes)

### [URL Variations](#url-variations)

**www vs non-www**

`www.mysite.com` and `mysite.com` are [treated as separate sites](https://yoast.com/video/ask-yoast-use-www-or-not/). Choose one, redirect the other.

**HTTP vs HTTPS**

`http://mysite.com` and `https://mysite.com` create duplicates. Always redirect HTTP to HTTPS.

**Trailing slashes**

`/products` and `/products/` are different URLs. [Pick one format site-wide](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/trailing-slashes).

Nuxt handles these redirects in `nuxt.config.ts`:

nuxt.config.ts

```
export default defineNuxtConfig({
  nitro: {
    prerender: {
      autoSubfolderIndex: false
    }
  }
})
```

For HTTPS and www vs non-www redirects, configure at the server level (Netlify, [Vercel](https://vercel.com), [Cloudflare](https://cloudflare.com)) for best performance and SEO.

### [Query Parameters](#query-parameters)

[URL parameters create exponential duplicates](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/query-parameters). Three filters generate 8 combinations. Add sorting and pagination, and you're looking at hundreds of URLs.

```
/products
/products?color=red
/products?color=red&size=large
/products?color=red&size=large&sort=price
/products?color=red&size=large&sort=price&page=2
```

**Fix:** Set [canonical tags](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/canonical-urls#filter-and-sort-parameters) to point filter and sort variations to the base URL. Alternatively, [block filtered pages from indexing](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/meta-tags) with noindex.

### [Parameter Order](#parameter-order)

`?sort=price&filter=red` and `?filter=red&sort=price` are identical content, different URLs.

**Fix:** Enforce consistent parameter order in canonical URLs. See the [Query Parameters guide](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/query-parameters) for the implementation.

### [Tracking Parameters](#tracking-parameters)

Analytics params (`utm_source`, `fbclid`, `gclid`) don't change content but create duplicate URLs.

**Fix:** Strip tracking parameters (utm_source, fbclid, gclid) from canonical URLs. See the [Query Parameters guide](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/query-parameters) for the composable implementation. Better yet, [redirect tracking params at the server level](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/query-parameters#server-side-parameter-handling) for proper 301 status codes.

### [Pagination](#pagination)

[Each paginated page has unique content](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/pagination). Use self-referencing canonicals; don't point page 2 to page 1. See the [Pagination SEO guide](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/pagination) for the implementation.

### [Print and Mobile Versions](#print-and-mobile-versions)

Printer-friendly URLs (`/article?print=true`) and mobile subdomains (`m.mysite.com`) create duplicates.

**Fix: Canonical to desktop version**

pages/article.vue

```
<script setup lang="ts">
const siteUrl = useSiteConfig().url

useHead({
  link: [{
    rel: 'canonical',
    // Always point to main URL
    href: \`${siteUrl}/article\`
  }]
})
</script>
```

For print, use CSS `@media print` instead of separate URLs.

### [Session IDs and Click Tracking](#session-ids-and-click-tracking)

Session IDs in URLs create infinite variations.

```
/products?sessionid=abc123
/products?sessionid=xyz789
/products?sessionid=def456
```

**Fix: Don't put session IDs in URLs.** Use cookies. If unavoidable, [block with robots.txt](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/robots-txt):

public/robots.txt

```
User-agent: *
Disallow: /*?sessionid=
Disallow: /*&sessionid=
Disallow: /*?sid=
Disallow: /*&sid=
```

Or use the Robots module:

[Robots v6.0.78.9M519 Tame the robots crawling and indexing your site with ease.](https://nuxtseo.com/docs/robots/getting-started/introduction) ## [Finding Duplicate Content](#finding-duplicate-content)

### [Google Search Console](#google-search-console)

[Use the Page Indexing report](https://support.google.com/webmasters/answer/12642436) to identify duplicates:

1. Open Search Console
2. Go to "Indexing" → "Pages"
3. Look for:
  - "Duplicate, Google chose different canonical than user"
  - "Duplicate without user-selected canonical"
  - "Alternate page with proper canonical tag"

Click each category to see affected URLs. If Google chose a different canonical than you specified, [conflicting signals exist](https://developers.google.com/search/blog/2019/03/how-to-discover-suggest-google-selected).

**Using URL Inspection:**

1. Enter any URL
2. Check "User-declared canonical" vs "Google-selected canonical"
3. If they differ, Google found stronger signals pointing to a different URL

**View page source (not DevTools)** to verify canonical tags are server-rendered:

```
curl https://mysite.com/products?sort=price | grep canonical
```

**Check for canonicalization conflicts:**

- Multiple `rel="canonical"` tags on same page
- Canonical in `<head>` vs HTTP header
- Canonical points to redirect or noindexed page
- Canonical URL returns 4xx/5xx status

**Test redirect chains:**

```
curl -I https://mysite.com/old-url
```

Should show one 301 redirect, not a chain.

### [Screaming Frog](#screaming-frog)

[Screaming Frog detects exact and near-duplicate content](https://www.screamingfrog.co.uk/seo-spider/tutorials/how-to-check-for-duplicate-content/):

**Exact duplicates**: Pages with identical HTML (MD5 hash match)

**Near duplicates**: Pages with 90%+ similarity (minhash algorithm)

**Setup:**

1. Enable near duplicates: `Config > Content > Duplicates`
2. Crawl your site
3. Go to "Content" tab
4. Filter by "Exact Duplicates" or "Near Duplicates"

Check these columns:

- `Closest Similarity Match`: Percentage match to most similar page
- `No. Near Duplicates`: Count of similar pages
- `Hash`: MD5 hash for exact duplicate detection

[Screaming Frog](https://screamingfrog.co.uk) auto-excludes nav and footer elements to focus on main content. [Adjust threshold](https://www.screamingfrog.co.uk/seo-spider/user-guide/tabs/#content) if needed (default 90%).

### [Site Search](#site-search)

Use Google site search to find duplicates manually:

```
site:mysite.com "exact title text"
```

If multiple URLs appear with the same title, you have duplicates.

### [Siteliner and Copyscape](#siteliner-and-copyscape)

**[Siteliner](https://www.siteliner.com/)**: Free tool that crawls up to 250 pages, shows duplicate content percentage

**[Copyscape](https://www.copyscape.com/)**: Detects external duplicate content (other sites copying you)

Both useful for content audits but don't replace Search Console or Screaming Frog for technical SEO.

## [Canonical vs 301 Redirect](#canonical-vs-301-redirect)

| When to Use | Canonical Tag | 301 Redirect |
| --- | --- | --- |
| **Need both URLs live** | ✅ Yes | ❌ No |
| **User should see one URL** | ❌ No | ✅ Yes |
| **Products in multiple categories** | ✅ Yes | ❌ No |
| **Old page no longer needed** | ❌ No | ✅ Yes |
| **UTM tracking parameters** | ✅ Yes | ❌ No |
| **www vs non-www** | ❌ No | ✅ Yes |
| **HTTP vs HTTPS** | ❌ No | ✅ Yes |
| **Moved/renamed pages** | ❌ No | ✅ Yes |

**Canonical tags** are [hints, not directives](https://www.searchenginejournal.com/canonical-vs-301-redirect/383124/). Google may ignore them. Both versions remain accessible. Use for duplicates you need (tracking params, multiple category paths).

**301 redirects** are permanent. Users see the redirect target. [Pass the same link equity as canonicals](https://seranking.com/blog/redirect-vs-canonical-tag/) but remove the duplicate from the index. Use for outdated or unnecessary URLs.

**Don't combine:** Using both canonical tag and 301 redirect on the same page sends conflicting signals. Pick one.

## [Decision Tree](#decision-tree)

![Duplicate Content Decision Tree](https://nuxtseo.com/images/learn-seo/vue/duplicate-content-decision.svg)

**Examples:**

- `http://mysite.com` → `https://mysite.com`: **301 redirect**
- `www.mysite.com` → `mysite.com`: **301 redirect**
- `/products?utm_source=twitter` → `/products`: **Canonical tag**
- `/products/shoes` and `/sale/shoes` (same product): **Canonical tag** (one canonical, one alternate)
- `/products?filter=red`: **Noindex + canonical to base URL**
- `/old-page` → `/new-page`: **301 redirect**

## [Common Mistakes](#common-mistakes)

**Mistake 1: Canonicalizing all paginated pages to page 1**

```
<!-- ❌ Wrong - hides pages 2+ from search -->
<script setup lang="ts">
useHead({
  link: [{ rel: 'canonical', href: 'https://mysite.com/blog' }]
})
</script>
```

[Each paginated page should reference itself](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/pagination#self-referencing-canonical-tags).

**Mistake 2: Using relative canonical URLs**

```
<!-- ❌ Wrong - must be absolute -->
<link rel="canonical" href="/products/phone">

<!-- ✅ Correct -->
<link rel="canonical" href="https://mysite.com/products/phone">
```

[Google requires absolute URLs](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls).

**Mistake 3: Combining canonical with noindex**

```
<!-- ❌ Conflicting signals -->
<script setup lang="ts">
useHead({
  link: [{ rel: 'canonical', href: 'https://mysite.com/page' }]
})
useSeoMeta({
  robots: 'noindex, follow'
})
</script>
```

Canonical says "this is a duplicate of X." Noindex says "don't index this." [Pick one](https://www.oncrawl.com/technical-seo/use-robots-txt-meta-robots-canonical-tags-correctly/).

**Mistake 4: Canonical chains**

```
Page A → canonical → Page B → canonical → Page C
```

[Google may ignore chained canonicals](https://developers.google.com/search/docs/crawling-indexing/canonicalization-troubleshooting). Canonical directly to the final target.

**Mistake 5: Client-side canonicals in SPAs**

Googlebot doesn't execute JavaScript fast enough. Nuxt renders canonical tags on the server by default, so this isn't an issue.

## [Preventing Duplicate Content](#preventing-duplicate-content)

### [Configure Trailing Slashes](#configure-trailing-slashes)

Nuxt handles trailing slashes via `nuxt.config.ts`:

nuxt.config.ts

```
export default defineNuxtConfig({
  // Force trailing slashes for prerendered routes
  nitro: {
    prerender: {
      autoSubfolderIndex: true
    }
  }
})
```

For dynamic redirects, use [server middleware](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/redirects#using-server-middleware).

### [Validate Parameter Values](#validate-parameter-values)

Prevent infinite URL variations by whitelisting allowed parameter values:

```
const allowedSortValues = ['price', 'name', 'date', 'rating']
const route = useRoute()
const sort = route.query.sort

if (sort && !allowedSortValues.includes(sort as string)) {
  // Redirect to base URL or default sort
  await navigateTo({ query: { ...route.query, sort: undefined } })
}
```

### [Block Low-Value Pages](#block-low-value-pages)

Use [robots.txt](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/robots-txt) to block search results, filtered pages, and admin sections:

public/robots.txt

```
User-agent: *

# Block search results
Disallow: /search?
Disallow: /*?q=
Disallow: /*?query=

# Block filters
Disallow: /*?filter=
Disallow: /*&filter=

# Block tracking params
Disallow: /*?utm_source=
Disallow: /*?fbclid=
Disallow: /*?gclid=

# Block session IDs
Disallow: /*?sessionid=
Disallow: /*?sid=
```

Or configure via the Robots module:

[Robots v6.0.78.9M519 Tame the robots crawling and indexing your site with ease.](https://nuxtseo.com/docs/robots/getting-started/introduction) ## [Automatic Handling with Nuxt SEO Utils](#automatic-handling-with-nuxt-seo-utils)

Nuxt SEO Utils handles canonical URLs, trailing slashes, and parameter normalization automatically through site config:

[SEO Utils v8.1.72.4M125 SEO utilities to improve your Nuxt sites discoverability and shareability.](https://nuxtseo.com/docs/seo-utils/getting-started/introduction)

Configure once in `nuxt.config.ts`:

nuxt.config.ts

```
export default defineNuxtConfig({
  site: {
    url: 'https://mysite.com',
    trailingSlash: false
  }
})
```

The module automatically:

- Generates canonical URLs with correct trailing slash handling
- Strips tracking parameters from canonicals
- Normalizes URL formats across your site

[The 2026 SEO Checklist for Nuxt & Vue Pre-launch setup, post-launch verification, and ongoing monitoring. Interactive checklist with links to every guide.](https://nuxtseo.com/learn-seo/checklist) [Haven't launched yet? Start with the Pre-Launch Warmup](https://nuxtseo.com/learn-seo/pre-launch-warmup)

---

[HTTP Redirects 301 redirects preserve SEO value when content moves. Nuxt handles server-side redirects through routeRules to pass link equity and maintain rankings.](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/redirects) [llms.txt Help AI assistants understand your Nuxt documentation with the llms.txt standard. Configure nuxt-llms for automatic generation.](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/llms-txt)

On this page

- [Common Causes](#common-causes)
- [Finding Duplicate Content](#finding-duplicate-content)
- [Canonical vs 301 Redirect](#canonical-vs-301-redirect)
- [Decision Tree](#decision-tree)
- [Common Mistakes](#common-mistakes)
- [Preventing Duplicate Content](#preventing-duplicate-content)
- [Automatic Handling with Nuxt SEO Utils](#automatic-handling-with-nuxt-seo-utils)

[GitHub](https://github.com/harlan-zw/nuxt-seo) [ Discord](https://discord.com/invite/275MBUBvgP)

### [NuxtSEO](https://nuxtseo.com/ "Home")

- [Getting Started](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)
- [MCP](https://nuxtseo.com/docs/nuxt-seo/guides/mcp)

Modules

- [Robots](https://nuxtseo.com/docs/robots/getting-started/introduction)
- [Sitemap](https://nuxtseo.com/docs/sitemap/getting-started/introduction)
- [OG Image](https://nuxtseo.com/docs/og-image/getting-started/introduction)
- [Schema.org](https://nuxtseo.com/docs/schema-org/getting-started/introduction)
- [Link Checker](https://nuxtseo.com/docs/link-checker/getting-started/introduction)
- [SEO Utils](https://nuxtseo.com/docs/seo-utils/getting-started/introduction)
- [Site Config](https://nuxtseo.com/docs/site-config/getting-started/introduction)
- [Skew Protection](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)
- [AI Ready](https://nuxtseo.com/docs/ai-ready/getting-started/introduction)

### [NuxtSEO Pro](https://nuxtseo.com/pro "Nuxt SEO Pro")

- [Getting Started](https://nuxtseo.com/pro)
- [Dashboard](https://nuxtseo.com/pro/dashboard)
- [Pro MCP](https://nuxtseo.com/pro/docs/getting-started/mcp-setup)

### [Learn SEO](https://nuxtseo.com/learn-seo "Learn SEO")

Nuxt

- [Mastering Meta](https://nuxtseo.com/learn-seo/nuxt/mastering-meta)
- [Controlling Crawlers](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers)
- [Launch & Listen](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen)
- [Routes & Rendering](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering)
- [Staying Secure](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/security)

Vue

- [Vue SEO Guide](https://nuxtseo.com/learn-seo/vue)
- [Mastering Meta](https://nuxtseo.com/learn-seo/vue/mastering-meta)
- [Controlling Crawlers](https://nuxtseo.com/learn-seo/vue/controlling-crawlers)
- [SPA SEO](https://nuxtseo.com/learn-seo/vue/spa)
- [SSR Frameworks](https://nuxtseo.com/learn-seo/vue/ssr-frameworks)
- [SEO Checklist](https://nuxtseo.com/learn-seo/checklist)
- [Pre-Launch Warmup](https://nuxtseo.com/learn-seo/pre-launch-warmup)
- [Backlinks & Authority](https://nuxtseo.com/learn-seo/backlinks)

### [Tools](https://nuxtseo.com/tools "SEO Tools")

- [Social Share Debugger](https://nuxtseo.com/tools/social-share-debugger)
- [Robots.txt Generator](https://nuxtseo.com/tools/robots-txt-generator)
- [Meta Tag Checker](https://nuxtseo.com/tools/meta-tag-checker)
- [HTML to Markdown](https://nuxtseo.com/tools/html-to-markdown)
- [XML Sitemap Validator](https://nuxtseo.com/tools/xml-sitemap-validator)
- [Schema.org Validator](https://nuxtseo.com/tools/schema-validator)
- [Keyword Idea Generator](https://nuxtseo.com/tools/keyword-generator)
- [Keyword Research](https://nuxtseo.com/tools/keyword-research)
- [SERP Analyzer](https://nuxtseo.com/tools/serp-analyzer)
- [Domain Rankings](https://nuxtseo.com/tools/domain-rankings)

Copyright © 2023-2026 Harlan Wilton - [MIT License](https://github.com/harlan-zw/nuxt-seo/blob/main/license) · [mdream](https://mdream.dev)