@murshisoft/docus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +116 -0
- package/app/app.config.ts +33 -0
- package/app/app.vue +79 -0
- package/app/components/IconMenuToggle.vue +83 -0
- package/app/components/LanguageSelect.vue +83 -0
- package/app/components/OgImage/OgImageDocs.vue +78 -0
- package/app/components/OgImage/OgImageLanding.vue +75 -0
- package/app/components/app/AppFooter.vue +11 -0
- package/app/components/app/AppFooterLeft.vue +5 -0
- package/app/components/app/AppFooterRight.vue +30 -0
- package/app/components/app/AppHeader.vue +82 -0
- package/app/components/app/AppHeaderBody.vue +13 -0
- package/app/components/app/AppHeaderCTA.vue +3 -0
- package/app/components/app/AppHeaderCenter.vue +10 -0
- package/app/components/app/AppHeaderLogo.vue +16 -0
- package/app/components/docs/DocsAsideLeftBody.vue +12 -0
- package/app/components/docs/DocsAsideLeftTop.vue +3 -0
- package/app/components/docs/DocsAsideRightBottom.vue +18 -0
- package/app/components/docs/DocsPageHeaderLinks.vue +96 -0
- package/app/composables/useDocusI18n.ts +35 -0
- package/app/error.vue +79 -0
- package/app/layouts/default.vue +5 -0
- package/app/layouts/docs.vue +15 -0
- package/app/pages/[[lang]]/[...slug].vue +145 -0
- package/app/plugins/i18n.ts +40 -0
- package/app/templates/landing.vue +44 -0
- package/app/types/index.d.ts +42 -0
- package/app/utils/navigation.ts +7 -0
- package/app/utils/prerender.ts +12 -0
- package/content.config.ts +67 -0
- package/i18n/locales/ar.json +22 -0
- package/i18n/locales/be.json +23 -0
- package/i18n/locales/bg.json +22 -0
- package/i18n/locales/bn.json +22 -0
- package/i18n/locales/ca.json +22 -0
- package/i18n/locales/ckb.json +18 -0
- package/i18n/locales/cs.json +22 -0
- package/i18n/locales/da.json +22 -0
- package/i18n/locales/de.json +22 -0
- package/i18n/locales/el.json +22 -0
- package/i18n/locales/en.json +22 -0
- package/i18n/locales/es.json +22 -0
- package/i18n/locales/et.json +22 -0
- package/i18n/locales/fi.json +22 -0
- package/i18n/locales/fr.json +22 -0
- package/i18n/locales/he.json +22 -0
- package/i18n/locales/hi.json +22 -0
- package/i18n/locales/hy.json +22 -0
- package/i18n/locales/it.json +22 -0
- package/i18n/locales/ja.json +22 -0
- package/i18n/locales/kk.json +22 -0
- package/i18n/locales/km.json +22 -0
- package/i18n/locales/ko.json +22 -0
- package/i18n/locales/ky.json +22 -0
- package/i18n/locales/lb.json +22 -0
- package/i18n/locales/ms.json +22 -0
- package/i18n/locales/nb.json +22 -0
- package/i18n/locales/nl.json +22 -0
- package/i18n/locales/pl.json +23 -0
- package/i18n/locales/ro.json +22 -0
- package/i18n/locales/ru.json +23 -0
- package/i18n/locales/sl.json +22 -0
- package/i18n/locales/sv.json +22 -0
- package/i18n/locales/uk.json +22 -0
- package/i18n/locales/ur.json +22 -0
- package/i18n/locales/vi.json +22 -0
- package/modules/config.ts +116 -0
- package/modules/css.ts +32 -0
- package/modules/routing.ts +41 -0
- package/nuxt.config.ts +84 -0
- package/nuxt.schema.ts +218 -0
- package/package.json +55 -0
- package/server/mcp/tools/get-page.ts +60 -0
- package/server/mcp/tools/list-pages.ts +60 -0
- package/server/routes/raw/[...slug].md.get.ts +45 -0
- package/server/utils/content.ts +37 -0
- package/utils/git.ts +110 -0
- package/utils/meta.ts +29 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "atau",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Halaman tidak dijumpai",
|
|
6
|
+
"description": "Kami mohon maaf, tetapi halaman yang anda cari tidak dapat dijumpai."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Salin halaman",
|
|
12
|
+
"link": "Salin halaman Markdown",
|
|
13
|
+
"view": "Lihat sebagai Markdown",
|
|
14
|
+
"gpt": "Buka di ChatGPT",
|
|
15
|
+
"claude": "Buka di Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Komuniti",
|
|
18
|
+
"toc": "Dalam halaman ini",
|
|
19
|
+
"report": "Laporkan masalah",
|
|
20
|
+
"edit": "Edit halaman ini"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "eller",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Side ikke funnet",
|
|
6
|
+
"description": "Vi beklager, men siden du leter etter kunne ikke finnes."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Kopier side",
|
|
12
|
+
"link": "Kopier Markdown-side",
|
|
13
|
+
"view": "Vis som Markdown",
|
|
14
|
+
"gpt": "Åpne i ChatGPT",
|
|
15
|
+
"claude": "Åpne i Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Fellesskap",
|
|
18
|
+
"toc": "På denne siden",
|
|
19
|
+
"report": "Rapporter et problem",
|
|
20
|
+
"edit": "Rediger denne siden"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "of",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Pagina niet gevonden",
|
|
6
|
+
"description": "Sorry, maar deze pagina is niet gevonden."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Kopieer pagina",
|
|
12
|
+
"link": "Kopieer Markdown pagina",
|
|
13
|
+
"view": "Bekijk als Markdown",
|
|
14
|
+
"gpt": "Open in ChatGPT",
|
|
15
|
+
"claude": "Open in Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Community",
|
|
18
|
+
"toc": "Op deze pagina",
|
|
19
|
+
"report": "Rapporteer een probleem",
|
|
20
|
+
"edit": "Bewerk deze pagina"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "lub",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Nie znaleziono strony",
|
|
6
|
+
"description": "Przepraszamy, ale nie znaleziono tej strony."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Skopiuj stronę",
|
|
12
|
+
"link": "Skopiuj stronę Markdown",
|
|
13
|
+
"view": "Wyświetl jako Markdown",
|
|
14
|
+
"gpt": "Otwórz w ChatGPT",
|
|
15
|
+
"claude": "Otwórz w Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Społeczność",
|
|
18
|
+
"toc": "Na tej stronie",
|
|
19
|
+
"report": "Zgłoś problem",
|
|
20
|
+
"edit": "Edytuj tę stronę"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "sau",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Pagina nu a fost găsită",
|
|
6
|
+
"description": "Ne pare rău, dar această pagină nu a putut fi găsită."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Copiază pagina",
|
|
12
|
+
"link": "Copiază pagina în Markdown",
|
|
13
|
+
"view": "Vezi ca Markdown",
|
|
14
|
+
"gpt": "Deschide în ChatGPT",
|
|
15
|
+
"claude": "Deschide în Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Comunitate",
|
|
18
|
+
"toc": "Pe această pagină",
|
|
19
|
+
"report": "Raportează o problemă",
|
|
20
|
+
"edit": "Editează această pagină"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "или",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Страница не найдена",
|
|
6
|
+
"description": "Извините, но запрашиваемая страница не найдена."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Копировать страницу",
|
|
12
|
+
"link": "Копировать Markdown-страницу",
|
|
13
|
+
"view": "Просмотреть как Markdown",
|
|
14
|
+
"gpt": "Открыть в ChatGPT",
|
|
15
|
+
"claude": "Открыть в Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Сообщество",
|
|
18
|
+
"toc": "На этой странице",
|
|
19
|
+
"report": "Сообщить о проблеме",
|
|
20
|
+
"edit": "Редактировать эту страницу"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "ali",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Stran ni bila najdena",
|
|
6
|
+
"description": "Opravičujemo se, vendar stran, ki jo iščete, ni bila najdena."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Kopiraj stran",
|
|
12
|
+
"link": "Kopiraj Markdown stran",
|
|
13
|
+
"view": "Prikaži kot Markdown",
|
|
14
|
+
"gpt": "Odpri v ChatGPT",
|
|
15
|
+
"claude": "Odpri v Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Skupnost",
|
|
18
|
+
"toc": "Na tej strani",
|
|
19
|
+
"report": "Prijavi težavo",
|
|
20
|
+
"edit": "Uredi to stran"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "eller",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Sidan hittades inte",
|
|
6
|
+
"description": "Vi ber om ursäkt, men sidan du letar efter kunde inte hittas."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Kopiera sida",
|
|
12
|
+
"link": "Kopiera Markdown-sida",
|
|
13
|
+
"view": "Visa som Markdown",
|
|
14
|
+
"gpt": "Öppna i ChatGPT",
|
|
15
|
+
"claude": "Öppna i Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Gemenskap",
|
|
18
|
+
"toc": "På denna sida",
|
|
19
|
+
"report": "Rapportera ett problem",
|
|
20
|
+
"edit": "Redigera denna sida"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "або",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Сторінку не знайдено",
|
|
6
|
+
"description": "Вибачте, але сторінку, яку ви шукаєте, не знайдено."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Скопіювати сторінку",
|
|
12
|
+
"link": "Скопіювати Markdown сторінку",
|
|
13
|
+
"view": "Переглянути як Markdown",
|
|
14
|
+
"gpt": "Відкрити в ChatGPT",
|
|
15
|
+
"claude": "Відкрити в Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Спільнота",
|
|
18
|
+
"toc": "На цій сторінці",
|
|
19
|
+
"report": "Повідомити про проблему",
|
|
20
|
+
"edit": "Редагувати цю сторінку"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "یا",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "صفحہ نہیں ملا",
|
|
6
|
+
"description": "ہمیں افسوس ہے، لیکن آپ جو صفحہ تلاش کر رہے ہیں وہ موجود نہیں ہے۔"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "صفحہ کاپی کریں",
|
|
12
|
+
"link": "Markdown صفحہ کاپی کریں",
|
|
13
|
+
"view": "Markdown کے طور پر دیکھیں",
|
|
14
|
+
"gpt": "ChatGPT میں کھولیں",
|
|
15
|
+
"claude": "Claude میں کھولیں"
|
|
16
|
+
},
|
|
17
|
+
"links": "کمیونٹی",
|
|
18
|
+
"toc": "اس صفحے پر",
|
|
19
|
+
"report": "مسئلہ کی اطلاع دیں",
|
|
20
|
+
"edit": "اس صفحے کو ترمیم کریں"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"or": "hoặc",
|
|
4
|
+
"error": {
|
|
5
|
+
"title": "Không tìm thấy trang",
|
|
6
|
+
"description": "Chúng tôi xin lỗi, nhưng trang bạn đang tìm kiếm không tồn tại."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"docs": {
|
|
10
|
+
"copy": {
|
|
11
|
+
"page": "Sao chép trang",
|
|
12
|
+
"link": "Sao chép trang Markdown",
|
|
13
|
+
"view": "Xem dưới dạng Markdown",
|
|
14
|
+
"gpt": "Mở trong ChatGPT",
|
|
15
|
+
"claude": "Mở trong Claude"
|
|
16
|
+
},
|
|
17
|
+
"links": "Cộng đồng",
|
|
18
|
+
"toc": "Trên trang này",
|
|
19
|
+
"report": "Báo cáo sự cố",
|
|
20
|
+
"edit": "Chỉnh sửa trang này"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createResolver, defineNuxtModule } from '@nuxt/kit'
|
|
2
|
+
import { defu } from 'defu'
|
|
3
|
+
import { existsSync } from 'node:fs'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import { inferSiteURL, getPackageJsonMetadata } from '../utils/meta'
|
|
6
|
+
import { getGitBranch, getGitEnv, getLocalGitInfo } from '../utils/git'
|
|
7
|
+
|
|
8
|
+
export default defineNuxtModule({
|
|
9
|
+
meta: {
|
|
10
|
+
name: 'config',
|
|
11
|
+
},
|
|
12
|
+
async setup(_options, nuxt) {
|
|
13
|
+
const dir = nuxt.options.rootDir
|
|
14
|
+
const url = inferSiteURL()
|
|
15
|
+
const meta = await getPackageJsonMetadata(dir)
|
|
16
|
+
const gitInfo = await getLocalGitInfo(dir) || getGitEnv()
|
|
17
|
+
const siteName = nuxt.options?.site?.name || meta.name || gitInfo?.name || ''
|
|
18
|
+
|
|
19
|
+
nuxt.options.llms = defu(nuxt.options.llms, {
|
|
20
|
+
domain: url,
|
|
21
|
+
title: siteName,
|
|
22
|
+
description: meta.description || '',
|
|
23
|
+
full: {
|
|
24
|
+
title: siteName,
|
|
25
|
+
description: meta.description || '',
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
nuxt.options.site = defu(nuxt.options.site, {
|
|
30
|
+
url,
|
|
31
|
+
name: siteName,
|
|
32
|
+
debug: false,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
nuxt.options.appConfig.header = defu(nuxt.options.appConfig.header, {
|
|
36
|
+
title: siteName,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
nuxt.options.appConfig.seo = defu(nuxt.options.appConfig.seo, {
|
|
40
|
+
titleTemplate: `%s - ${siteName}`,
|
|
41
|
+
title: siteName,
|
|
42
|
+
description: meta.description || '',
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
nuxt.options.appConfig.github = defu(nuxt.options.appConfig.github, {
|
|
46
|
+
owner: gitInfo?.owner,
|
|
47
|
+
name: gitInfo?.name,
|
|
48
|
+
url: gitInfo?.url,
|
|
49
|
+
branch: getGitBranch(),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
** I18N
|
|
54
|
+
*/
|
|
55
|
+
if (nuxt.options.i18n && nuxt.options.i18n.locales) {
|
|
56
|
+
const { resolve } = createResolver(import.meta.url)
|
|
57
|
+
|
|
58
|
+
// Filter locales to only include existing ones
|
|
59
|
+
const filteredLocales = nuxt.options.i18n.locales.filter((locale) => {
|
|
60
|
+
const localeCode = typeof locale === 'string' ? locale : locale.code
|
|
61
|
+
|
|
62
|
+
// Check for JSON locale file
|
|
63
|
+
const localeFilePath = resolve('../i18n/locales', `${localeCode}.json`)
|
|
64
|
+
const hasLocaleFile = existsSync(localeFilePath)
|
|
65
|
+
|
|
66
|
+
// Check for content folder
|
|
67
|
+
const contentPath = join(nuxt.options.rootDir, 'content', localeCode)
|
|
68
|
+
const hasContentFolder = existsSync(contentPath)
|
|
69
|
+
|
|
70
|
+
if (!hasLocaleFile) {
|
|
71
|
+
console.warn(`[Docus] Locale file not found: ${localeCode}.json - skipping locale "${localeCode}"`)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!hasContentFolder) {
|
|
75
|
+
console.warn(`[Docus] Content folder not found: content/${localeCode}/ - skipping locale "${localeCode}"`)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return hasLocaleFile && hasContentFolder
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Override strategy to prefix
|
|
82
|
+
nuxt.options.i18n = {
|
|
83
|
+
...nuxt.options.i18n,
|
|
84
|
+
strategy: 'prefix',
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Expose filtered locales
|
|
88
|
+
nuxt.options.runtimeConfig.public.docus = {
|
|
89
|
+
filteredLocales,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
nuxt.hook('i18n:registerModule', (register) => {
|
|
93
|
+
const langDir = resolve('../i18n/locales')
|
|
94
|
+
|
|
95
|
+
const locales = filteredLocales?.map((locale) => {
|
|
96
|
+
return typeof locale === 'string'
|
|
97
|
+
? {
|
|
98
|
+
code: locale,
|
|
99
|
+
name: locale,
|
|
100
|
+
file: `${locale}.json`,
|
|
101
|
+
}
|
|
102
|
+
: {
|
|
103
|
+
code: locale.code,
|
|
104
|
+
name: locale.name || locale.code,
|
|
105
|
+
file: `${locale.code}.json`,
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
register({
|
|
110
|
+
langDir,
|
|
111
|
+
locales,
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
})
|
package/modules/css.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineNuxtModule, addTemplate, createResolver } from '@nuxt/kit'
|
|
2
|
+
import { joinURL } from 'ufo'
|
|
3
|
+
import { resolveModulePath } from 'exsolve'
|
|
4
|
+
|
|
5
|
+
export default defineNuxtModule({
|
|
6
|
+
meta: {
|
|
7
|
+
name: 'css',
|
|
8
|
+
},
|
|
9
|
+
async setup(_options, nuxt) {
|
|
10
|
+
const dir = nuxt.options.rootDir
|
|
11
|
+
const resolver = createResolver(import.meta.url)
|
|
12
|
+
|
|
13
|
+
const contentDir = joinURL(dir, 'content')
|
|
14
|
+
const uiPath = resolveModulePath('@nuxt/ui', { from: import.meta.url, conditions: ['style'] })
|
|
15
|
+
const tailwindPath = resolveModulePath('tailwindcss', { from: import.meta.url, conditions: ['style'] })
|
|
16
|
+
const layerDir = resolver.resolve('../app')
|
|
17
|
+
|
|
18
|
+
const cssTemplate = addTemplate({
|
|
19
|
+
filename: 'docus.css',
|
|
20
|
+
getContents: () => {
|
|
21
|
+
return `@import ${JSON.stringify(tailwindPath)};
|
|
22
|
+
@import ${JSON.stringify(uiPath)};
|
|
23
|
+
|
|
24
|
+
@source "${contentDir.replace(/\\/g, '/')}/**/*";
|
|
25
|
+
@source "${layerDir.replace(/\\/g, '/')}/**/*";
|
|
26
|
+
@source "../../app.config.ts";`
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
nuxt.options.css.unshift(cssTemplate.dst)
|
|
31
|
+
},
|
|
32
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineNuxtModule, extendPages, createResolver } from '@nuxt/kit'
|
|
2
|
+
|
|
3
|
+
export default defineNuxtModule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'routing',
|
|
6
|
+
},
|
|
7
|
+
async setup(_options, nuxt) {
|
|
8
|
+
const { resolve } = createResolver(import.meta.url)
|
|
9
|
+
|
|
10
|
+
const isI18nEnabled = !!(nuxt.options.i18n && nuxt.options.i18n.locales)
|
|
11
|
+
|
|
12
|
+
// Ensure useDocusI18n is available in the app
|
|
13
|
+
nuxt.hook('imports:extend', (imports) => {
|
|
14
|
+
if (imports.some(i => i.name === 'useDocusI18n')) return
|
|
15
|
+
|
|
16
|
+
imports.push({
|
|
17
|
+
name: 'useDocusI18n',
|
|
18
|
+
from: resolve('../app/composables/useDocusI18n'),
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
extendPages((pages) => {
|
|
23
|
+
const landingTemplate = resolve('../app/templates/landing.vue')
|
|
24
|
+
|
|
25
|
+
if (isI18nEnabled) {
|
|
26
|
+
pages.push({
|
|
27
|
+
name: 'lang-index',
|
|
28
|
+
path: '/:lang?',
|
|
29
|
+
file: landingTemplate,
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
pages.push({
|
|
34
|
+
name: 'index',
|
|
35
|
+
path: '/',
|
|
36
|
+
file: landingTemplate,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
})
|
package/nuxt.config.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { extendViteConfig, createResolver, useNuxt } from '@nuxt/kit'
|
|
2
|
+
|
|
3
|
+
const { resolve } = createResolver(import.meta.url)
|
|
4
|
+
|
|
5
|
+
export default defineNuxtConfig({
|
|
6
|
+
modules: [
|
|
7
|
+
resolve('./modules/config'),
|
|
8
|
+
resolve('./modules/routing'),
|
|
9
|
+
resolve('./modules/css'),
|
|
10
|
+
'@nuxt/ui',
|
|
11
|
+
'@nuxt/content',
|
|
12
|
+
'@nuxt/image',
|
|
13
|
+
'@nuxtjs/robots',
|
|
14
|
+
'@nuxtjs/mcp-toolkit',
|
|
15
|
+
'nuxt-og-image',
|
|
16
|
+
'nuxt-llms',
|
|
17
|
+
() => {
|
|
18
|
+
// Update @nuxt/content optimizeDeps options
|
|
19
|
+
extendViteConfig((config) => {
|
|
20
|
+
config.optimizeDeps ||= {}
|
|
21
|
+
config.optimizeDeps.include ||= []
|
|
22
|
+
config.optimizeDeps.include.push('@nuxt/content > slugify')
|
|
23
|
+
config.optimizeDeps.include = config.optimizeDeps.include
|
|
24
|
+
.map(id => id.replace(/^@nuxt\/content > /, '@vkuttyp/docus > @nuxt/content > '))
|
|
25
|
+
})
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
devtools: {
|
|
29
|
+
enabled: true,
|
|
30
|
+
},
|
|
31
|
+
content: {
|
|
32
|
+
build: {
|
|
33
|
+
markdown: {
|
|
34
|
+
highlight: {
|
|
35
|
+
langs: ['bash', 'diff', 'json', 'js', 'ts', 'html', 'css', 'vue', 'shell', 'mdc', 'md', 'yaml'],
|
|
36
|
+
},
|
|
37
|
+
remarkPlugins: {
|
|
38
|
+
'remark-mdc': {
|
|
39
|
+
options: {
|
|
40
|
+
autoUnwrap: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
experimental: {
|
|
48
|
+
asyncContext: true,
|
|
49
|
+
},
|
|
50
|
+
compatibilityDate: '2025-07-22',
|
|
51
|
+
nitro: {
|
|
52
|
+
prerender: {
|
|
53
|
+
crawlLinks: true,
|
|
54
|
+
failOnError: false,
|
|
55
|
+
autoSubfolderIndex: false,
|
|
56
|
+
},
|
|
57
|
+
compatibilityDate: {
|
|
58
|
+
// Don't generate observability routes for now
|
|
59
|
+
vercel: '2025-07-14',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
hooks: {
|
|
63
|
+
'nitro:config'(nitroConfig) {
|
|
64
|
+
const nuxt = useNuxt()
|
|
65
|
+
|
|
66
|
+
const i18nOptions = nuxt.options.i18n
|
|
67
|
+
|
|
68
|
+
const routes: string[] = []
|
|
69
|
+
if (!i18nOptions) {
|
|
70
|
+
routes.push('/')
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
routes.push(...(i18nOptions.locales?.map(locale => typeof locale === 'string' ? `/${locale}` : `/${locale.code}`) || []))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
nitroConfig.prerender = nitroConfig.prerender || {}
|
|
77
|
+
nitroConfig.prerender.routes = nitroConfig.prerender.routes || []
|
|
78
|
+
nitroConfig.prerender.routes.push(...(routes || []))
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
icon: {
|
|
82
|
+
provider: 'iconify',
|
|
83
|
+
},
|
|
84
|
+
})
|