diff --git a/server/hydrogen-render/render-page-html.js b/server/hydrogen-render/render-page-html.js
index d209aa30..af1d60ab 100644
--- a/server/hydrogen-render/render-page-html.js
+++ b/server/hydrogen-render/render-page-html.js
@@ -71,6 +71,11 @@ function renderPageHtml({
metaImageUrl = pageOptions.imageUrl;
}
+ let maybeRelCanonical = '';
+ if (pageOptions.canonicalUrl) {
+ maybeRelCanonical = sanitizeHtml(``);
+ }
+
const pageHtml = `
@@ -83,6 +88,7 @@ function renderPageHtml({
${sanitizeHtml(``)}
+ ${maybeRelCanonical}
${styles
.map(
(styleUrl) =>
diff --git a/server/routes/room-routes.js b/server/routes/room-routes.js
index 2044993f..c0a2be5c 100644
--- a/server/routes/room-routes.js
+++ b/server/routes/room-routes.js
@@ -917,6 +917,18 @@ router.get(
blockedBySafeSearch: isNsfw,
entryPoint: 'client/js/entry-client-hydrogen.js',
locationHref: urlJoin(basePath, req.originalUrl),
+ canonicalUrl: matrixPublicArchiveURLCreator.archiveUrlForDate(
+ roomIdOrAlias,
+ new Date(toTimestamp),
+ {
+ preferredPrecision: precisionFromUrl,
+ // We purposely omit `scrollStartEventId` here because the canonical location
+ // for any given event ID is the page it resides on.
+ //
+ // We can avoid passing along the `viaServers` because we already joined the
+ // room above (see `ensureRoomJoined`).
+ }
+ ),
shouldIndex,
cspNonce: res.locals.cspNonce,
};