@movk/nuxt-docs 1.14.2 → 1.15.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 (42) hide show
  1. package/README.md +1 -1
  2. package/app/app.config.ts +5 -32
  3. package/app/app.vue +54 -32
  4. package/app/components/DocsAsideRightBottom.vue +1 -1
  5. package/app/components/OgImage/OgImageDocs.takumi.vue +90 -0
  6. package/app/components/PageHeaderLinks.vue +6 -16
  7. package/app/components/content/CommitChangelog.vue +1 -0
  8. package/app/components/content/Mermaid.vue +3 -1
  9. package/app/components/header/HeaderCTA.vue +1 -10
  10. package/app/components/theme-picker/ThemePicker.vue +22 -33
  11. package/app/composables/useTheme.ts +64 -84
  12. package/app/composables/useToolCall.ts +5 -8
  13. package/app/error.vue +1 -1
  14. package/app/pages/docs/[...slug].vue +6 -6
  15. package/app/plugins/theme.ts +39 -68
  16. package/app/templates/landing.vue +5 -2
  17. package/app/templates/releases.vue +5 -2
  18. package/app/types/index.d.ts +8 -57
  19. package/content.config.ts +1 -0
  20. package/modules/ai-chat/index.ts +16 -26
  21. package/modules/ai-chat/runtime/components/AiChat.vue +3 -3
  22. package/modules/ai-chat/runtime/components/AiChatFloatingInput.vue +6 -6
  23. package/modules/ai-chat/runtime/components/AiChatPanel.vue +216 -231
  24. package/modules/ai-chat/runtime/components/AiChatPreStream.vue +0 -14
  25. package/modules/ai-chat/runtime/composables/useAIChat.ts +25 -73
  26. package/modules/ai-chat/runtime/composables/useModels.ts +0 -19
  27. package/modules/ai-chat/runtime/server/api/ai-chat.ts +74 -48
  28. package/modules/ai-chat/runtime/server/utils/getModel.ts +1 -9
  29. package/modules/ai-chat/runtime/types.ts +5 -0
  30. package/nuxt.config.ts +42 -36
  31. package/nuxt.schema.ts +14 -99
  32. package/package.json +21 -25
  33. package/server/mcp/tools/get-page.ts +5 -47
  34. package/server/mcp/tools/list-getting-started-guides.ts +1 -3
  35. package/server/mcp/tools/list-pages.ts +9 -44
  36. package/utils/git.ts +26 -79
  37. package/app/components/OgImage/Nuxt.vue +0 -247
  38. package/app/composables/useAnalytics.ts +0 -7
  39. package/modules/ai-chat/runtime/components/AiChatReasoning.vue +0 -49
  40. package/modules/ai-chat/runtime/components/AiChatSlideoverFaq.vue +0 -38
  41. package/modules/ai-chat/runtime/components/AiChatToolCall.vue +0 -31
  42. package/modules/ai-chat/runtime/server/utils/docs_agent.ts +0 -54
package/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
  <img src="https://docs.mhaibaraai.cn/ai/AiChat.png" alt="AiChat" width="400">
25
25
  </div>
26
26
 
27
- - **AI 聊天助手** - 内置智能文档助手,基于 Vercel AI SDK 支持多种 LLM 模型(Mistral、Qwen、OpenRouter)
27
+ - **AI 聊天助手** - 内置智能文档助手,基于 Vercel AI SDK 支持多种 LLM 模型
28
28
  - **MCP Server 支持** - 集成 Model Context Protocol 服务器,为 AI 助手提供结构化的文档访问能力
29
29
  - **LLM 优化** - 通过 `nuxt-llms` 模块自动生成 `llms.txt` 和 `llms-full.txt`,为 AI 工具提供优化的文档索引
30
30
  - **流式响应** - 支持 AI 响应流式输出和代码高亮,配合 `shiki-stream` 实现实时语法高亮渲染
package/app/app.config.ts CHANGED
@@ -17,26 +17,8 @@ export default defineAppConfig({
17
17
  colors: {
18
18
  primary: 'green',
19
19
  neutral: 'slate'
20
- },
21
- contentNavigation: {
22
- slots: {
23
- linkLeadingIcon: 'size-4 mr-1',
24
- linkTrailing: 'hidden'
25
- },
26
- defaultVariants: {
27
- variant: 'link'
28
- }
29
- },
30
- pageLinks: {
31
- slots: {
32
- linkLeadingIcon: 'size-4',
33
- linkLabelExternalIcon: 'size-2.5'
34
- }
35
20
  }
36
- },
37
- vercelAnalytics: {
38
- enable: false,
39
- debug: false
21
+
40
22
  },
41
23
  header: {
42
24
  avatar: 'https://docs.mhaibaraai.cn/avatar.png',
@@ -79,28 +61,19 @@ export default defineAppConfig({
79
61
  },
80
62
  texts: {
81
63
  title: 'AI 助手',
82
- collapse: '折叠',
83
- expand: '展开',
84
64
  clearChat: '清除聊天记录',
85
65
  close: '关闭',
86
- loading: 'Loading...',
87
- askAnything: '问我任何事情...',
88
- askMeAnythingDescription: '我可以帮助您浏览文档、解释概念并回答您的问题。',
89
- faq: 'FAQ 建议',
90
66
  placeholder: '输入你的问题...',
91
67
  lineBreak: '换行',
92
68
  trigger: '与 AI 聊天',
93
- streaming: '思考中...',
94
- streamed: '思考过程',
95
69
  explainWithAi: '用 AI 解释此页面'
96
70
  },
97
71
  icons: {
98
- loading: 'i-lucide-loader',
99
72
  trigger: 'i-custom-ai',
100
- explain: 'i-lucide-brain',
101
- close: 'i-lucide-x',
102
- clearChat: 'i-lucide-trash-2',
103
- streaming: 'i-lucide-chevron-down',
73
+ explain: 'i-lucide-bot-message-square',
74
+ reasoning: 'i-lucide-brain',
75
+ close: 'i-lucide-panel-right-close',
76
+ clearChat: 'i-lucide-list-x',
104
77
  providers: {
105
78
  deepseek: 'i-hugeicons:deepseek',
106
79
  alibaba: 'i-hugeicons:qwen',
package/app/app.vue CHANGED
@@ -1,33 +1,39 @@
1
1
  <script setup lang="ts">
2
2
  import colors from 'tailwindcss/colors'
3
- import { Analytics } from '@vercel/analytics/nuxt'
4
- import { SpeedInsights } from '@vercel/speed-insights/nuxt'
3
+ import { withoutTrailingSlash } from 'ufo'
4
+ import { zh_cn } from '@nuxt/ui/locale'
5
5
 
6
6
  const site = useSiteConfig()
7
7
  const appConfig = useAppConfig()
8
8
  const colorMode = useColorMode()
9
9
  const route = useRoute()
10
- const { isEnabled: isAiChatEnabled, panelWidth: aiChatPanelWidth, shouldPushContent } = useAIChat()
10
+ const { style, link } = useTheme()
11
+ const { isEnabled: isAiChatEnabled } = useAIChat()
11
12
 
12
13
  const { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs', ['category', 'description']))
13
- const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSections('docs'), {
14
+ const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSections('docs', {
15
+ ignoredTags: ['style']
16
+ }), {
14
17
  server: false
15
18
  })
19
+
16
20
  const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
17
- const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
18
- const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ':root {}')
19
- const font = computed(() => `:root { --font-sans: '${appConfig.theme.font}', sans-serif; }`)
20
21
 
21
22
  useHead({
22
23
  meta: [
23
24
  { name: 'viewport', content: 'width=device-width, initial-scale=1' },
24
25
  { key: 'theme-color', name: 'theme-color', content: color }
25
26
  ],
26
- style: [
27
- { innerHTML: radius, id: 'nuxt-ui-radius', tagPriority: -2 },
28
- { innerHTML: blackAsPrimary, id: 'nuxt-ui-black-as-primary', tagPriority: -2 },
29
- { innerHTML: font, id: 'nuxt-ui-font', tagPriority: -2 }
30
- ]
27
+ link: [
28
+ { rel: 'icon', href: '/favicon.ico' },
29
+ { rel: 'canonical', href: `${site.url}${withoutTrailingSlash(route.path)}` },
30
+ ...link.value
31
+ ],
32
+ htmlAttrs: {
33
+ lang: 'zh-CN',
34
+ dir: 'ltr'
35
+ },
36
+ style
31
37
  })
32
38
 
33
39
  useSeoMeta({
@@ -44,32 +50,48 @@ provide('navigation', rootNavigation)
44
50
  </script>
45
51
 
46
52
  <template>
47
- <UApp :toaster="appConfig.toaster">
53
+ <UApp :toaster="appConfig.toaster" :locale="zh_cn">
48
54
  <NuxtLoadingIndicator color="var(--ui-primary)" :height="2" />
49
- <Analytics v-if="appConfig.vercelAnalytics" :debug="appConfig.vercelAnalytics?.debug" />
50
- <SpeedInsights v-if="appConfig.vercelAnalytics" :debug="appConfig.vercelAnalytics?.debug" />
51
55
 
52
- <div :class="{ root: route.path.startsWith('/docs/') }" :style="{ marginRight: shouldPushContent ? `${aiChatPanelWidth}px` : '0' }">
53
- <template v-if="!route.path.startsWith('/examples')">
54
- <Header v-if="$route.meta.header !== false" />
55
- </template>
56
+ <UTheme
57
+ :ui="{
58
+ contentNavigation: {
59
+ linkLeadingIcon: 'size-4 mr-1',
60
+ linkTrailing: 'hidden'
61
+ },
62
+ pageLinks: {
63
+ linkLeadingIcon: 'size-4',
64
+ linkLabelExternalIcon: 'size-2.5'
65
+ }
66
+ }"
67
+ >
68
+ <div class="flex">
69
+ <div class="flex-1 min-w-0" :class="[route.path.startsWith('/docs/') && 'root']">
70
+ <template v-if="!route.path.startsWith('/examples')">
71
+ <Header v-if="$route.meta.header !== false" />
72
+ </template>
56
73
 
57
- <NuxtLayout>
58
- <NuxtPage />
59
- </NuxtLayout>
74
+ <NuxtLayout>
75
+ <NuxtPage />
76
+ </NuxtLayout>
60
77
 
61
- <template v-if="!route.path.startsWith('/examples')">
62
- <Footer v-if="$route.meta.footer !== false" />
78
+ <template v-if="!route.path.startsWith('/examples')">
79
+ <Footer v-if="$route.meta.footer !== false" />
63
80
 
64
- <ClientOnly>
65
- <LazyUContentSearch :files="files" :navigation="rootNavigation" :fuse="{ resultLimit: 1000 }" />
66
- <template v-if="isAiChatEnabled">
67
- <LazyAiChatPanel />
68
- <LazyAiChatFloatingInput />
81
+ <ClientOnly>
82
+ <UContentSearch :files="files" :navigation="rootNavigation" :fuse="{ resultLimit: 500 }" />
83
+ </ClientOnly>
69
84
  </template>
70
- </ClientOnly>
71
- </template>
72
- </div>
85
+ </div>
86
+
87
+ <template v-if="!route.path.startsWith('/examples') && isAiChatEnabled">
88
+ <ClientOnly>
89
+ <AiChatPanel />
90
+ <AiChatFloatingInput />
91
+ </ClientOnly>
92
+ </template>
93
+ </div>
94
+ </UTheme>
73
95
  </UApp>
74
96
  </template>
75
97
 
@@ -19,6 +19,6 @@ const showExplainWithAi = computed(() => {
19
19
  size="sm"
20
20
  variant="ghost"
21
21
  color="neutral"
22
- @click="open(`解释此页面 ${pageUrl}`, true)"
22
+ @click="open(`阅读 ${pageUrl} 处的文档页面并对其进行总结,我想问一下相关问题。`)"
23
23
  />
24
24
  </template>
@@ -0,0 +1,90 @@
1
+ <script setup lang="ts">
2
+ withDefaults(defineProps<{
3
+ title?: string
4
+ description?: string
5
+ siteName?: string
6
+ }>(), {
7
+ title: '文档',
8
+ description: '使用 Nuxt Content 构建的文档站点',
9
+ siteName: 'Movk Nuxt Docs'
10
+ })
11
+ </script>
12
+
13
+ <template>
14
+ <div
15
+ style="font-family: 'Public Sans', 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;"
16
+ class="w-full h-full flex flex-col justify-center items-center relative p-10 lg:p-15 bg-white text-neutral-900 dark:bg-neutral-900 dark:text-neutral-50"
17
+ >
18
+ <div
19
+ class="absolute top-0 left-0 right-0 bottom-0"
20
+ :style="{
21
+ backgroundImage: `radial-gradient(at 100% 100%, rgba(34, 197, 94, 0.15), transparent)`
22
+ }"
23
+ />
24
+ <div
25
+ class="absolute top-0 left-0 right-0 bottom-0"
26
+ :style="{
27
+ backgroundImage: `radial-gradient(at 0% 0%, rgba(34, 197, 94, 0.1), transparent)`
28
+ }"
29
+ />
30
+
31
+ <div class="relative flex flex-col items-center text-center gap-5 lg:gap-8">
32
+ <div class="flex items-center gap-3">
33
+ <svg viewBox="0 0 64 64" class="w-10 h-10 lg:w-16 lg:h-16">
34
+ <defs>
35
+ <linearGradient
36
+ id="nsLine1"
37
+ x1="0%"
38
+ y1="100%"
39
+ x2="100%"
40
+ y2="0%"
41
+ >
42
+ <stop offset="0%" stop-color="#22c55e" />
43
+ <stop offset="100%" stop-color="#86efac" />
44
+ </linearGradient>
45
+ <linearGradient
46
+ id="nsFill1"
47
+ x1="0%"
48
+ y1="0%"
49
+ x2="0%"
50
+ y2="100%"
51
+ >
52
+ <stop offset="0%" stop-color="#22c55e" stop-opacity="0.6" />
53
+ <stop offset="100%" stop-color="#22c55e" stop-opacity="0" />
54
+ </linearGradient>
55
+ </defs>
56
+ <path d="M8 52 Q20 48 24 36 T40 20 T56 12 L56 56 L8 56 Z" fill="url(#nsFill1)" />
57
+ <path
58
+ d="M8 52 Q20 48 24 36 T40 20 T56 12"
59
+ fill="none"
60
+ stroke="url(#nsLine1)"
61
+ stroke-width="4"
62
+ stroke-linecap="round"
63
+ />
64
+ <circle
65
+ cx="56"
66
+ cy="12"
67
+ r="6"
68
+ fill="url(#nsLine1)"
69
+ />
70
+ </svg>
71
+ <span class="text-[32px] font-medium lg:text-[42px] text-green-500">
72
+ {{ siteName }}
73
+ </span>
74
+ </div>
75
+
76
+ <div class="items-center justify-center w-full">
77
+ <h1
78
+ class="text-[48px] lg:text-[72px] leading-tight text-pretty font-normal text-slate-900 max-w-175 lg:max-w-250"
79
+ style="display: block; line-clamp: 3; text-overflow: ellipsis; text-wrap: balance;"
80
+ >
81
+ {{ title }}
82
+ </h1>
83
+ </div>
84
+
85
+ <p v-if="description" class="text-slate-500 text-[24px] lg:text-[32px] opacity-70 max-w-162.5 lg:max-w-225 leading-normal">
86
+ {{ description }}
87
+ </p>
88
+ </div>
89
+ </div>
90
+ </template>
@@ -1,10 +1,11 @@
1
1
  <script setup lang="ts">
2
+ import { useClipboard } from '@vueuse/core'
3
+
2
4
  const route = useRoute()
3
5
  const toast = useToast()
4
6
  const { copy, copied } = useClipboard()
5
7
  const site = useSiteConfig()
6
- const { vercelAnalytics, ui } = useAppConfig()
7
- const { track } = useAnalytics()
8
+ const { ui } = useAppConfig()
8
9
 
9
10
  const appBaseURL = useRuntimeConfig().app?.baseURL || '/'
10
11
 
@@ -15,7 +16,6 @@ const items = [[
15
16
  label: 'Copy Markdown link',
16
17
  icon: 'i-lucide-link',
17
18
  onSelect() {
18
- if (vercelAnalytics?.debug) track('Page Action', { action: 'Copy Markdown Link' })
19
19
  copy(mdPath.value)
20
20
  toast.add({
21
21
  title: 'Copied to clipboard',
@@ -27,28 +27,19 @@ const items = [[
27
27
  label: 'View as Markdown',
28
28
  icon: 'i-simple-icons-markdown',
29
29
  target: '_blank',
30
- to: `/raw${route.path}.md`,
31
- onSelect() {
32
- if (vercelAnalytics?.debug) track('Page Action', { action: 'View as Markdown' })
33
- }
30
+ to: `/raw${route.path}.md`
34
31
  },
35
32
  {
36
33
  label: 'Open in ChatGPT',
37
34
  icon: 'i-simple-icons-openai',
38
35
  target: '_blank',
39
- to: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${mdPath.value} so I can ask questions about it.`)}`,
40
- onSelect() {
41
- if (vercelAnalytics?.debug) track('Page Action', { action: 'Open in ChatGPT' })
42
- }
36
+ to: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${mdPath.value} so I can ask questions about it.`)}`
43
37
  },
44
38
  {
45
39
  label: 'Open in Claude',
46
40
  icon: 'i-simple-icons-anthropic',
47
41
  target: '_blank',
48
- to: `https://claude.ai/new?q=${encodeURIComponent(`Read ${mdPath.value} so I can ask questions about it.`)}`,
49
- onSelect() {
50
- if (vercelAnalytics?.debug) track('Page Action', { action: 'Open in Claude' })
51
- }
42
+ to: `https://claude.ai/new?q=${encodeURIComponent(`Read ${mdPath.value} so I can ask questions about it.`)}`
52
43
  }
53
44
  ], [
54
45
  {
@@ -77,7 +68,6 @@ const items = [[
77
68
  ]]
78
69
 
79
70
  async function copyPage() {
80
- if (vercelAnalytics?.debug) track('Page Action', { action: 'Copy Page Content' })
81
71
  copy(await $fetch<string>(`/raw${route.path}.md`))
82
72
  }
83
73
  </script>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { camelCase, kebabCase, upperFirst } from 'scule'
3
+ import { useTimeAgo } from '@vueuse/core'
3
4
 
4
5
  interface Commit {
5
6
  sha: string
@@ -1,7 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { hash } from 'ohash'
3
3
  import type { IconProps } from '@nuxt/ui'
4
- import type { ClassNameValue } from 'tailwind-merge'
5
4
  import {
6
5
  useClipboard,
7
6
  useElementVisibility,
@@ -10,6 +9,9 @@ import {
10
9
  } from '@vueuse/core'
11
10
  import { tv } from '@nuxt/ui/utils/tv'
12
11
 
12
+ type ClassNameValue = ClassNameArray | string | null | undefined | 0 | 0n | false
13
+ type ClassNameArray = ClassNameValue[]
14
+
13
15
  const theme = {
14
16
  slots: {
15
17
  root: 'relative my-5 group border border-muted rounded-md overflow-hidden',
@@ -1,18 +1,9 @@
1
1
  <script lang="ts" setup>
2
- const route = useRoute()
3
2
  const { isEnabled: isAiChatEnabled } = useAIChat()
4
3
  </script>
5
4
 
6
5
  <template>
7
6
  <div v-if="isAiChatEnabled" class="hidden md:block">
8
- <UButton
9
- v-if="route.path === '/'"
10
- to="/docs"
11
- label="Get Started"
12
- variant="ghost"
13
- trailing
14
- icon="i-lucide-arrow-right"
15
- />
16
- <AiChat v-else />
7
+ <AiChat />
17
8
  </div>
18
9
  </template>
@@ -1,19 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import { useClipboard } from '@vueuse/core'
3
3
 
4
- const appConfig = useAppConfig()
5
4
  const colorMode = useColorMode()
6
5
 
7
- const { track } = useAnalytics()
8
-
9
6
  const open = ref(false)
10
7
 
11
- watch(open, (isOpen) => {
12
- if (isOpen && appConfig.vercelAnalytics?.debug) {
13
- track('Theme Picker Opened')
14
- }
15
- })
16
-
17
8
  const { copy: copyCSS, copied: copiedCSS } = useClipboard()
18
9
  const { copy: copyAppConfig, copied: copiedAppConfig } = useClipboard()
19
10
 
@@ -22,7 +13,7 @@ const {
22
13
  neutral,
23
14
  primaryColors,
24
15
  primary,
25
- setBlackAsPrimary,
16
+ blackAsPrimary,
26
17
  radiuses,
27
18
  radius,
28
19
  fonts,
@@ -58,21 +49,24 @@ const {
58
49
  Primary
59
50
 
60
51
  <UButton
61
- to="https://ui.nuxt.com/docs/getting-started/theme/css-variables#colors"
52
+ to="/docs/getting-started/theme/css-variables#colors"
62
53
  size="xs"
63
54
  color="neutral"
64
55
  variant="link"
65
- target="_blank"
66
- icon="i-lucide-circle-help"
56
+ icon="i-lucide-help-circle"
67
57
  class="p-0 -my-0.5"
68
58
  :ui="{ leadingIcon: 'size-3' }"
69
59
  />
70
60
  </legend>
71
61
 
72
62
  <div class="grid grid-cols-3 gap-1 -mx-2">
73
- <ThemePickerButton label="Black" :selected="appConfig.theme.blackAsPrimary" @click="setBlackAsPrimary(true)">
63
+ <ThemePickerButton
64
+ label="Black"
65
+ :selected="blackAsPrimary"
66
+ @click="blackAsPrimary = true"
67
+ >
74
68
  <template #leading>
75
- <span class="inline-block w-2 h-2 rounded-full bg-black dark:bg-white" />
69
+ <span class="inline-block size-2 rounded-full bg-black dark:bg-white" />
76
70
  </template>
77
71
  </ThemePickerButton>
78
72
 
@@ -81,7 +75,7 @@ const {
81
75
  :key="color"
82
76
  :label="color"
83
77
  :chip="color"
84
- :selected="!appConfig.theme.blackAsPrimary && primary === color"
78
+ :selected="!blackAsPrimary && primary === color"
85
79
  @click="primary = color"
86
80
  />
87
81
  </div>
@@ -92,12 +86,11 @@ const {
92
86
  Neutral
93
87
 
94
88
  <UButton
95
- to="https://ui.nuxt.com/docs/getting-started/theme/css-variables#text"
89
+ to="/docs/getting-started/theme/css-variables#text"
96
90
  size="xs"
97
91
  color="neutral"
98
92
  variant="link"
99
- target="_blank"
100
- icon="i-lucide-circle-help"
93
+ icon="i-lucide-help-circle"
101
94
  class="p-0 -my-0.5"
102
95
  :ui="{ leadingIcon: 'size-3' }"
103
96
  />
@@ -120,12 +113,11 @@ const {
120
113
  Radius
121
114
 
122
115
  <UButton
123
- to="https://ui.nuxt.com/docs/getting-started/theme/css-variables#radius"
116
+ to="/docs/getting-started/theme/css-variables#radius"
124
117
  size="xs"
125
118
  color="neutral"
126
119
  variant="link"
127
- target="_blank"
128
- icon="i-lucide-circle-help"
120
+ icon="i-lucide-help-circle"
129
121
  class="p-0 -my-0.5"
130
122
  :ui="{ leadingIcon: 'size-3' }"
131
123
  />
@@ -148,12 +140,11 @@ const {
148
140
  Font
149
141
 
150
142
  <UButton
151
- to="https://ui.nuxt.com/docs/getting-started/integrations/fonts"
143
+ to="/docs/getting-started/integrations/fonts"
152
144
  size="xs"
153
145
  color="neutral"
154
146
  variant="link"
155
- target="_blank"
156
- icon="i-lucide-circle-help"
147
+ icon="i-lucide-help-circle"
157
148
  class="p-0 -my-0.5"
158
149
  :ui="{ leadingIcon: 'size-3' }"
159
150
  />
@@ -177,12 +168,11 @@ const {
177
168
  Icons
178
169
 
179
170
  <UButton
180
- to="https://ui.nuxt.com/docs/getting-started/integrations/icons"
171
+ to="/docs/getting-started/integrations/icons"
181
172
  size="xs"
182
173
  color="neutral"
183
174
  variant="link"
184
- target="_blank"
185
- icon="i-lucide-circle-help"
175
+ icon="i-lucide-help-circle"
186
176
  class="p-0 -my-0.5"
187
177
  :ui="{ leadingIcon: 'size-3' }"
188
178
  />
@@ -206,12 +196,11 @@ const {
206
196
  Color Mode
207
197
 
208
198
  <UButton
209
- to="https://ui.nuxt.com/docs/getting-started/integrations/color-mode"
199
+ to="/docs/getting-started/integrations/color-mode"
210
200
  size="xs"
211
201
  color="neutral"
212
202
  variant="link"
213
- target="_blank"
214
- icon="i-lucide-circle-help"
203
+ icon="i-lucide-help-circle"
215
204
  class="p-0 -my-0.5"
216
205
  :ui="{ leadingIcon: 'size-3' }"
217
206
  />
@@ -241,7 +230,7 @@ const {
241
230
  size="sm"
242
231
  label="main.css"
243
232
  class="flex-1 text-[11px]"
244
- :icon="copiedCSS ? appConfig.ui.icons.copyCheck : appConfig.ui.icons.copy"
233
+ :icon="copiedCSS ? 'i-lucide-copy-check' : 'i-lucide-copy'"
245
234
  @click="copyCSS(exportCSS())"
246
235
  />
247
236
  <UButton
@@ -250,7 +239,7 @@ const {
250
239
  variant="soft"
251
240
  size="sm"
252
241
  label="app.config.ts"
253
- :icon="copiedAppConfig ? appConfig.ui.icons.copyCheck : appConfig.ui.icons.copy"
242
+ :icon="copiedAppConfig ? 'i-lucide-copy-check' : 'i-lucide-copy'"
254
243
  class="flex-1 text-[11px]"
255
244
  @click="copyAppConfig(exportAppConfig())"
256
245
  />