docus 5.6.1 → 5.8.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.
Files changed (74) hide show
  1. package/app/app.vue +13 -1
  2. package/app/assets/icons/LICENSE +14 -0
  3. package/app/assets/icons/ai.svg +1 -0
  4. package/app/components/LanguageSelect.vue +1 -4
  5. package/app/components/OgImage/OgImageDocs.vue +2 -4
  6. package/app/components/OgImage/OgImageLanding.vue +36 -13
  7. package/app/components/app/AppFooterRight.vue +32 -14
  8. package/app/components/app/AppHeader.vue +10 -0
  9. package/app/components/app/AppHeaderBottom.vue +20 -0
  10. package/app/components/app/AppHeaderBottomRight.vue +3 -0
  11. package/app/components/docs/DocsAsideLeftBody.vue +2 -4
  12. package/app/components/docs/DocsAsideLeftTop.vue +18 -1
  13. package/app/components/docs/DocsAsideMobileBar.vue +88 -0
  14. package/app/components/docs/DocsAsideRight.vue +33 -0
  15. package/app/components/docs/DocsAsideRightBottom.vue +1 -1
  16. package/app/composables/useDocusI18n.ts +21 -5
  17. package/app/composables/useLogoAssets.ts +1 -1
  18. package/app/composables/useSubNavigation.ts +55 -0
  19. package/app/pages/[[lang]]/[...slug].vue +4 -13
  20. package/i18n/locales/ar.json +1 -0
  21. package/i18n/locales/be.json +1 -0
  22. package/i18n/locales/bg.json +1 -0
  23. package/i18n/locales/bn.json +1 -0
  24. package/i18n/locales/ca.json +1 -0
  25. package/i18n/locales/ckb.json +1 -0
  26. package/i18n/locales/cs.json +1 -0
  27. package/i18n/locales/da.json +1 -0
  28. package/i18n/locales/de.json +1 -0
  29. package/i18n/locales/el.json +1 -0
  30. package/i18n/locales/en.json +1 -0
  31. package/i18n/locales/es.json +1 -0
  32. package/i18n/locales/et.json +1 -0
  33. package/i18n/locales/fi.json +1 -0
  34. package/i18n/locales/fr.json +1 -0
  35. package/i18n/locales/he.json +1 -0
  36. package/i18n/locales/hi.json +1 -0
  37. package/i18n/locales/hy.json +1 -0
  38. package/i18n/locales/id.json +1 -0
  39. package/i18n/locales/it.json +1 -0
  40. package/i18n/locales/ja.json +1 -0
  41. package/i18n/locales/kk.json +1 -0
  42. package/i18n/locales/km.json +1 -0
  43. package/i18n/locales/ko.json +1 -0
  44. package/i18n/locales/ky.json +1 -0
  45. package/i18n/locales/lb.json +1 -0
  46. package/i18n/locales/ms.json +1 -0
  47. package/i18n/locales/nb.json +1 -0
  48. package/i18n/locales/nl.json +1 -0
  49. package/i18n/locales/pl.json +1 -0
  50. package/i18n/locales/pt-BR.json +1 -0
  51. package/i18n/locales/ro.json +1 -0
  52. package/i18n/locales/ru.json +1 -0
  53. package/i18n/locales/si.json +1 -0
  54. package/i18n/locales/sl.json +1 -0
  55. package/i18n/locales/sv.json +1 -0
  56. package/i18n/locales/tr.json +1 -0
  57. package/i18n/locales/uk.json +1 -0
  58. package/i18n/locales/ur.json +1 -0
  59. package/i18n/locales/vi.json +1 -0
  60. package/i18n/locales/zh-CN.json +1 -0
  61. package/modules/assistant/runtime/components/AssistantChat.vue +2 -2
  62. package/modules/assistant/runtime/components/AssistantPanel.vue +1 -1
  63. package/modules/assistant/runtime/components/AssistantPreStream.vue +1 -1
  64. package/modules/assistant/runtime/composables/useAssistant.ts +7 -3
  65. package/modules/assistant/runtime/server/api/search.ts +3 -2
  66. package/modules/config.ts +18 -6
  67. package/modules/markdown-rewrite.ts +7 -3
  68. package/modules/routing.ts +4 -1
  69. package/nuxt.config.ts +24 -2
  70. package/nuxt.schema.ts +15 -1
  71. package/package.json +13 -14
  72. package/server/mcp/tools/get-page.ts +2 -4
  73. package/server/mcp/tools/list-pages.ts +2 -1
  74. package/server/routes/sitemap.xml.ts +3 -3
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Community",
18
18
  "toc": "Auf dieser Seite",
19
+ "menu": "Menü",
19
20
  "report": "Problem melden",
20
21
  "edit": "Diese Seite bearbeiten"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Κοινότητα",
18
18
  "toc": "Σε αυτή τη σελίδα",
19
+ "menu": "Μενού",
19
20
  "report": "Αναφορά προβλήματος",
20
21
  "edit": "Επεξεργασία αυτής της σελίδας"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Community",
18
18
  "toc": "On this page",
19
+ "menu": "Menu",
19
20
  "report": "Report an issue",
20
21
  "edit": "Edit this page"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Comunidad",
18
18
  "toc": "En esta página",
19
+ "menu": "Menú",
19
20
  "report": "Reportar un problema",
20
21
  "edit": "Editar esta página"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Kogukond",
18
18
  "toc": "Sellel lehel",
19
+ "menu": "Menüü",
19
20
  "report": "Teata probleemist",
20
21
  "edit": "Muuda seda lehekülge"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Yhteisö",
18
18
  "toc": "Tällä sivulla",
19
+ "menu": "Valikko",
19
20
  "report": "Ilmoita ongelmasta",
20
21
  "edit": "Muokkaa tätä sivua"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Communauté",
18
18
  "toc": "Sur cette page",
19
+ "menu": "Menu",
19
20
  "report": "Signaler un problème",
20
21
  "edit": "Éditer cette page"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "קהילה",
18
18
  "toc": "בעמוד זה",
19
+ "menu": "תפריט",
19
20
  "report": "דווח על בעיה",
20
21
  "edit": "ערוך עמוד זה"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "समुदाय",
18
18
  "toc": "इस पृष्ठ पर",
19
+ "menu": "मेनू",
19
20
  "report": "समस्या की रिपोर्ट करें",
20
21
  "edit": "इस पृष्ठ को संपादित करें"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Համայնք",
18
18
  "toc": "Այս էջում",
19
+ "menu": "Ընտրացանկ",
19
20
  "report": "Հաղորդել խնդրի մասին",
20
21
  "edit": "Խմբագրել այս էջը"
21
22
  },
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "links": "Komunitas",
21
21
  "toc": "Pada halaman ini",
22
+ "menu": "Menu",
22
23
  "report": "Laporkan masalah",
23
24
  "edit": "Ubah halaman ini"
24
25
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Comunità",
18
18
  "toc": "In questa pagina",
19
+ "menu": "Menu",
19
20
  "report": "Segnala un problema",
20
21
  "edit": "Modifica questa pagina"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "コミュニティ",
18
18
  "toc": "このページの内容",
19
+ "menu": "メニュー",
19
20
  "report": "問題を報告",
20
21
  "edit": "このページを編集"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Қауымдастық",
18
18
  "toc": "Осы бетте",
19
+ "menu": "Мәзір",
19
20
  "report": "Мәселе туралы хабарлау",
20
21
  "edit": "Осы бетті өңдеу"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "សហគមន៍",
18
18
  "toc": "នៅលើទំព័រនេះ",
19
+ "menu": "ម៉ឺនុយ",
19
20
  "report": "រាយការណ៍បញ្ហា",
20
21
  "edit": "កែសម្រួលទំព័រនេះ"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "커뮤니티",
18
18
  "toc": "이 페이지에서",
19
+ "menu": "메뉴",
19
20
  "report": "문제 신고",
20
21
  "edit": "이 페이지 편집"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Коом",
18
18
  "toc": "Бул барактта",
19
+ "menu": "Меню",
19
20
  "report": "Көйгөй туурасында кабарлоо",
20
21
  "edit": "Бул баракты түзөтүү"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Gemeinschaft",
18
18
  "toc": "Op dëser Säit",
19
+ "menu": "Menü",
19
20
  "report": "Problem mellen",
20
21
  "edit": "Dës Säit änneren"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Komuniti",
18
18
  "toc": "Dalam halaman ini",
19
+ "menu": "Menu",
19
20
  "report": "Laporkan masalah",
20
21
  "edit": "Edit halaman ini"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Fellesskap",
18
18
  "toc": "På denne siden",
19
+ "menu": "Meny",
19
20
  "report": "Rapporter et problem",
20
21
  "edit": "Rediger denne siden"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Community",
18
18
  "toc": "Op deze pagina",
19
+ "menu": "Menu",
19
20
  "report": "Rapporteer een probleem",
20
21
  "edit": "Bewerk deze pagina"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Społeczność",
18
18
  "toc": "Na tej stronie",
19
+ "menu": "Menu",
19
20
  "report": "Zgłoś problem",
20
21
  "edit": "Edytuj tę stronę"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Comunidade",
18
18
  "toc": "Nesta página",
19
+ "menu": "Menu",
19
20
  "report": "Reportar um erro",
20
21
  "edit": "Editar esta página"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Comunitate",
18
18
  "toc": "Pe această pagină",
19
+ "menu": "Meniu",
19
20
  "report": "Raportează o problemă",
20
21
  "edit": "Editează această pagină"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Сообщество",
18
18
  "toc": "На этой странице",
19
+ "menu": "Меню",
19
20
  "report": "Сообщить о проблеме",
20
21
  "edit": "Редактировать эту страницу"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Community",
18
18
  "toc": "මෙම පිටුවේ",
19
+ "menu": "මෙනුව",
19
20
  "report": "ගැටලුවක් වාර්තා කරන්න",
20
21
  "edit": "මෙම පිටුව සංස්කරණය කරන්න"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Skupnost",
18
18
  "toc": "Na tej strani",
19
+ "menu": "Meni",
19
20
  "report": "Prijavi težavo",
20
21
  "edit": "Uredi to stran"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Gemenskap",
18
18
  "toc": "På denna sida",
19
+ "menu": "Meny",
19
20
  "report": "Rapportera ett problem",
20
21
  "edit": "Redigera denna sida"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Topluluk",
18
18
  "toc": "Bu sayfada",
19
+ "menu": "Menü",
19
20
  "report": "Sorun bildir",
20
21
  "edit": "Bu sayfayı düzenle"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Спільнота",
18
18
  "toc": "На цій сторінці",
19
+ "menu": "Меню",
19
20
  "report": "Повідомити про проблему",
20
21
  "edit": "Редагувати цю сторінку"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "کمیونٹی",
18
18
  "toc": "اس صفحے پر",
19
+ "menu": "مینو",
19
20
  "report": "مسئلہ کی اطلاع دیں",
20
21
  "edit": "اس صفحے کو ترمیم کریں"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "Cộng đồng",
18
18
  "toc": "Trên trang này",
19
+ "menu": "Menu",
19
20
  "report": "Báo cáo sự cố",
20
21
  "edit": "Chỉnh sửa trang này"
21
22
  },
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "links": "社区",
18
18
  "toc": "在此页面上",
19
+ "menu": "菜单",
19
20
  "report": "提交问题报告",
20
21
  "edit": "编辑此页面"
21
22
  },
@@ -6,15 +6,15 @@ const { toggle } = useAssistant()
6
6
  const { t } = useDocusI18n()
7
7
 
8
8
  const tooltipText = computed(() => t('assistant.tooltip'))
9
- const triggerIcon = computed(() => appConfig.assistant?.icons?.trigger || 'i-lucide-sparkles')
9
+ const triggerIcon = computed(() => appConfig.assistant?.icons?.trigger || 'i-custom-ai')
10
10
  </script>
11
11
 
12
12
  <template>
13
13
  <UTooltip :text="tooltipText">
14
14
  <UButton
15
15
  :icon="triggerIcon"
16
+ color="neutral"
16
17
  variant="ghost"
17
- class="rounded-full"
18
18
  @click="toggle"
19
19
  />
20
20
  </UTooltip>
@@ -25,7 +25,7 @@ const displayPlaceholder = computed(() => t('assistant.placeholder'))
25
25
  const chat = new Chat({
26
26
  messages: messages.value,
27
27
  transport: new DefaultChatTransport({
28
- api: config.public.assistant.apiPath,
28
+ api: (config.app?.baseURL.replace(/\/$/, '') || '') + config.public.assistant.apiPath,
29
29
  }),
30
30
  onError: (error: Error) => {
31
31
  const message = (() => {
@@ -3,7 +3,7 @@ import { ShikiCachedRenderer } from 'shiki-stream/vue'
3
3
  import { useColorMode } from '#imports'
4
4
  import { useHighlighter } from '../composables/useHighlighter'
5
5
 
6
- const colorMode = useColorMode()
6
+ const colorMode = useColorMode() as { value: string, forced?: boolean }
7
7
  const highlighter = await useHighlighter()
8
8
  const props = defineProps<{
9
9
  code: string
@@ -1,5 +1,7 @@
1
1
  import type { UIMessage } from 'ai'
2
+ import { useAppConfig, useRuntimeConfig, useState } from '#imports'
2
3
  import { useMediaQuery } from '@vueuse/core'
4
+ import { computed } from 'vue'
3
5
  import type { FaqCategory, FaqQuestions, LocalizedFaqQuestions } from '../types'
4
6
 
5
7
  function normalizeFaqQuestions(questions: FaqQuestions): FaqCategory[] {
@@ -23,7 +25,10 @@ const PANEL_WIDTH_EXPANDED = 520
23
25
  export function useAssistant() {
24
26
  const config = useRuntimeConfig()
25
27
  const appConfig = useAppConfig()
26
- const isEnabled = computed(() => config.public.assistant?.enabled ?? false)
28
+ const assistantRuntimeConfig = config.public.assistant as { enabled?: boolean } | undefined
29
+ const assistantConfig = appConfig.assistant as { faqQuestions?: FaqQuestions | LocalizedFaqQuestions } | undefined
30
+ const docusRuntimeConfig = appConfig.docus as { locale?: string } | undefined
31
+ const isEnabled = computed(() => assistantRuntimeConfig?.enabled ?? false)
27
32
 
28
33
  const isOpen = useState('assistant-open', () => false)
29
34
  const isExpanded = useState('assistant-expanded', () => false)
@@ -35,14 +40,13 @@ export function useAssistant() {
35
40
  const shouldPushContent = computed(() => !isMobile.value && isOpen.value)
36
41
 
37
42
  const faqQuestions = computed<FaqCategory[]>(() => {
38
- const assistantConfig = appConfig.assistant
39
43
  const faqConfig = assistantConfig?.faqQuestions
40
44
  if (!faqConfig) return []
41
45
 
42
46
  // Check if it's a localized object (has locale keys like 'en', 'fr')
43
47
  if (!Array.isArray(faqConfig)) {
44
48
  const localizedConfig = faqConfig as LocalizedFaqQuestions
45
- const currentLocale = appConfig.docus?.locale || 'en'
49
+ const currentLocale = docusRuntimeConfig?.locale || 'en'
46
50
  const defaultLocale = config.public.i18n?.defaultLocale || 'en'
47
51
 
48
52
  // Try current locale, then default locale, then first available
@@ -60,11 +60,12 @@ export default defineEventHandler(async (event) => {
60
60
 
61
61
  const mcpServer = config.assistant.mcpServer
62
62
  const isExternalUrl = mcpServer.startsWith('http://') || mcpServer.startsWith('https://')
63
+ const baseURL = config.app?.baseURL?.replace(/\/$/, '') || ''
63
64
  const mcpUrl = isExternalUrl
64
65
  ? mcpServer
65
66
  : import.meta.dev
66
- ? `http://localhost:3000${mcpServer}`
67
- : `${getRequestURL(event).origin}${mcpServer}`
67
+ ? `http://localhost:3000${baseURL}${mcpServer}`
68
+ : `${getRequestURL(event).origin}${baseURL}${mcpServer}`
68
69
 
69
70
  const httpClient = await createMCPClient({
70
71
  transport: { type: 'http', url: mcpUrl },
package/modules/config.ts CHANGED
@@ -7,6 +7,13 @@ import { getGitBranch, getGitEnv, getLocalGitInfo } from '../utils/git'
7
7
 
8
8
  const log = logger.withTag('Docus')
9
9
 
10
+ type I18nLocale = string | { code: string, name?: string }
11
+ type DocusI18nOptions = { locales?: I18nLocale[], strategy?: string }
12
+ type RegisterModuleOptions = {
13
+ langDir: string
14
+ locales: Array<{ code: string, name: string, file: string }>
15
+ }
16
+
10
17
  export default defineNuxtModule({
11
18
  meta: {
12
19
  name: 'config',
@@ -54,11 +61,14 @@ export default defineNuxtModule({
54
61
  /*
55
62
  ** I18N
56
63
  */
57
- if (nuxt.options.i18n && nuxt.options.i18n.locales) {
64
+ const typedNuxtOptions = nuxt.options as typeof nuxt.options & { i18n?: DocusI18nOptions }
65
+ const i18nOptions = typedNuxtOptions.i18n
66
+
67
+ if (i18nOptions?.locales) {
58
68
  const { resolve } = createResolver(import.meta.url)
59
69
 
60
70
  // Filter locales to only include existing ones
61
- const filteredLocales = nuxt.options.i18n.locales.filter((locale) => {
71
+ const filteredLocales = i18nOptions.locales.filter((locale: I18nLocale) => {
62
72
  const localeCode = typeof locale === 'string' ? locale : locale.code
63
73
 
64
74
  // Check for JSON locale file
@@ -81,8 +91,8 @@ export default defineNuxtModule({
81
91
  })
82
92
 
83
93
  // Override strategy to prefix
84
- nuxt.options.i18n = {
85
- ...nuxt.options.i18n,
94
+ typedNuxtOptions.i18n = {
95
+ ...i18nOptions,
86
96
  strategy: 'prefix',
87
97
  }
88
98
 
@@ -91,10 +101,12 @@ export default defineNuxtModule({
91
101
  filteredLocales,
92
102
  }
93
103
 
94
- nuxt.hook('i18n:registerModule', (register) => {
104
+ const registerI18nModule = nuxt.hook as unknown as (name: string, callback: (register: (options: RegisterModuleOptions) => void) => void) => void
105
+
106
+ registerI18nModule('i18n:registerModule', (register) => {
95
107
  const langDir = resolve('../i18n/locales')
96
108
 
97
- const locales = filteredLocales?.map((locale) => {
109
+ const locales = filteredLocales.map((locale: I18nLocale) => {
98
110
  return typeof locale === 'string'
99
111
  ? {
100
112
  code: locale,
@@ -4,6 +4,9 @@ import { readFile, writeFile } from 'node:fs/promises'
4
4
 
5
5
  const log = logger.withTag('Docus')
6
6
 
7
+ type I18nLocale = string | { code: string }
8
+ type DocusI18nOptions = { locales?: I18nLocale[] }
9
+
7
10
  export default defineNuxtModule({
8
11
  meta: {
9
12
  name: 'markdown-rewrite',
@@ -44,13 +47,14 @@ export default defineNuxtModule({
44
47
  ]
45
48
 
46
49
  // Check if i18n is enabled
47
- const isI18nEnabled = !!(nuxt.options.i18n && nuxt.options.i18n.locales)
50
+ const i18nOptions = (nuxt.options as typeof nuxt.options & { i18n?: DocusI18nOptions }).i18n
51
+ const isI18nEnabled = !!i18nOptions?.locales
48
52
  let localeCodes: string[] = []
49
53
 
50
54
  if (isI18nEnabled) {
51
55
  // Get locale codes
52
- const locales = nuxt.options.i18n.locales || []
53
- localeCodes = locales.map((locale) => {
56
+ const locales = i18nOptions?.locales || []
57
+ localeCodes = locales.map((locale: I18nLocale) => {
54
58
  return typeof locale === 'string' ? locale : locale.code
55
59
  })
56
60
 
@@ -1,6 +1,8 @@
1
1
  import { defineNuxtModule, extendPages, createResolver } from '@nuxt/kit'
2
2
  import { landingPageExists } from '../utils/pages'
3
3
 
4
+ type DocusI18nOptions = { locales?: Array<string | { code: string }> }
5
+
4
6
  export default defineNuxtModule({
5
7
  meta: {
6
8
  name: 'routing',
@@ -8,7 +10,8 @@ export default defineNuxtModule({
8
10
  async setup(_options, nuxt) {
9
11
  const { resolve } = createResolver(import.meta.url)
10
12
 
11
- const isI18nEnabled = !!(nuxt.options.i18n && nuxt.options.i18n.locales)
13
+ const i18nOptions = (nuxt.options as typeof nuxt.options & { i18n?: DocusI18nOptions }).i18n
14
+ const isI18nEnabled = !!i18nOptions?.locales
12
15
 
13
16
  // Ensure useDocusI18n is available in the app
14
17
  nuxt.hook('imports:extend', (imports) => {
package/nuxt.config.ts CHANGED
@@ -1,13 +1,25 @@
1
+ import { join } from 'node:path'
1
2
  import { extendViteConfig, createResolver, useNuxt } from '@nuxt/kit'
2
3
 
3
4
  const { resolve } = createResolver(import.meta.url)
4
5
 
6
+ type DocusI18nOptions = { locales?: Array<string | { code: string }> }
7
+
5
8
  export default defineNuxtConfig({
6
9
  modules: [
7
10
  resolve('./modules/config'),
8
11
  resolve('./modules/routing'),
9
12
  resolve('./modules/markdown-rewrite'),
10
13
  resolve('./modules/css'),
14
+ () => {
15
+ const nuxt = useNuxt()
16
+ nuxt.options.icon ||= {}
17
+ nuxt.options.icon.customCollections ||= []
18
+ nuxt.options.icon.customCollections.push({
19
+ prefix: 'custom',
20
+ dir: join(nuxt.options.srcDir, 'assets/icons'),
21
+ })
22
+ },
11
23
  '@nuxt/ui',
12
24
  '@nuxt/content',
13
25
  '@nuxt/image',
@@ -77,14 +89,14 @@ export default defineNuxtConfig({
77
89
  'nitro:config'(nitroConfig) {
78
90
  const nuxt = useNuxt()
79
91
 
80
- const i18nOptions = nuxt.options.i18n
92
+ const i18nOptions = (nuxt.options as typeof nuxt.options & { i18n?: DocusI18nOptions }).i18n
81
93
 
82
94
  const routes: string[] = []
83
95
  if (!i18nOptions) {
84
96
  routes.push('/')
85
97
  }
86
98
  else {
87
- routes.push(...(i18nOptions.locales?.map(locale => typeof locale === 'string' ? `/${locale}` : `/${locale.code}`) || []))
99
+ routes.push(...(i18nOptions.locales?.map((locale: string | { code: string }) => typeof locale === 'string' ? `/${locale}` : `/${locale.code}`) || []))
88
100
  }
89
101
 
90
102
  nitroConfig.prerender = nitroConfig.prerender || {}
@@ -94,6 +106,16 @@ export default defineNuxtConfig({
94
106
  },
95
107
  },
96
108
  icon: {
109
+ customCollections: [
110
+ {
111
+ prefix: 'custom',
112
+ dir: resolve('./app/assets/icons'),
113
+ },
114
+ ],
115
+ clientBundle: {
116
+ scan: true,
117
+ includeCustomCollections: true,
118
+ },
97
119
  provider: 'iconify',
98
120
  },
99
121
  robots: {
package/nuxt.schema.ts CHANGED
@@ -193,6 +193,20 @@ export default defineNuxtSchema({
193
193
  }),
194
194
  },
195
195
  }),
196
+ navigation: group({
197
+ title: 'Navigation',
198
+ description: 'Navigation configuration.',
199
+ icon: 'i-lucide-navigation',
200
+ fields: {
201
+ sub: field({
202
+ type: 'string',
203
+ title: 'Sub Navigation',
204
+ description: 'Enable sub-navigation for multi-section docs. Use "header" for a secondary tab bar below the header, or "aside" for section anchors at the top of the sidebar.',
205
+ icon: 'i-lucide-layout-panel-left',
206
+ default: '',
207
+ }),
208
+ },
209
+ }),
196
210
  socials: field({
197
211
  type: 'object',
198
212
  title: 'Social Networks',
@@ -266,7 +280,7 @@ export default defineNuxtSchema({
266
280
  assistant: group({
267
281
  title: 'Assistant',
268
282
  description: 'Assistant configuration.',
269
- icon: 'i-lucide-sparkles',
283
+ icon: 'i-custom-ai',
270
284
  fields: {
271
285
  floatingInput: field({
272
286
  type: 'boolean',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docus",
3
3
  "description": "Nuxt layer for Docus documentation theme",
4
- "version": "5.6.1",
4
+ "version": "5.8.0",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
7
7
  "repository": {
@@ -22,26 +22,25 @@
22
22
  "README.md"
23
23
  ],
24
24
  "dependencies": {
25
- "@ai-sdk/gateway": "^3.0.46",
26
- "@ai-sdk/mcp": "^1.0.21",
27
- "@ai-sdk/vue": "3.0.86",
28
- "@iconify-json/lucide": "^1.2.91",
29
- "@iconify-json/simple-icons": "^1.2.71",
30
- "@iconify-json/vscode-icons": "^1.2.43",
31
- "@nuxt/content": "^3.11.2",
25
+ "@ai-sdk/gateway": "^3.0.66",
26
+ "@ai-sdk/mcp": "^1.0.25",
27
+ "@ai-sdk/vue": "3.0.116",
28
+ "@iconify-json/lucide": "^1.2.96",
29
+ "@iconify-json/simple-icons": "^1.2.73",
30
+ "@iconify-json/vscode-icons": "^1.2.45",
31
+ "@nuxt/content": "^3.12.0",
32
32
  "@nuxt/image": "^2.0.0",
33
33
  "@nuxt/kit": "^4.3.1",
34
- "@nuxt/ui": "^4.4.0",
34
+ "@nuxt/ui": "^4.5.1",
35
35
  "@nuxtjs/i18n": "^10.2.3",
36
36
  "@nuxtjs/mcp-toolkit": "^0.7.0",
37
- "@nuxtjs/mdc": "^0.20.1",
38
- "@nuxtjs/robots": "^5.7.0",
37
+ "@nuxtjs/mdc": "^0.20.2",
38
+ "@nuxtjs/robots": "^5.7.1",
39
39
  "@vueuse/core": "^14.2.1",
40
- "ai": "6.0.86",
40
+ "ai": "6.0.116",
41
41
  "defu": "^6.1.4",
42
42
  "exsolve": "^1.0.8",
43
43
  "git-url-parse": "^16.1.0",
44
- "minimark": "^1.0.0",
45
44
  "motion-v": "^1.10.3",
46
45
  "nuxt-llms": "^0.2.0",
47
46
  "nuxt-og-image": "^5.1.13",
@@ -52,7 +51,7 @@
52
51
  "@shikijs/langs": "^3.22.0",
53
52
  "@shikijs/themes": "^3.22.0",
54
53
  "shiki-stream": "^0.1.4",
55
- "tailwindcss": "^4.1.18",
54
+ "tailwindcss": "^4.2.1",
56
55
  "ufo": "^1.6.3",
57
56
  "zod": "^4.3.6",
58
57
  "zod-to-json-schema": "^3.25.1"