// Slugs a CMS page may not claim, because a top-level page lives at `/:slug` and // must never shadow an existing named route (SPA route or API namespace). The // catch-all page route is matched only after these, but reserving the names up // front gives the admin a clear "that slug is reserved" error at create time // instead of a silently unreachable page. // // Kept as a Set of lowercase single-segment slugs. Page slugs are validated to a // single segment (^[a-z0-9-]+$) so we only need to guard first path segments. const RESERVED_SLUGS = new Set([ // API / infrastructure 'api', 'internal', 'uploads', 'assets', 'static', 'public', // Auth / account 'login', 'logout', 'register', 'account', 'auth', // Admin app 'admin', // Existing top-level SPA sections 'site', 'wiki', 'news', 'newsletter', 'screenshots', 'five-on-friday', 'about', 'status', // Page-builder's own surface 'pages', 'preview', ]) /** @returns {boolean} true if `slug` collides with a reserved route name. */ function isReservedSlug(slug) { return RESERVED_SLUGS.has(String(slug).toLowerCase()) } module.exports = { RESERVED_SLUGS, isReservedSlug }