CMS mode: members-only communities with an external canonical home#3671
Open
tefkah wants to merge 1 commit into
Open
CMS mode: members-only communities with an external canonical home#3671tefkah wants to merge 1 commit into
tefkah wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds “CMS mode” support for communities that use PubPub as an editorial backend while publishing content on an external canonical site. The change gates public access to members-only, introduces canonical URL helpers for content-facing links (citations/feeds/deposits), and updates crawler behavior (noindex/robots/sitemaps) accordingly.
Changes:
- Add CMS-mode gating (members-only) with bypasses for auth/legal/dashboard and crawler endpoints, plus a login CTA on the “community not found” page.
- Introduce
canonical*Urlhelpers and switch Crossref/RSS/citations/connection cards/SSR canonical tags to point at the external canonical home for CMS communities. - Add CMS settings + superadmin-gated canonical URL fields in the dashboard, with schema + DB migration + unit tests.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/pubEdge/helpers.ts | Use canonical pub URLs for pub-edge link generation. |
| utils/crossref/transform/pub.js | Use canonical pub URL in Crossref pub deposits. |
| utils/crossref/transform/community.js | Use canonical community URL in Crossref community deposits. |
| utils/crossref/transform/collection.js | Use canonical collection URL in Crossref collection deposits. |
| utils/cms.ts | Add CMS/spam gate bypass helpers for auth/legal/dashboard/crawler paths. |
| utils/canonicalUrls.js | Add canonical URL helpers for community/collection/pub. |
| utils/api/schemas/community.ts | Add CMS + canonical URL fields to the community API schema. |
| utils/tests/cms.test.ts | Add unit tests for canonical URL helpers and bypass path logic. |
| tools/migrations/2026_07_23_addCmsModeToCommunities.js | Add CMS/canonical URL columns to Communities. |
| server/utils/ssr.tsx | Add noindex,nofollow meta for CMS communities. |
| server/utils/initData.ts | Enforce CMS/spam gating and throw a new private-community error. |
| server/utils/errors.ts | Render “community not found” with a server-side login prompt for logged-out users. |
| server/utils/citations/generateCitationHtml.ts | Use canonical pub URL for citation output. |
| server/rss/queries.ts | Use canonical community/pub URLs in RSS feeds. |
| server/routes/sitemap.ts | Disable sitemaps for CMS communities. |
| server/routes/robots.ts | Disallow crawling for CMS communities. |
| server/routes/pubDocument.tsx | Use canonical pub URL for SSR canonical link. |
| server/errorPages/communityNotFound.html | Add styling + placeholder for injected login CTA. |
| server/doi/queries.ts | Fetch canonical URL fields for DOI/Crossref operations. |
| server/doi/api.ts | (Needs cleanup) Debug logging added in auth helper. |
| server/community/permissions.ts | Allow admins to toggle CMS mode; superadmins to set canonical URL fields. |
| server/community/model.ts | Add CMS/canonical fields to Community model (comment needs correction). |
| client/containers/DashboardSettings/CommunitySettings/UnderlaySettings.tsx | Add SuperAdminTag to Underlay section heading and IDs. |
| client/containers/DashboardSettings/CommunitySettings/CommunitySettings.tsx | Add a “CMS” settings subtab for admins/superadmins. |
| client/containers/DashboardSettings/CommunitySettings/CmsSettings.tsx | New CMS settings UI, including superadmin-only canonical URL fields. |
| client/components/SuperAdminTag/SuperAdminTag.tsx | New reusable superadmin-only label component. |
| client/components/index.ts | Export SuperAdminTag. |
Comments suppressed due to low confidence (1)
utils/canonicalUrls.js:167
- canonicalPubUrl applies canonicalPubUrlTemplate/canonicalBaseUrl whenever those fields are set, regardless of cmsMode. To keep canonical overrides isolated to CMS-mode communities (and avoid surprising URL changes if a superadmin fills these fields on a normal community), gate these branches on community.cmsMode.
export const canonicalPubUrl = (community, pub, options = {}) => {
if (community && community.canonicalPubUrlTemplate) {
return community.canonicalPubUrlTemplate.replace(/\{slug\}/g, pub.slug);
}
if (community && community.canonicalBaseUrl) {
const url = pubUrl(community, pub, { ...options, absolute: true });
return url.replace(communityUrl(community), canonicalCommunityUrl(community));
}
return pubUrl(community, pub, options);
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
16
to
+21
| const permissions = await getPermissions(requestIds); | ||
| console.log('permissions', permissions); | ||
| const isAuthenticated = | ||
| (target === 'pub' && permissions.pub) || | ||
| (target === 'collection' && permissions.collection); | ||
| console.log('isAuthenticated', isAuthenticated); |
Comment on lines
+133
to
+138
| export const canonicalCommunityUrl = (community) => { | ||
| if (community.canonicalBaseUrl) { | ||
| return community.canonicalBaseUrl.replace(/\/+$/, ''); | ||
| } | ||
| return communityUrl(community); | ||
| }; |
Comment on lines
+259
to
+262
| /** | ||
| * CMS mode: the community is only visible to members; public visitors are | ||
| * redirected to canonicalBaseUrl (or shown a not-found page if none is set). | ||
| */ |
Comment on lines
+104
to
+107
| canonicalPubUrlTemplate: z | ||
| .string() | ||
| .regex(/\{slug\}/, 'Template must contain {slug}') | ||
| .nullable(), |
Comment on lines
+25
to
+32
| <SettingsSection | ||
| id="cms-mode" | ||
| title={ | ||
| <> | ||
| CMS mode <SuperAdminTag /> | ||
| </> | ||
| } | ||
| description={ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds CMS mode for communities that use PubPub as an editorial backend and publish elsewhere (e.g. a site fed by Push to Underlay):
{slug}). Canonical tags, citations, export front matter, connection cards, RSS, and new Crossref deposits then point at the external site.noindex,Disallow: /in robots.txt, and no sitemap.CMS mode and the Underlay integration are independent toggles.
Design notes
communityUrloverride — it also powers in-app navigation. Newcanonical*Urlhelpers are applied only at content chokepoints and fall back to normal URLs, so non-CMS communities are unaffected (Crossref snapshots pass unchanged)./dashand crawler files (utils/cms.ts).cmsModeis admin-editable; the URL fields are superadmin-only, marked with the new reusableSuperAdminTag(also on the Underlay section) — use it on any superadmin-gated setting going forward.Migration
2026_07_23_addCmsModeToCommunities.js: addscmsMode,canonicalBaseUrl,canonicalPubUrlTemplatetoCommunities. Reversible, no backfill.Deferred
approvedByTargetalready covers inbound edges, and edge cards link to the canonical site automatically.