Adios
BlogNext.js Ecommerce

Next.js Ecommerce

How to Build Faceted Navigation in Next.js Without an SEO Crawl Trap

Build useful Next.js category filters while controlling canonical URLs, parameter normalization, pagination, crawlable combinations, and empty results.

Adios teamUpdated July 17, 20268 min read

Filters can create millions of technically valid URLs from a modest catalog. Only a small, intentional subset usually deserves to become a search landing page.

Separate hierarchy from filter state

Trail Supply uses durable category routes such as /women/jackets. Color, size, waterproof rating, price range, and sort order refine that set. Category hierarchy communicates the catalog; most filter state exists to help a shopper within that category.

List every filter, allowed value, default, and interaction. Decide which combinations have distinct search demand, enough products, stable inventory, and unique explanatory content. Those can become curated landing pages; the rest remain useful non-indexable application states.

Normalize parameter URLs

Use one parameter name per filter, lowercase normalized values, a stable sort order, and no default-valued parameters. Reject unknown filters and values. Redirect equivalent URL shapes to the normalized representation when that improves consistency.

A filter parser should return typed application state and a normalized URL, not pass arbitrary searchParams into database queries. Limit value count and complexity to protect both the database and the crawl surface.

const filters = filterSchema.parse({
  color: searchParams.color,
  size: searchParams.size,
  sort: searchParams.sort ?? "featured",
});

const normalized = buildFilterUrl("/women/jackets", filters);

Render filtered results on the server

Read searchParams in the page, validate the filters, query products on the server, and render the result count, active filters, product links, and pagination in the initial response. Client Components can update filters through navigation without owning the catalog query.

Use stable loading and empty states. An invalid filter should not become a successful empty category. Return or redirect according to the normalization policy, and provide a useful clear-filter path for a valid combination with no results.

Choose indexable combinations explicitly

Maintain an allowlist or content-backed landing-page catalog for combinations such as women's waterproof jackets. An indexable combination needs its own canonical URL, title, H1, description, internal links, and sufficient stable results. It should be reviewed like any other content page.

Do not infer indexability merely because a combination currently returns products. Inventory changes can turn it empty tomorrow, and several different combinations may serve the same intent. Product and search teams should own the approved set together.

Handle pagination and sorting

Give paginated category results stable URLs and ordinary links so users and crawlers can reach deeper products. Do not canonicalize every page to page one when those pages contain different product links. Sorting usually changes order rather than the resource and normally should not create a separate search landing page.

Keep pagination behavior stable when filters change. Reset to the first page after a new filter, reject out-of-range pages with a meaningful status, and ensure the canonical represents the normalized state actually rendered.

Measure crawl behavior and server cost

Inspect request logs for unexpected parameters, repeated empty combinations, deep pagination, and bot-driven database load. Compare sitemap URLs with indexed and discovered URLs. A widening gap often reveals accidental discovery or weak landing pages.

Cache approved category and landing pages with targeted tags, but bound arbitrary filter queries and protect the database. Adios runtime logs keep request behavior attached to the serving release, helping the team connect a crawl spike to the routing or link change that produced it.

Test the policy before promotion

Build a table of normal, equivalent, approved, empty, invalid, sorted, paginated, and out-of-range URLs. Assert their final status, redirect, canonical, robots value, H1, result set, internal links, and sitemap membership. This turns a vague SEO policy into executable expectations.

Deploy the candidate to an Adios preview and run the table against the production build. Inspect logs for unexpected query load and verify the health route. Promote the routing change only when the normalized behavior is correct; the canonical custom domain stays on the last healthy version otherwise.

  All articles