Skip to content

Commit 8831def

Browse files
authored
fix(seo): use canonical SITE_URL for robots and sitemap (#4598)
* fix(seo): use canonical SITE_URL for robots and sitemap * fix(seo): drop /templates from sitemap and guard robots/sitemap in seo test
1 parent 4295a5c commit 8831def

3 files changed

Lines changed: 34 additions & 6 deletions

File tree

apps/sim/app/(landing)/seo.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,21 @@ const SEO_SCAN_DIRS = [
2626

2727
const 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+
3244
function 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[] = []

apps/sim/app/robots.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { MetadataRoute } from 'next'
2-
import { getBaseUrl } from '@/lib/core/utils/urls'
2+
import { SITE_URL } from '@/lib/core/utils/urls'
33

44
const DISALLOWED_PATHS = [
55
'/api/',
@@ -45,8 +45,6 @@ const LINK_PREVIEW_BOTS = [
4545
]
4646

4747
export default function robots(): MetadataRoute.Robots {
48-
const baseUrl = getBaseUrl()
49-
5048
return {
5149
rules: [
5250
{ userAgent: '*', allow: '/', disallow: DISALLOWED_PATHS },
@@ -56,6 +54,6 @@ export default function robots(): MetadataRoute.Robots {
5654
disallow: LINK_PREVIEW_DISALLOWED_PATHS,
5755
},
5856
],
59-
sitemap: [`${baseUrl}/sitemap.xml`, `${baseUrl}/blog/sitemap-images.xml`],
57+
sitemap: [`${SITE_URL}/sitemap.xml`, `${SITE_URL}/blog/sitemap-images.xml`],
6058
}
6159
}

apps/sim/app/sitemap.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import type { MetadataRoute } from 'next'
22
import { COURSES } from '@/lib/academy/content'
33
import { getAllPostMeta } from '@/lib/blog/registry'
4-
import { getBaseUrl } from '@/lib/core/utils/urls'
4+
import { SITE_URL } from '@/lib/core/utils/urls'
55
import integrations from '@/app/(landing)/integrations/data/integrations.json'
66
import { ALL_CATALOG_MODELS, MODEL_PROVIDERS_WITH_CATALOGS } from '@/app/(landing)/models/utils'
77

88
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
9-
const baseUrl = getBaseUrl()
9+
const baseUrl = SITE_URL
1010
const posts = await getAllPostMeta()
1111

1212
const latestPostDate =
@@ -46,6 +46,9 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
4646
{
4747
url: `${baseUrl}/partners`,
4848
},
49+
{
50+
url: `${baseUrl}/contact`,
51+
},
4952
{
5053
url: `${baseUrl}/terms`,
5154
lastModified: new Date('2024-10-14'),

0 commit comments

Comments
 (0)