@lobehub/lobehub 2.0.0-next.294 → 2.0.0-next.295

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 (170) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +0 -1
  3. package/apps/desktop/src/main/__mocks__/setup.ts +0 -1
  4. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -4
  5. package/apps/desktop/tsconfig.json +4 -10
  6. package/changelog/v1.json +9 -0
  7. package/e2e/scripts/setup.ts +45 -32
  8. package/package.json +1 -1
  9. package/packages/database/src/models/__tests__/knowledgeBase.test.ts +1 -1
  10. package/packages/database/src/repositories/knowledge/index.ts +1 -4
  11. package/packages/types/src/discover/assistants.ts +2 -2
  12. package/scripts/migrate-spa-navigation.ts +129 -0
  13. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-topics/route.ts +112 -109
  14. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-user-topics/route.ts +125 -113
  15. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-users/route.ts +74 -65
  16. package/src/app/[variants]/(auth)/auth-error/page.tsx +1 -1
  17. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
  18. package/src/app/[variants]/(auth)/next-auth/error/AuthErrorPage.tsx +1 -1
  19. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +1 -1
  20. package/src/app/[variants]/(auth)/oauth/callback/error/page.tsx +1 -1
  21. package/src/app/[variants]/(auth)/oauth/callback/success/page.tsx +1 -1
  22. package/src/app/[variants]/(auth)/oauth/consent/[uid]/page.tsx +1 -1
  23. package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
  24. package/src/app/[variants]/(auth)/reset-password/page.tsx +2 -2
  25. package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
  26. package/src/app/[variants]/(auth)/signin/useSignIn.ts +1 -1
  27. package/src/app/[variants]/(auth)/signup/[[...signup]]/BetterAuthSignUpForm.tsx +2 -2
  28. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
  29. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +1 -1
  30. package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
  31. package/src/app/[variants]/(auth)/verify-email/page.tsx +2 -2
  32. package/src/app/[variants]/(main)/_layout/index.tsx +1 -1
  33. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/CronTopicGroup.tsx +1 -1
  34. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/AddTopicButon.tsx +1 -1
  35. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
  36. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  37. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  38. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +1 -1
  39. package/src/app/[variants]/(main)/agent/features/TelemetryNotification.tsx +2 -3
  40. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Nav.tsx +9 -9
  41. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -3
  42. package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +1 -2
  43. package/src/app/[variants]/(main)/community/(detail)/features/ShareButton.tsx +2 -3
  44. package/src/app/[variants]/(main)/community/(detail)/features/Toc/Heading.tsx +2 -3
  45. package/src/app/[variants]/(main)/community/(detail)/mcp/features/Details/Versions/index.tsx +2 -2
  46. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Nav.tsx +12 -11
  47. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Parameter/ParameterItem.tsx +2 -3
  48. package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +11 -10
  49. package/src/app/[variants]/(main)/community/(detail)/provider/features/Header.tsx +10 -9
  50. package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +1 -1
  51. package/src/app/[variants]/(main)/community/(list)/assistant/features/Category/useCategory.tsx +1 -1
  52. package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +2 -3
  53. package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +1 -1
  54. package/src/app/[variants]/(main)/community/features/CreateButton/Inner.tsx +1 -1
  55. package/src/app/[variants]/(main)/community/features/CreateButton/index.tsx +1 -1
  56. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -2
  57. package/src/app/[variants]/(main)/community/features/Title.tsx +5 -5
  58. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +1 -1
  59. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  60. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  61. package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +1 -1
  62. package/src/app/[variants]/(main)/group/features/TelemetryNotification.tsx +2 -3
  63. package/src/app/[variants]/(main)/home/_layout/Body/Agent/AllAgentsDrawer/index.tsx +1 -1
  64. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +6 -11
  65. package/src/app/[variants]/(main)/image/NotSupportClient.tsx +4 -3
  66. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ImageUpload.tsx +1 -1
  67. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +1 -1
  68. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +1 -1
  69. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +1 -1
  70. package/src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx +1 -1
  71. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +1 -1
  72. package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/index.tsx +1 -1
  73. package/src/app/[variants]/(main)/settings/about/features/ItemCard.tsx +2 -3
  74. package/src/app/[variants]/(main)/settings/about/features/ItemLink.tsx +2 -3
  75. package/src/app/[variants]/(main)/settings/about/features/Version.tsx +6 -7
  76. package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +1 -1
  77. package/src/app/[variants]/(main)/settings/features/UpgradeAlert.tsx +4 -4
  78. package/src/app/[variants]/(main)/settings/provider/(list)/Footer.tsx +2 -2
  79. package/src/app/[variants]/(main)/settings/provider/detail/index.tsx +1 -1
  80. package/src/app/[variants]/(main)/settings/provider/detail/ollama/CheckError.tsx +1 -1
  81. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +12 -6
  82. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
  83. package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/ShareModal.tsx +1 -1
  84. package/src/app/[variants]/(main)/settings/stats/features/rankings/AssistantsRank.tsx +1 -1
  85. package/src/app/[variants]/(main)/settings/stats/features/rankings/TopicsRank.tsx +1 -1
  86. package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
  87. package/src/app/[variants]/(mobile)/chat/settings/features/AgentInfoDescription/index.tsx +1 -1
  88. package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +1 -1
  89. package/src/app/[variants]/(mobile)/router/index.tsx +1 -1
  90. package/src/app/[variants]/page.tsx +1 -1
  91. package/src/app/[variants]/router/index.tsx +1 -1
  92. package/src/components/404/index.tsx +4 -4
  93. package/src/components/Analytics/index.tsx +1 -1
  94. package/src/components/BrandWatermark/index.tsx +4 -4
  95. package/src/components/Branding/ProductLogo/Custom.tsx +1 -1
  96. package/src/components/Error/index.tsx +3 -4
  97. package/src/components/GoBack/index.tsx +2 -2
  98. package/src/components/LabsModal/LabCard.tsx +1 -1
  99. package/src/components/Link.tsx +25 -5
  100. package/src/components/OllamaSetupGuide/index.tsx +5 -4
  101. package/src/components/WebFavicon/index.tsx +1 -1
  102. package/src/components/client/ClientResponsiveContent/index.tsx +1 -1
  103. package/src/components/client/ClientResponsiveLayout.tsx +1 -1
  104. package/src/components/mdx/Image.tsx +1 -1
  105. package/src/components/mdx/Link.tsx +26 -9
  106. package/src/features/AlertBanner/CloudBanner.tsx +2 -3
  107. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +8 -7
  108. package/src/features/ChatInput/ActionBar/Params/Controls.tsx +1 -3
  109. package/src/features/ChatInput/ActionBar/Token/index.tsx +1 -1
  110. package/src/features/ChatInput/Mobile/index.tsx +1 -1
  111. package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +1 -1
  112. package/src/features/Conversation/Error/OllamaBizError/index.tsx +1 -1
  113. package/src/features/Conversation/Error/OllamaSetupGuide/Desktop.tsx +1 -2
  114. package/src/features/Conversation/Error/index.tsx +1 -1
  115. package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/Settings.tsx +1 -1
  116. package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +1 -1
  117. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +1 -1
  118. package/src/features/Conversation/Messages/Tool/Tool/index.tsx +1 -1
  119. package/src/features/Conversation/Messages/components/SearchGrounding.tsx +1 -1
  120. package/src/features/DataImporter/Error.tsx +3 -3
  121. package/src/features/DevPanel/CacheViewer/cacheProvider.tsx +2 -1
  122. package/src/features/DevPanel/MetadataViewer/Og.tsx +1 -1
  123. package/src/features/DevPanel/features/FloatPanel.tsx +1 -1
  124. package/src/features/DevPanel/features/Table/TooltipContent.tsx +3 -4
  125. package/src/features/DevPanel/index.tsx +1 -1
  126. package/src/features/EditorCanvas/InlineToolbar.tsx +1 -6
  127. package/src/features/FileViewer/NotSupport/index.tsx +2 -3
  128. package/src/features/Follow/index.tsx +8 -9
  129. package/src/features/LibraryModal/AddFilesToKnowledgeBase/SelectForm.tsx +2 -2
  130. package/src/features/MCP/Scores.tsx +1 -1
  131. package/src/features/MCPPluginDetail/Nav.tsx +8 -8
  132. package/src/features/MCPPluginDetail/Overview/TagList.tsx +1 -1
  133. package/src/features/MobileTabBar/index.tsx +2 -1
  134. package/src/features/OllamaSetupGuide/Desktop.tsx +1 -2
  135. package/src/features/PWAInstall/Install.tsx +1 -1
  136. package/src/features/PWAInstall/index.tsx +1 -1
  137. package/src/features/PluginStore/McpList/index.tsx +1 -1
  138. package/src/features/PluginStore/PluginList/Detail/Header.tsx +6 -6
  139. package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
  140. package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +1 -1
  141. package/src/features/ResourceManager/components/ChunkDrawer/index.tsx +1 -1
  142. package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +26 -26
  143. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +147 -149
  144. package/src/features/ResourceManager/index.tsx +1 -1
  145. package/src/features/Setting/Footer.tsx +4 -5
  146. package/src/features/User/UserPanel/PanelContent.tsx +1 -1
  147. package/src/hooks/useActiveTabKey.ts +6 -3
  148. package/src/hooks/useIsSingleMode.test.ts +10 -24
  149. package/src/hooks/useIsSingleMode.ts +4 -2
  150. package/src/hooks/useIsSubSlug.ts +2 -1
  151. package/src/hooks/useQuery.ts +5 -5
  152. package/src/layout/GlobalProvider/AppTheme.tsx +2 -2
  153. package/src/layout/GlobalProvider/StyleRegistry.tsx +1 -1
  154. package/src/layout/GlobalProvider/useUserStateRedirect.ts +13 -25
  155. package/src/libs/next/Image.tsx +13 -0
  156. package/src/libs/next/Link.tsx +13 -0
  157. package/src/libs/next/dynamic.tsx +13 -0
  158. package/src/libs/next/index.ts +22 -0
  159. package/src/libs/next/navigation.ts +22 -0
  160. package/src/libs/router/Link.tsx +30 -0
  161. package/src/libs/router/index.ts +18 -0
  162. package/src/libs/router/navigation.ts +72 -0
  163. package/src/server/modules/AgentRuntime/AgentStateManager.ts +5 -1
  164. package/src/store/chat/slices/portal/selectors.test.ts +5 -15
  165. package/src/store/page/index.ts +1 -1
  166. package/src/store/page/slices/crud/index.ts +1 -1
  167. package/src/app/[variants]/(main)/hooks/usePathname.ts +0 -10
  168. package/src/app/[variants]/(main)/hooks/useQuery.ts +0 -12
  169. package/src/app/[variants]/(main)/hooks/useRouter.ts +0 -22
  170. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +0 -11
@@ -1,7 +1,6 @@
1
1
  import { Flexbox } from '@lobehub/ui';
2
2
  import { Divider } from 'antd';
3
3
  import { cssVar } from 'antd-style';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
@@ -29,9 +28,9 @@ const ParameterItem = memo<ParameterItemProps>(
29
28
  <Flexbox align={'flex-start'} gap={16}>
30
29
  <p style={{ color: cssVar.colorTextSecondary, margin: 0 }}>
31
30
  {desc}{' '}
32
- <Link href={docUrl} target={'_blank'}>
31
+ <a href={docUrl} rel="noreferrer" target="_blank">
33
32
  {t('models.parameterList.docs')}
34
- </Link>
33
+ </a>
35
34
  </p>
36
35
  <Divider dashed style={{ margin: 0 }} />
37
36
  <Flexbox align={'center'} gap={16} horizontal style={{ paddingBottom: 8 }} wrap={'wrap'}>
@@ -4,7 +4,6 @@ import { BRANDING_PROVIDER, SOCIAL_URL } from '@lobechat/business-const';
4
4
  import { Flexbox, Icon, Tabs } from '@lobehub/ui';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { BookOpenIcon, BrainCircuitIcon, ListIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import urlJoin from 'url-join';
@@ -78,28 +77,30 @@ const Nav = memo<NavProps>(({ mobile, setActiveTab, activeTab = ProviderNavKey.O
78
77
  <Flexbox align={'center'} className={styles.nav} horizontal justify={'space-between'}>
79
78
  {nav}
80
79
  <Flexbox gap={12} horizontal>
81
- <Link className={styles.link} href={SOCIAL_URL.discord} target={'_blank'}>
80
+ <a className={styles.link} href={SOCIAL_URL.discord} rel="noreferrer" target="_blank">
82
81
  {t('mcp.details.nav.needHelp')}
83
- </Link>
82
+ </a>
84
83
  {identifier && (
85
- <Link
84
+ <a
86
85
  className={styles.link}
87
86
  href={urlJoin(
88
87
  'https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders',
89
88
  `${identifier}.ts`,
90
89
  )}
91
- target={'_blank'}
90
+ rel="noreferrer"
91
+ target="_blank"
92
92
  >
93
93
  {t('mcp.details.nav.viewSourceCode')}
94
- </Link>
94
+ </a>
95
95
  )}
96
- <Link
96
+ <a
97
97
  className={styles.link}
98
- href={'https://github.com/lobehub/lobe-chat/issues/new/choose'}
99
- target={'_blank'}
98
+ href="https://github.com/lobehub/lobe-chat/issues/new/choose"
99
+ rel="noreferrer"
100
+ target="_blank"
100
101
  >
101
102
  {t('mcp.details.nav.reportIssue')}
102
- </Link>
103
+ </a>
103
104
  </Flexbox>
104
105
  </Flexbox>
105
106
  );
@@ -4,7 +4,6 @@ import { Github, ProviderCombine } from '@lobehub/icons';
4
4
  import { ActionIcon, Flexbox } from '@lobehub/ui';
5
5
  import { cssVar, useResponsive } from 'antd-style';
6
6
  import { GlobeIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import urlJoin from 'url-join';
@@ -32,9 +31,9 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
32
31
  <ProviderCombine provider={identifier} size={mobile ? 32 : 48} />
33
32
  <Flexbox align={'center'} gap={4} horizontal>
34
33
  {Boolean(url || modelsUrl) ? (
35
- <Link href={url || (modelsUrl as string)} target={'_blank'}>
34
+ <a href={url || (modelsUrl as string)} rel="noreferrer" target="_blank">
36
35
  @{name}
37
- </Link>
36
+ </a>
38
37
  ) : (
39
38
  <span>@{name}</span>
40
39
  )}
@@ -42,25 +41,27 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
42
41
  </Flexbox>
43
42
  <Flexbox align={'center'} horizontal>
44
43
  {Boolean(url || modelsUrl) && (
45
- <Link
44
+ <a
46
45
  href={(url || modelsUrl) as string}
47
46
  onClick={(e) => e.stopPropagation()}
48
- target={'_blank'}
47
+ rel="noreferrer"
48
+ target="_blank"
49
49
  >
50
50
  <ActionIcon color={cssVar.colorTextDescription} icon={GlobeIcon} />
51
- </Link>
51
+ </a>
52
52
  )}
53
53
 
54
- <Link
54
+ <a
55
55
  href={urlJoin(
56
56
  'https://github.com/lobehub/lobe-chat-agents/tree/main/locales',
57
57
  identifier as string,
58
58
  )}
59
59
  onClick={(e) => e.stopPropagation()}
60
- target={'_blank'}
60
+ rel="noreferrer"
61
+ target="_blank"
61
62
  >
62
63
  <ActionIcon fill={cssVar.colorTextDescription} icon={Github} />
63
- </Link>
64
+ </a>
64
65
  </Flexbox>
65
66
  </Flexbox>
66
67
 
@@ -4,7 +4,7 @@ import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
6
  import { useDiscoverStore } from '@/store/discover';
7
- import { McpSorts, AssistantSorts } from '@/types/discover';
7
+ import { AssistantSorts, McpSorts } from '@/types/discover';
8
8
 
9
9
  import Title from '../../components/Title';
10
10
  import AssistantList from '../assistant/features/List';
@@ -2,6 +2,7 @@ import {
2
2
  BadgeDollarSignIcon,
3
3
  BriefcaseIcon,
4
4
  Coffee,
5
+ CompassIcon,
5
6
  DramaIcon,
6
7
  GamepadIcon,
7
8
  GraduationCapIcon,
@@ -14,7 +15,6 @@ import {
14
15
  PencilIcon,
15
16
  PrinterIcon,
16
17
  TerminalSquareIcon,
17
- CompassIcon,
18
18
  } from 'lucide-react';
19
19
  import { useMemo } from 'react';
20
20
  import { useTranslation } from 'react-i18next';
@@ -1,12 +1,11 @@
1
- import { Dropdown, type DropdownMenuItemType, Icon , Button } from '@lobehub/ui';
1
+ import { Button, Dropdown, type DropdownMenuItemType, Icon } from '@lobehub/ui';
2
2
  import { ArrowDownWideNarrow, ChevronDown } from 'lucide-react';
3
3
  import { memo, useMemo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
7
- import { useQuery } from '@/app/[variants]/(main)/hooks/useQuery';
8
6
  import { useQueryRoute } from '@/hooks/useQueryRoute';
9
7
  import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
8
+ import { usePathname , useQuery } from '@/libs/router/navigation';
10
9
  import {
11
10
  AssistantSorts,
12
11
  DiscoverTab,
@@ -3,7 +3,7 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { McpIcon, ProviderIcon } from '@lobehub/ui/icons';
5
5
  import { Bot, Brain, ShapesIcon } from 'lucide-react';
6
- import { usePathname } from 'next/navigation';
6
+ import { usePathname } from '@/libs/router/navigation';
7
7
  import { memo, useMemo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { Link, useNavigate } from 'react-router-dom';
@@ -1,7 +1,7 @@
1
1
  import { Button, Icon, Tag, Typography } from '@lobehub/ui';
2
2
  import { Divider } from 'antd';
3
3
  import { Github, Settings, Share2 } from 'lucide-react';
4
- import Image from 'next/image';
4
+ import Image from '@/libs/next/Image';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { ActionIcon, Button, Modal , Skeleton } from '@lobehub/ui';
2
2
  import { useResponsive } from 'antd-style';
3
3
  import { Brush } from 'lucide-react';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -6,8 +6,7 @@ import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import urlJoin from 'url-join';
8
8
 
9
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
10
- import { useQuery } from '@/app/[variants]/(main)/hooks/useQuery';
9
+ import { usePathname , useQuery } from '@/libs/router/navigation';
11
10
  import { withSuspense } from '@/components/withSuspense';
12
11
  import { useQueryRoute } from '@/hooks/useQueryRoute';
13
12
 
@@ -3,7 +3,6 @@
3
3
  import { Flexbox, type FlexboxProps, Icon } from '@lobehub/ui';
4
4
  import { createStaticStyles, cx } from 'antd-style';
5
5
  import { ChevronRight } from 'lucide-react';
6
- import NextLink from 'next/link';
7
6
  import { type ReactNode, memo } from 'react';
8
7
  import { Link as RouterLink } from 'react-router-dom';
9
8
 
@@ -51,10 +50,10 @@ const Title = memo<TitleProps>(
51
50
  if (moreLink) {
52
51
  if (isExternalLink) {
53
52
  moreLinkElement = (
54
- <NextLink className={styles.more} href={moreLink} target="_blank">
53
+ <a className={styles.more} href={moreLink} rel="noreferrer" target="_blank">
55
54
  <span style={{ marginRight: 4 }}>{more}</span>
56
55
  <Icon icon={ChevronRight} />
57
- </NextLink>
56
+ </a>
58
57
  );
59
58
  } else if (isCommunityRoute) {
60
59
  moreLinkElement = (
@@ -64,11 +63,12 @@ const Title = memo<TitleProps>(
64
63
  </RouterLink>
65
64
  );
66
65
  } else {
66
+ // For non-external, non-community routes (like auth pages), use RouterLink
67
67
  moreLinkElement = (
68
- <NextLink className={styles.more} href={moreLink}>
68
+ <RouterLink className={styles.more} to={moreLink}>
69
69
  <span style={{ marginRight: 4 }}>{more}</span>
70
70
  <Icon icon={ChevronRight} />
71
- </NextLink>
71
+ </RouterLink>
72
72
  );
73
73
  }
74
74
  }
@@ -3,7 +3,6 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { BotPromptIcon } from '@lobehub/ui/icons';
5
5
  import { MessageSquarePlusIcon, SearchIcon } from 'lucide-react';
6
- import { usePathname } from 'next/navigation';
7
6
  import { memo } from 'react';
8
7
  import { useTranslation } from 'react-i18next';
9
8
  import { useParams } from 'react-router-dom';
@@ -11,6 +10,7 @@ import urlJoin from 'url-join';
11
10
 
12
11
  import NavItem from '@/features/NavPanel/components/NavItem';
13
12
  import { useQueryRoute } from '@/hooks/useQueryRoute';
13
+ import { usePathname } from '@/libs/router/navigation';
14
14
  import { useAgentGroupStore } from '@/store/agentGroup';
15
15
  import { useChatStore } from '@/store/chat';
16
16
  import { useGlobalStore } from '@/store/global';
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,4 +1,4 @@
1
- import { usePathname } from 'next/navigation';
1
+ import { usePathname } from '@/libs/router/navigation';
2
2
  import { useCallback } from 'react';
3
3
  import { useParams } from 'react-router-dom';
4
4
  import urlJoin from 'url-join';
@@ -2,12 +2,12 @@
2
2
 
3
3
  import { ActionIcon } from '@lobehub/ui';
4
4
  import { Share2 } from 'lucide-react';
5
- import dynamic from 'next/dynamic';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
 
9
8
  import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
10
9
  import { useWorkspaceModal } from '@/hooks/useWorkspaceModal';
10
+ import dynamic from '@/libs/next/dynamic';
11
11
  import { useChatStore } from '@/store/chat';
12
12
  import { useServerConfigStore } from '@/store/serverConfig';
13
13
  import { serverConfigSelectors } from '@/store/serverConfig/selectors';
@@ -4,7 +4,6 @@ import { BRANDING_NAME } from '@lobechat/business-const';
4
4
  import { Avatar, Button, Flexbox, Icon } from '@lobehub/ui';
5
5
  import { createStaticStyles, cssVar } from 'antd-style';
6
6
  import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
 
@@ -56,10 +55,10 @@ const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => {
56
55
  <div className={styles.desc}>
57
56
  {t('telemetry.desc', { appName: BRANDING_NAME })}
58
57
  <span>
59
- <Link href={PRIVACY_URL} target={'_blank'}>
58
+ <a href={PRIVACY_URL} rel="noreferrer" target="_blank">
60
59
  {t('telemetry.learnMore')}
61
60
  <Icon icon={LucideArrowUpRightFromSquare} style={{ marginInlineStart: 4 }} />
62
- </Link>
61
+ </a>
63
62
  </span>
64
63
  </div>
65
64
  </Flexbox>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,21 +1,18 @@
1
- import { useLocation, useSearchParams } from 'react-router-dom';
2
-
3
1
  import { ProfileTabs, SettingsTabs, type SidebarTabKey } from '@/store/global/initialState';
2
+ import { usePathname, useSearchParams } from '@/libs/router/navigation';
4
3
 
5
4
  /**
6
5
  * Returns the active tab key (chat/discover/settings/...)
7
- * React Router version for (main) directory
6
+ * Uses React Router via @/libs/router
8
7
  */
9
8
  export const useActiveTabKey = () => {
10
- const location = useLocation();
11
- const pathname = location.pathname;
12
-
9
+ const pathname = usePathname();
13
10
  return pathname.split('/').find(Boolean) as SidebarTabKey;
14
11
  };
15
12
 
16
13
  /**
17
14
  * Returns the active setting page key (?active=common/sync/agent/...)
18
- * React Router version for (main) directory
15
+ * Uses React Router via @/libs/router
19
16
  */
20
17
  export const useActiveSettingsKey = () => {
21
18
  const [searchParams] = useSearchParams();
@@ -26,12 +23,10 @@ export const useActiveSettingsKey = () => {
26
23
 
27
24
  /**
28
25
  * Returns the active profile page key (profile/security/stats/...)
29
- * React Router version for (main) directory
26
+ * Uses React Router via @/libs/router
30
27
  */
31
28
  export const useActiveProfileKey = () => {
32
- const location = useLocation();
33
- const pathname = location.pathname;
34
-
29
+ const pathname = usePathname();
35
30
  const tabs = pathname.split('/').findLast(Boolean);
36
31
 
37
32
  if (tabs === 'profile') return ProfileTabs.Profile;
@@ -4,7 +4,6 @@ import { UTM_SOURCE } from '@lobechat/business-const';
4
4
  import { Center, Flexbox, Icon, Text } from '@lobehub/ui';
5
5
  import { createStaticStyles, cssVar } from 'antd-style';
6
6
  import { Database, FileImage, Network, Sparkles } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { Trans, useTranslation } from 'react-i18next';
9
8
 
10
9
  import FeatureList from '@/components/FeatureList';
@@ -131,11 +130,13 @@ const NotSupportClient = () => {
131
130
  <Trans
132
131
  components={[
133
132
  <span key="0" />,
134
- <Link href={DATABASE_SELF_HOSTING_URL} key="1" />,
133
+ <a href={DATABASE_SELF_HOSTING_URL} key="1" rel="noreferrer" target="_blank" />,
135
134
  <span key="2" />,
136
- <Link
135
+ <a
137
136
  href={`${OFFICIAL_URL}?utm_source=${UTM_SOURCE}&utm_medium=client_not_support_image`}
138
137
  key="3"
138
+ rel="noreferrer"
139
+ target="_blank"
139
140
  />,
140
141
  ]}
141
142
  i18nKey={'notSupportGuide.desc'}
@@ -4,7 +4,7 @@ import { Center } from '@lobehub/ui';
4
4
  import { App } from 'antd';
5
5
  import { createStaticStyles, cssVar, cx } from 'antd-style';
6
6
  import { Image as ImageIcon, X } from 'lucide-react';
7
- import Image from 'next/image';
7
+ import Image from '@/libs/next/Image';
8
8
  import React, { type FC, memo, useEffect, useRef, useState } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
@@ -3,7 +3,7 @@
3
3
  import { Button, Modal } from '@lobehub/ui';
4
4
  import { createStaticStyles, cx } from 'antd-style';
5
5
  import { Upload, X } from 'lucide-react';
6
- import Image from 'next/image';
6
+ import Image from '@/libs/next/Image';
7
7
  import React, { type FC, memo, useEffect, useRef, useState } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
@@ -4,7 +4,7 @@
4
4
  import { Center } from '@lobehub/ui';
5
5
  import { createStaticStyles, cssVar, cx } from 'antd-style';
6
6
  import { Image as ImageIcon, X } from 'lucide-react';
7
- import Image from 'next/image';
7
+ import Image from '@/libs/next/Image';
8
8
  import React, { type FC, memo, useEffect, useRef, useState } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
@@ -1,7 +1,7 @@
1
1
  import { ActionIcon, Block } from '@lobehub/ui';
2
2
  import { createStaticStyles, cx } from 'antd-style';
3
3
  import { MaximizeIcon, MinimizeIcon } from 'lucide-react';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useEffect, useState } from 'react';
6
6
 
7
7
  import Loading from '@/components/Loading/BrandTextLoading';
@@ -9,7 +9,7 @@ import {
9
9
  SearchIcon,
10
10
  SignatureIcon,
11
11
  } from 'lucide-react';
12
- import { usePathname } from 'next/navigation';
12
+ import { usePathname } from '@/libs/router/navigation';
13
13
  import { memo, useMemo } from 'react';
14
14
  import { useTranslation } from 'react-i18next';
15
15
  import { Link, useNavigate } from 'react-router-dom';
@@ -1,7 +1,7 @@
1
1
  import { Button, Icon, Text } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { Link2 } from 'lucide-react';
4
- import Link from 'next/link';
4
+ import Link from '@/libs/router/Link';
5
5
  import { memo } from 'react';
6
6
  import { useNavigate } from 'react-router-dom';
7
7
 
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,7 +1,6 @@
1
1
  import { Block, Icon } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { type LucideIcon } from 'lucide-react';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
 
7
6
  export interface ItemCardProps {
@@ -13,12 +12,12 @@ export interface ItemCardProps {
13
12
 
14
13
  const ItemCard = memo<ItemCardProps>(({ label, icon, href }) => {
15
14
  return (
16
- <Link href={href} style={{ color: 'inherit' }} target={'_blank'}>
15
+ <a href={href} rel="noreferrer" style={{ color: 'inherit' }} target="_blank">
17
16
  <Block clickable gap={12} horizontal paddingBlock={12} paddingInline={18}>
18
17
  {icon && <Icon fill={cssVar.colorText} icon={icon} size={18} />}
19
18
  {label}
20
19
  </Block>
21
- </Link>
20
+ </a>
22
21
  );
23
22
  });
24
23
 
@@ -1,7 +1,6 @@
1
1
  import { Flexbox, Icon } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { type LucideIcon, SquareArrowOutUpRight } from 'lucide-react';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
 
7
6
  export interface ItemLinkProps {
@@ -13,12 +12,12 @@ export interface ItemLinkProps {
13
12
 
14
13
  const ItemLink = memo<ItemLinkProps>(({ label, href }) => {
15
14
  return (
16
- <Link href={href} style={{ color: 'inherit' }} target={'_blank'}>
15
+ <a href={href} rel="noreferrer" style={{ color: 'inherit' }} target="_blank">
17
16
  <Flexbox align={'center'} gap={8} horizontal>
18
17
  {label}
19
18
  <Icon color={cssVar.colorTextDescription} icon={SquareArrowOutUpRight} size={14} />
20
19
  </Flexbox>
21
- </Link>
20
+ </a>
22
21
  );
23
22
  });
24
23
 
@@ -1,7 +1,6 @@
1
1
  import { BRANDING_NAME } from '@lobechat/business-const';
2
2
  import { Block, Button, Flexbox, Tag } from '@lobehub/ui';
3
3
  import { createStaticStyles } from 'antd-style';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
@@ -31,7 +30,7 @@ const Version = memo<{ mobile?: boolean }>(({ mobile }) => {
31
30
  width={'100%'}
32
31
  >
33
32
  <Flexbox align={'center'} flex={'none'} gap={16} horizontal>
34
- <Link href={OFFICIAL_SITE} target={'_blank'}>
33
+ <a href={OFFICIAL_SITE} rel="noreferrer" target="_blank">
35
34
  <Block
36
35
  align={'center'}
37
36
  className={styles.logo}
@@ -42,7 +41,7 @@ const Version = memo<{ mobile?: boolean }>(({ mobile }) => {
42
41
  >
43
42
  <ProductLogo size={52} />
44
43
  </Block>
45
- </Link>
44
+ </a>
46
45
  <Flexbox align={'flex-start'} gap={6}>
47
46
  <div style={{ fontSize: 18, fontWeight: 'bolder' }}>{BRANDING_NAME}</div>
48
47
  <Flexbox gap={6} horizontal={!mobile}>
@@ -56,15 +55,15 @@ const Version = memo<{ mobile?: boolean }>(({ mobile }) => {
56
55
  </Flexbox>
57
56
  </Flexbox>
58
57
  <Flexbox flex={mobile ? 1 : undefined} gap={8} horizontal>
59
- <Link href={CHANGELOG_URL} style={{ flex: 1 }} target={'_blank'}>
58
+ <a href={CHANGELOG_URL} rel="noreferrer" style={{ flex: 1 }} target="_blank">
60
59
  <Button block={mobile}>{t('changelog')}</Button>
61
- </Link>
60
+ </a>
62
61
  {hasNewVersion && (
63
- <Link href={MANUAL_UPGRADE_URL} style={{ flex: 1 }} target={'_blank'}>
62
+ <a href={MANUAL_UPGRADE_URL} rel="noreferrer" style={{ flex: 1 }} target="_blank">
64
63
  <Button block={mobile} type={'primary'}>
65
64
  {t('upgradeVersion.action')}
66
65
  </Button>
67
- </Link>
66
+ </a>
68
67
  )}
69
68
  </Flexbox>
70
69
  </Flexbox>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { ENABLE_BUSINESS_FEATURES } from '@lobechat/business-const';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { Fragment } from 'react';
6
6
 
7
7
  import Loading from '@/components/Loading/BrandTextLoading';
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { Alert, Button, Flexbox } from '@lobehub/ui';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
@@ -20,16 +19,17 @@ const UpgradeAlert = memo(() => {
20
19
  title={
21
20
  <Flexbox gap={8}>
22
21
  <p>{t('upgradeVersion.newVersion', { version: `v${latestVersion}` })}</p>
23
- <Link
22
+ <a
24
23
  aria-label={t('upgradeVersion.action')}
25
24
  href={MANUAL_UPGRADE_URL}
25
+ rel="noreferrer"
26
26
  style={{ marginBottom: 6 }}
27
- target={'_blank'}
27
+ target="_blank"
28
28
  >
29
29
  <Button block size={'small'} type={'primary'}>
30
30
  {t('upgradeVersion.action')}
31
31
  </Button>
32
- </Link>
32
+ </a>
33
33
  </Flexbox>
34
34
  }
35
35
  type={'info'}
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Center } from '@lobehub/ui';
4
4
  import { cssVar } from 'antd-style';
5
- import Link from 'next/link';
6
5
  import { memo } from 'react';
7
6
  import { Trans, useTranslation } from 'react-i18next';
8
7
 
@@ -24,10 +23,11 @@ const Footer = memo(() => {
24
23
  <Trans
25
24
  components={[
26
25
  <span key="0" />,
27
- <Link
26
+ <a
28
27
  aria-label={t('llm.waitingForMoreLinkAriaLabel')}
29
28
  href={MORE_MODEL_PROVIDER_REQUEST_URL}
30
29
  key="1"
30
+ rel="noreferrer"
31
31
  target="_blank"
32
32
  />,
33
33
  ]}
@@ -1,4 +1,4 @@
1
- import dynamic from 'next/dynamic';
1
+ import dynamic from '@/libs/next/dynamic';
2
2
 
3
3
  import Loading from '@/components/Loading/BrandTextLoading';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { type ChatMessageError } from '@lobechat/types';
2
2
  import { Skeleton } from '@lobehub/ui';
3
- import dynamic from 'next/dynamic';
3
+ import dynamic from '@/libs/next/dynamic';
4
4
  import { type ReactNode } from 'react';
5
5
 
6
6
  import Container from './Container';