Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 12x 12x 12x 12x 12x 5x 7x 7x 5x 3x 7x 3x 7x 2x 5x 1x 1x 1x 1x 1x 1x 1x 4x | export interface CanonicalInput {
baseUrl: string;
pathname: string;
searchParams: URLSearchParams;
allowedCanonicalParams?: string[];
}
export interface CanonicalOutput {
canonicalUrl: string;
robots: string;
}
export function computeCanonical(input: CanonicalInput): CanonicalOutput {
const { baseUrl, pathname, searchParams, allowedCanonicalParams = [] } = input;
const base = `${baseUrl}${pathname}`;
// Rule 1 & 5: page param handling
const pageRaw = searchParams.get("page");
const pageNum = pageRaw !== null ? parseInt(pageRaw, 10) : 1;
if (pageNum > 1) {
// Rule 1: page 2+ → noindex, canonical strips all query params
return { canonicalUrl: base, robots: "noindex, follow" };
}
// At this point page is absent, "1", or invalid (treat as 1).
// Collect non-page params to check for filters.
const nonPageParams: string[] = [];
for (const key of searchParams.keys()) {
if (key !== "page") {
nonPageParams.push(key);
}
}
// Rule 2: any param NOT in allowedCanonicalParams present → index, canonical is bare base
const hasDisallowedParam = nonPageParams.some(
(key) => !allowedCanonicalParams.includes(key),
);
if (hasDisallowedParam) {
return { canonicalUrl: base, robots: "index, follow" };
}
// Rule 3: only allowedCanonicalParams present → preserve them in canonical
if (nonPageParams.length > 0) {
const preserved = new URLSearchParams();
for (const key of allowedCanonicalParams) {
const values = searchParams.getAll(key);
for (const v of values) {
preserved.append(key, v);
}
}
const qs = preserved.toString();
return { canonicalUrl: qs ? `${base}?${qs}` : base, robots: "index, follow" };
}
// Rule 4: no params (or only page=1) → canonical is bare base
return { canonicalUrl: base, robots: "index, follow" };
}
|