@@ -26,9 +26,21 @@ const SEO_SCAN_DIRS = [
2626
2727const SEO_SCAN_INDIVIDUAL_FILES = [
2828 path . resolve ( APP_DIR , 'page.tsx' ) ,
29+ path . resolve ( APP_DIR , 'robots.ts' ) ,
30+ path . resolve ( APP_DIR , 'sitemap.ts' ) ,
2931 path . resolve ( SIM_ROOT , 'ee' , 'whitelabeling' , 'metadata.ts' ) ,
3032]
3133
34+ /**
35+ * Files whose entire URL output is SEO-facing (robots.txt, sitemap.xml).
36+ * Unlike metadata exports, these don't use `metadataBase`, so the existing
37+ * `getBaseUrl()`-in-metadata check would miss a regression here.
38+ */
39+ const SEO_DEFAULT_EXPORT_FILES = [
40+ path . resolve ( APP_DIR , 'robots.ts' ) ,
41+ path . resolve ( APP_DIR , 'sitemap.ts' ) ,
42+ ]
43+
3244function collectFiles ( dir : string , exts : string [ ] ) : string [ ] {
3345 const results : string [ ] = [ ]
3446 if ( ! fs . existsSync ( dir ) ) return results
@@ -97,6 +109,21 @@ describe('SEO canonical URLs', () => {
97109 ) . toHaveLength ( 0 )
98110 } )
99111
112+ it ( 'robots.ts and sitemap.ts do not import getBaseUrl' , ( ) => {
113+ const violations : string [ ] = [ ]
114+ for ( const file of SEO_DEFAULT_EXPORT_FILES ) {
115+ if ( ! fs . existsSync ( file ) ) continue
116+ const content = fs . readFileSync ( file , 'utf-8' )
117+ if ( content . includes ( 'getBaseUrl' ) ) {
118+ violations . push ( path . relative ( SIM_ROOT , file ) )
119+ }
120+ }
121+ expect (
122+ violations ,
123+ `robots.ts/sitemap.ts must use SITE_URL, not getBaseUrl():\n${ violations . join ( '\n' ) } `
124+ ) . toHaveLength ( 0 )
125+ } )
126+
100127 it ( 'public pages do not use getBaseUrl() for SEO metadata' , ( ) => {
101128 const files = getAllSeoFiles ( [ '.ts' , '.tsx' ] )
102129 const violations : string [ ] = [ ]
0 commit comments