Skip to content

Commit 4b6944e

Browse files
authored
Generate robots.txt (#11)
* Generate robot.txt * Generate robots.txt during prerender * Fix types
1 parent d241fb5 commit 4b6944e

File tree

5 files changed

+100
-4
lines changed

5 files changed

+100
-4
lines changed

app.config.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616

1717
import type { ModuleOptions } from 'nuxt-icon'
18+
import type { DeepPartial } from './utils/DeepPartial'
19+
import type { RobotsTxtOptions } from './server/routes/robots.txt'
1820

1921
interface ExactproDocsOptions {
2022
/**
@@ -35,20 +37,26 @@ interface ExactproDocsOptions {
3537
*
3638
* @default 'master'
3739
*/
38-
branch?: string
40+
branch: string
3941
/**
4042
* Path to the directory with documentation files on GitHub
4143
* Specify if the documentation is stored in a subdirectory of the repository.
4244
*
4345
* @default '/'
4446
*/
45-
docsDir?: string
47+
docsDir: string
48+
}
49+
seo?: {
50+
sitemap?: {
51+
baseUrl?: string
52+
}
53+
robots?: RobotsTxtOptions[]
4654
}
4755
}
4856

4957
declare module 'nuxt/schema' {
5058
interface AppConfigInput {
51-
exactproDocs?: ExactproDocsOptions
59+
exactproDocs?: DeepPartial<ExactproDocsOptions>
5260
// TODO: Workaround for nuxt-icon types module, delete when https://github.com/nuxt-modules/icon/pull/63 is resolved
5361
nuxtIcon?: ModuleOptions
5462
}
@@ -62,7 +70,7 @@ export default defineAppConfig({
6270
branch: 'master',
6371
docsDir: '/'
6472
}
65-
},
73+
} as ExactproDocsOptions,
6674
// TODO: Workaround for nuxt-icon types module, delete when https://github.com/nuxt-modules/icon/pull/63 is resolved
6775
nuxtIcon: {}
6876
})

docs/app.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
export default defineAppConfig({
1818
exactproDocs: {
1919
title: 'Docs Template Project',
20+
seo: {
21+
sitemap: {
22+
baseUrl: 'https://exactpro.github.io/docs-toolkit'
23+
},
24+
robots: [{ UserAgent: '*' }, { Allow: '/' }]
25+
},
2026
github: {
2127
repoLink: 'https://github.com/exactpro/docs-toolkit',
2228
branch: 'master',

nuxt.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ export default defineNuxtConfig({
3636
}
3737
},
3838
modules: ['@nuxt/content', '@nuxtjs/tailwindcss', 'nuxt-icon'],
39+
nitro: {
40+
prerender: {
41+
routes: ['/robots.txt']
42+
}
43+
},
3944
content: {
4045
documentDriven: true,
4146
highlight: {

server/routes/robots.txt.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const keysToTemplates = {
18+
UserAgent: (input: string) => `User-agent: ${input}`,
19+
CrawlDelay: (input: string) => `Crawl-delay: ${input}`,
20+
Disallow: (input: string) => `Disallow: ${input}`,
21+
Allow: (input: string) => `Allow: ${input}`,
22+
Host: (input: string) => `Host: ${input}`,
23+
Sitemap: (input: string) => `Sitemap: ${input}`,
24+
CleanParam: (input: string) => `Clean-param: ${input}`,
25+
Comment: (input: string) => `# ${input}`
26+
}
27+
28+
export type RobotsTxtOptions = {
29+
[key in keyof typeof keysToTemplates]?: string
30+
} & {
31+
BlankLine?: boolean
32+
}
33+
34+
export default defineEventHandler((event) => {
35+
setHeader(event, 'Content-Type', 'text/plain')
36+
const lines: string[] = []
37+
const config = useAppConfig()
38+
for (const robotOptionsItem of config.exactproDocs?.seo?.robots ?? []) {
39+
for (const [key, value] of Object.entries(robotOptionsItem)) {
40+
if (typeof value === 'string') {
41+
lines.push(keysToTemplates[key as keyof typeof keysToTemplates](value))
42+
}
43+
// If BlankLine is true, add blank line
44+
if (typeof value === 'boolean' && value) {
45+
lines.push('')
46+
}
47+
}
48+
}
49+
if (config.exactproDocs?.seo?.sitemap?.baseUrl) {
50+
lines.push('')
51+
lines.push(
52+
`Sitemap: ${config.exactproDocs.seo.sitemap.baseUrl}/sitemap.xml`
53+
)
54+
}
55+
return lines.join('\n')
56+
})

utils/DeepPartial.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export type DeepPartial<T> = T extends object
18+
? {
19+
[P in keyof T]?: DeepPartial<T[P]>
20+
}
21+
: T

0 commit comments

Comments
 (0)