Query Parameters and SEO in Nuxt
- Query parameters create separate URLs. Compare their content before deciding whether to consolidate them
- Set canonical URLs to suggest a preferred equivalent URL, and strip tracking params (
utm_,fbclid,gclid) from every canonical you generate - Choose readable category URLs. Both query parameters and path segments can identify indexable content
- Validate parameter values on the server so crawlers can't generate infinite URL variations from junk input
For deciding whether content belongs in a path segment or query parameter, see URL Structure.
Query parameters (?sort=price&filter=red) identify separate URLs. Sorting may reorder the same products; filters may select distinct products. Choose a policy after comparing the content.
With filters, sorting, and pagination, a single page can generate hundreds of URL variations. Equivalent variations can waste crawl resources. Distinct pagination or filter pages need their own URL policy.
Quick Setup
Start by classifying parameters. Remove tracking parameters from canonical URLs when they do not change the content. Keep the page number in pagination canonicals.
For filters and sorting, decide whether each variant deserves indexing. Use canonicalization for equivalent content, or noindex for exclusion. Keep useful pagination URLs crawlable and self-canonical.
Common Parameter Types
Different query parameters need different handling:
| Parameter Type | Examples | SEO Treatment | Why |
|---|---|---|---|
| Filters | ?color=red&size=large | Choose by content and indexing policy | Can show distinct content |
| Sorting | ?sort=price | Choose by content and indexing policy | May reorder an equivalent collection |
| Pagination | ?page=2 | Self-referencing canonical | Each page has unique content |
| Tracking | ?utm_source=twitter | Strip from canonical | No content value, analytics only |
| Search | ?q=shoes | Depends on results | Choose which results belong in search |
| Sessions | ?sessionid=abc | Canonical to base | Creates infinite URLs |
Filter Parameters
Filters create exponential URL variations. Three color filters generate 8 combinations (red, blue, green, red+blue, red+green, blue+green, red+blue+green, none).
Block Filtered Pages
This example assumes color, size, and brand views should stay out of search. Change that policy if they provide distinct indexable content.
<script setup lang="ts">
const route = useRoute()
const hasFilters = computed(() =>
route.query.color || route.query.size || route.query.brand
)
useSeoMeta({
robots: () => hasFilters.value ? 'noindex, follow' : 'index, follow'
})
</script>Move Important Filters to Path
Path segments can make important category URLs easier to read. Query URLs are also valid. These are two URL-design choices:
// /products?category=shoes
// A valid category URL// /products/shoes
// Create pages/products/[category].vueSort Parameters
Sorting can change presentation without changing the basic collection. Compare the rendered pages before selecting a canonical policy. Users share sorted URLs ("cheapest laptops" links to ?sort=price).
Include Sort in Canonical
This example treats allowed sort views as distinct indexable URLs. If the views are equivalent for your site, consolidate them instead.
<script setup lang="ts">
const route = useRoute()
const allowedSortValues = ['price', 'name', 'date', 'rating']
const sort = computed(() => {
const value = route.query.sort
return typeof value === 'string' && allowedSortValues.includes(value)
? value
: undefined
})
useHead(() => ({
link: [{
rel: 'canonical',
href: sort.value
? `https://mysite.com/products?sort=${sort.value}`
: 'https://mysite.com/products'
}]
}))
</script>Why validate sort values? Prevents parameter manipulation creating infinite URLs (?sort=abc, ?sort=xyz).
Block Sort from Indexing
If sorted views don't add value (same content, different order), use noindex:
useSeoMeta({
robots: () => route.query.sort ? 'noindex, follow' : 'index, follow'
})Pagination Parameters
Each page in a sequence has unique content. Google recommends self-referencing canonicals rather than pointing every page back to page 1. See the Pagination SEO guide for full implementation details.
<script setup lang="ts">
const route = useRoute()
const page = computed(() => route.query.page || '1')
useHead(() => ({
link: [{
rel: 'canonical',
// Each page references itself
href: page.value === '1'
? 'https://mysite.com/blog'
: `https://mysite.com/blog?page=${page.value}`
}]
}))
</script>For page-number validation, supply maxPages from your data source. This excerpt normalizes a value; it does not reject an HTTP request:
const page = computed(() => {
const pageNum = Number.parseInt(route.query.page)
return pageNum > 0 && pageNum <= maxPages ? pageNum : 1
})Return an appropriate HTTP error if your route must reject an out-of-range page.
Tracking Parameters
Analytics parameters (utm_, fbclid, gclid) don't change content but create duplicate URLs.
Strip Tracking Params
Use the canonicalQueryWhitelist configuration below to keep content parameters and omit tracking parameters. Choose the list for your site; do not remove parameters that change the page's content.
Server-Side Parameter Handling
Canonical metadata can omit tracking parameters without redirecting the visitor. If your app needs redirects, parse the pathname and query separately. Preserve content parameters and verify that the destination does not redirect again. A route rule with an empty redirect object is not an implementation.
Parameter Order Consistency
Generate equivalent URLs with a consistent parameter order. Use that order in both internal links and canonical URLs. Do not reorder or remove parameters unless your application treats the resulting URLs as equivalent.
Search Parameters
Search queries create unique URLs for each search term. Treatment depends on result quality:
Block Thin Search Results
Decide whether search results provide useful content before making them indexable. Google does not set a minimum result count for this decision.
If you use noindex, allow the crawler to fetch the page and read the directive. Authentication is required for private results.
robots.txt for Search
If you choose to prevent crawling of search URLs, this is a crawl-control pattern. Google cannot read a noindex or canonical on a URL blocked by robots.txt:
User-agent: *
Disallow: /search?
# Or use URL patterns
Disallow: /*?q=
Disallow: /*?query=Testing Parameter Handling
In Google Search Console's URL Inspection tool, enter a URL with parameters and compare "User-declared canonical" against "Google-selected canonical". A mismatch means Google disagrees with the canonical you set, so check that first before digging further.
Manual Verification
# Check canonical in HTML
curl https://mysite.com/products?sort=price | grep canonical
# Should return:
# <link rel="canonical" href="https://mysite.com/products?sort=price">Test Parameter Variations
Create a test matrix:
| URL | Expected Canonical | Expected Robots |
|---|---|---|
/products | Self | index, follow |
/products?sort=price | Self or base | Depends on strategy |
/products?filter=red | Depends on content | Depends on indexing policy |
/products?utm_source=twitter | Base URL | index, follow |
/products?page=2 | Self | index, follow |
robots.txt Parameter Blocking
Use these example crawl restrictions only when these variants should not be fetched. Google cannot read blocked pages' canonical or noindex metadata. Do not use robots.txt to consolidate equivalents or hide private content. Keep useful pagination URLs crawlable:
User-agent: *
# Block all URLs with these params
Disallow: /*?sessionid=
Disallow: /*?sid=
Disallow: /*&sessionid=
Disallow: /*&sid=
# Block tracking params
Disallow: /*?utm_source=
Disallow: /*?fbclid=
Disallow: /*?gclid=
# Block filter combinations
Disallow: /*?filter=
Disallow: /*&filter=Google deprecated the URL Parameters tool in Search Console in 2022. Use robots.txt or meta robots instead.
Common Mistakes
Missing initial canonical metadata: prefer a server-rendered canonical and check its resolved value. Google can also process JavaScript-generated canonicals.
Treating all variations as duplicates: separate equivalent URLs from parameters that change the content.
Inconsistent parameter handling: Some pages canonical to base, others to self. Be consistent site-wide.
Ignoring tracking parameters: Analytics params create duplicate URLs. Strip them from canonicals.
Not validating parameter values: Allows ?sort=anything creating infinite URLs. Whitelist valid values.
Automate with Nuxt SEO Utils
Nuxt SEO Utils generates canonical URLs automatically from your site URL and route path, keeping only the query parameters listed in canonicalQueryWhitelist. The default whitelist covers page, sort, filter, search, q, category, and tag; anything else, including utm_*, fbclid, and gclid, gets stripped with no extra config:
export default defineNuxtConfig({
modules: ['@nuxtjs/seo'],
seo: {
// override the default whitelist if your params differ
canonicalQueryWhitelist: ['page', 'sort', 'filter', 'search', 'q', 'category', 'tag']
}
})See the canonical URL guide for the full configuration reference.
Checklist
- Set self-referencing or base-URL canonicals for every query parameter variant
- noindex filtered and search-result pages that don't add unique value
- Strip tracking parameters (
utm_,fbclid,gclid) from canonical URLs - Give valuable filter pages stable URLs, with paths or query parameters
- Validate parameter values server-side to block infinite URL variations
- Confirm canonical output with
curlor the URL Inspection tool
Pre-launch setup, post-launch verification, and ongoing monitoring. Interactive checklist with links to every guide.