Skip to content

Commit 123957b

Browse files
committed
fix(canonical): slugless canonical for singletons; drop volatile listing query params
Singletons are served at their slugless listing URL (ListingController forwards a singleton listing to the record), but getCanonicalRouteAndParams returned the record-detail route, exposing two URLs for identical content (/o-spolecnosti and /o-spolecnosti/o-nas). Canonicalize singletons to the slugless /{singularSlug} URL instead. Also stop merging listing query params (order/status/filters) into the listing canonical, where they appeared as ?order=-createdAt&status=published.
1 parent 2ba6e81 commit 123957b

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

src/Controller/Frontend/ListingController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,15 @@ public function listing(Request $request, ContentRepository $contentRepository,
6969

7070
$records = $this->setRecords($content, $amountPerPage, $page);
7171

72-
// Set canonical URL
72+
// Set canonical URL. Note: query params (order/status/filters from
73+
// parseQueryParams) are intentionally NOT merged in — they are volatile and
74+
// would pollute the canonical (e.g. ?order=-createdAt&status=published).
7375
$this->canonical->setPath(
7476
'listing_locale',
75-
array_merge([
77+
[
7678
'contentTypeSlug' => $contentType->get('slug'),
7779
'_locale' => $request->getLocale(),
78-
], $params)
80+
]
7981
);
8082

8183
// Render

src/Utils/ContentHelper.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ private function getCanonicalRouteAndParams(Content $record, ?string $locale = n
6868
];
6969
}
7070

71+
// Singletons are served at their slugless listing URL: ListingController
72+
// forwards a singleton "listing" to the record. Canonicalize to that URL
73+
// (`/{singularSlug}`) instead of the record-detail route
74+
// (`/{singularSlug}/{slug}`), so a singleton has a single, slugless URL
75+
// rather than two URLs serving identical content.
76+
if ($record->getDefinition()->get('singleton')) {
77+
return [
78+
'route' => 'listing_locale',
79+
'params' => [
80+
'contentTypeSlug' => $record->getContentTypeSingularSlug(),
81+
'_locale' => $locale,
82+
],
83+
];
84+
}
85+
7186
return [
7287
'route' => $record->getDefinition()->get('record_route'),
7388
'params' => [

0 commit comments

Comments
 (0)