@lobehub/chat 1.110.2 β†’ 1.110.3

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/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.110.3](https://github.com/lobehub/lobe-chat/compare/v1.110.2...v1.110.3)
6
+
7
+ <sup>Released on **2025-08-06**</sup>
8
+
9
+ #### πŸ’„ Styles
10
+
11
+ - **misc**: Fix provider setting page hydration error.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Styles
19
+
20
+ - **misc**: Fix provider setting page hydration error, closes [#8695](https://github.com/lobehub/lobe-chat/issues/8695) ([88e7d2a](https://github.com/lobehub/lobe-chat/commit/88e7d2a))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ### [Version 1.110.2](https://github.com/lobehub/lobe-chat/compare/v1.110.1...v1.110.2)
6
31
 
7
32
  <sup>Released on **2025-08-06**</sup>
@@ -29,9 +29,9 @@ describe('MenuController', () => {
29
29
  it('should call menuManager.refreshMenus', () => {
30
30
  // ζ¨‘ζ‹ŸθΏ”ε›žε€Ό
31
31
  mockRefreshMenus.mockReturnValueOnce(true);
32
-
32
+
33
33
  const result = menuController.refreshAppMenu();
34
-
34
+
35
35
  expect(mockRefreshMenus).toHaveBeenCalled();
36
36
  expect(result).toBe(true);
37
37
  });
@@ -41,9 +41,9 @@ describe('MenuController', () => {
41
41
  it('should call menuManager.showContextMenu with type only', () => {
42
42
  const menuType = 'chat';
43
43
  mockShowContextMenu.mockReturnValueOnce({ shown: true });
44
-
45
- const result = menuController.showContextMenu(menuType);
46
-
44
+
45
+ const result = menuController.showContextMenu({ type: menuType });
46
+
47
47
  expect(mockShowContextMenu).toHaveBeenCalledWith(menuType, undefined);
48
48
  expect(result).toEqual({ shown: true });
49
49
  });
@@ -52,9 +52,9 @@ describe('MenuController', () => {
52
52
  const menuType = 'file';
53
53
  const menuData = { fileId: '123', filePath: '/path/to/file.txt' };
54
54
  mockShowContextMenu.mockReturnValueOnce({ shown: true });
55
-
56
- const result = menuController.showContextMenu(menuType, menuData);
57
-
55
+
56
+ const result = menuController.showContextMenu({ type: menuType, data: menuData });
57
+
58
58
  expect(mockShowContextMenu).toHaveBeenCalledWith(menuType, menuData);
59
59
  expect(result).toEqual({ shown: true });
60
60
  });
@@ -63,20 +63,20 @@ describe('MenuController', () => {
63
63
  describe('setDevMenuVisibility', () => {
64
64
  it('should call menuManager.rebuildAppMenu with showDevItems true', () => {
65
65
  mockRebuildAppMenu.mockReturnValueOnce(true);
66
-
66
+
67
67
  const result = menuController.setDevMenuVisibility(true);
68
-
68
+
69
69
  expect(mockRebuildAppMenu).toHaveBeenCalledWith({ showDevItems: true });
70
70
  expect(result).toBe(true);
71
71
  });
72
72
 
73
73
  it('should call menuManager.rebuildAppMenu with showDevItems false', () => {
74
74
  mockRebuildAppMenu.mockReturnValueOnce(true);
75
-
75
+
76
76
  const result = menuController.setDevMenuVisibility(false);
77
-
77
+
78
78
  expect(mockRebuildAppMenu).toHaveBeenCalledWith({ showDevItems: false });
79
79
  expect(result).toBe(true);
80
80
  });
81
81
  });
82
- });
82
+ });
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Fix provider setting page hydration error."
6
+ ]
7
+ },
8
+ "date": "2025-08-06",
9
+ "version": "1.110.3"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "fixes": [
package/next.config.ts CHANGED
@@ -282,6 +282,7 @@ const nextConfig: NextConfig = {
282
282
  ...config.resolve.fallback,
283
283
  zipfile: false,
284
284
  };
285
+
285
286
  return config;
286
287
  },
287
288
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.110.2",
3
+ "version": "1.110.3",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -129,9 +129,9 @@
129
129
  "@azure-rest/ai-inference": "1.0.0-beta.5",
130
130
  "@azure/core-auth": "^1.10.0",
131
131
  "@cfworker/json-schema": "^4.1.1",
132
- "@clerk/localizations": "^3.20.1",
133
- "@clerk/nextjs": "^6.25.4",
134
- "@clerk/themes": "^2.3.3",
132
+ "@clerk/localizations": "^3.20.6",
133
+ "@clerk/nextjs": "^6.28.1",
134
+ "@clerk/themes": "^2.4.4",
135
135
  "@codesandbox/sandpack-react": "^2.20.0",
136
136
  "@cyntler/react-doc-viewer": "^1.17.0",
137
137
  "@electric-sql/pglite": "0.2.17",
@@ -27,7 +27,8 @@ const Layout = memo<LayoutProps>(({ children, category }) => {
27
27
  const activeKey = useActiveSettingsKey();
28
28
  const theme = useTheme();
29
29
  const pathname = usePathname();
30
- const isSkip = SKIP_PATHS.some((path) => pathname.startsWith(path));
30
+
31
+ const isSkip = SKIP_PATHS.some((path) => pathname.includes(path));
31
32
  const isProvider = pathname.includes('/settings/provider/');
32
33
  const providerName = useProviderName(activeKey);
33
34
 
@@ -8,6 +8,7 @@ import SettingContainer from '@/features/Setting/SettingContainer';
8
8
  const Container = memo<PropsWithChildren>(({ children }) => {
9
9
  const path = usePathname();
10
10
  const isRoot = path === '/settings/provider';
11
+
11
12
  return <SettingContainer variant={isRoot ? 'secondary' : undefined}>{children}</SettingContainer>;
12
13
  });
13
14
  export default Container;
@@ -1,20 +1,15 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { Flexbox } from 'react-layout-kit';
3
3
 
4
- import NProgress from '@/components/NProgress';
5
-
6
4
  import ProviderMenu from '../../ProviderMenu';
7
5
  import Container from './Container';
8
6
 
9
7
  const Layout = ({ children }: PropsWithChildren) => {
10
8
  return (
11
- <>
12
- <NProgress />
13
- <Flexbox horizontal width={'100%'}>
14
- <ProviderMenu />
15
- <Container>{children}</Container>
16
- </Flexbox>
17
- </>
9
+ <Flexbox horizontal width={'100%'}>
10
+ <ProviderMenu />
11
+ <Container>{children}</Container>
12
+ </Flexbox>
18
13
  );
19
14
  };
20
15
  export default Layout;
@@ -31,7 +31,7 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
31
31
  const direction = isRtlLang(locale) ? 'rtl' : 'ltr';
32
32
 
33
33
  return (
34
- <html dir={direction} lang={locale} suppressHydrationWarning>
34
+ <html dir={direction} lang={locale}>
35
35
  <head>
36
36
  {process.env.DEBUG_REACT_SCAN === '1' && (
37
37
  // eslint-disable-next-line @next/next/no-sync-scripts
@@ -46,6 +46,7 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
46
46
  locale={locale}
47
47
  neutralColor={neutralColor}
48
48
  primaryColor={primaryColor}
49
+ variants={variants}
49
50
  >
50
51
  <AuthProvider>
51
52
  {children}
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+
3
+ import Link, { LinkProps } from 'next/link';
4
+ import { AnchorHTMLAttributes, ReactNode } from 'react';
5
+
6
+ import { useServerConfigStore } from '@/store/serverConfig';
7
+
8
+ interface InnerLinkProps
9
+ extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkProps>,
10
+ LinkProps {
11
+ children?: ReactNode | undefined;
12
+ }
13
+
14
+ const InnerLink = ({ href, ...props }: InnerLinkProps) => {
15
+ const variants = useServerConfigStore((s) => s.segmentVariants);
16
+
17
+ return <Link {...props} as={href} href={`/${variants}${href}`} />;
18
+ };
19
+
20
+ export default InnerLink;
@@ -115,11 +115,23 @@ export const UpdateModal = memo(() => {
115
115
  const closeDownloadedModal = () => setDownloadedInfo(null);
116
116
  const closeLatestVersionModal = () => setLatestVersionInfo(null);
117
117
 
118
+ const handleCancelCheck = () => {
119
+ setIsChecking(false);
120
+ setUpdateAvailableInfo(null);
121
+ setDownloadedInfo(null);
122
+ setProgress(null);
123
+ setLatestVersionInfo(null);
124
+ };
125
+
118
126
  const renderCheckingModal = () => (
119
127
  <Modal
120
- closable={false}
121
- footer={null}
122
- maskClosable={false}
128
+ closable
129
+ footer={[
130
+ <Button key="cancel" onClick={handleCancelCheck}>
131
+ {t('cancel', { ns: 'common' })}
132
+ </Button>,
133
+ ]}
134
+ onCancel={handleCancelCheck}
123
135
  open={isChecking}
124
136
  title={t('updater.checkingUpdate')}
125
137
  >
@@ -37,6 +37,6 @@ export const usePlatform = () => {
37
37
  ((platformInfo.isChromium && !platformInfo.isIOS) ||
38
38
  (platformInfo.isMacOS && platformInfo.isSonomaOrLaterSafari)),
39
39
  }),
40
- [platformInfo],
40
+ [],
41
41
  );
42
42
  };
@@ -23,6 +23,7 @@ interface GlobalLayoutProps {
23
23
  locale: string;
24
24
  neutralColor?: string;
25
25
  primaryColor?: string;
26
+ variants?: string;
26
27
  }
27
28
 
28
29
  const GlobalLayout = async ({
@@ -32,6 +33,7 @@ const GlobalLayout = async ({
32
33
  locale: userLocale,
33
34
  appearance,
34
35
  isMobile,
36
+ variants,
35
37
  }: GlobalLayoutProps) => {
36
38
  const antdLocale = await getAntdLocale(userLocale);
37
39
 
@@ -52,6 +54,7 @@ const GlobalLayout = async ({
52
54
  <ServerConfigStoreProvider
53
55
  featureFlags={serverFeatureFlags}
54
56
  isMobile={isMobile}
57
+ segmentVariants={variants}
55
58
  serverConfig={serverConfig}
56
59
  >
57
60
  <QueryProvider>
package/src/server/ld.ts CHANGED
@@ -22,7 +22,7 @@ export const AUTHOR_LIST = {
22
22
  avatar: 'https://avatars.githubusercontent.com/u/17870709?v=4',
23
23
  desc: 'Founder, Design Engineer',
24
24
  name: 'CanisMinor',
25
- url: 'https://github.com/arvinxx',
25
+ url: 'https://github.com/canisminor1990',
26
26
  },
27
27
  lobehub: {
28
28
  avatar: 'https://avatars.githubusercontent.com/u/131470832?v=4',
@@ -11,12 +11,17 @@ interface GlobalStoreProviderProps {
11
11
  children: ReactNode;
12
12
  featureFlags?: Partial<IFeatureFlags>;
13
13
  isMobile?: boolean;
14
+ segmentVariants?: string;
14
15
  serverConfig?: GlobalServerConfig;
15
16
  }
16
17
 
17
18
  export const ServerConfigStoreProvider = memo<GlobalStoreProviderProps>(
18
- ({ children, featureFlags, serverConfig, isMobile }) => (
19
- <Provider createStore={() => createServerConfigStore({ featureFlags, isMobile, serverConfig })}>
19
+ ({ children, featureFlags, serverConfig, isMobile, segmentVariants }) => (
20
+ <Provider
21
+ createStore={() =>
22
+ createServerConfigStore({ featureFlags, isMobile, segmentVariants, serverConfig })
23
+ }
24
+ >
20
25
  {children}
21
26
  </Provider>
22
27
  ),
@@ -15,11 +15,13 @@ import { ServerConfigAction, createServerConfigSlice } from './action';
15
15
  interface ServerConfigState {
16
16
  featureFlags: IFeatureFlags;
17
17
  isMobile?: boolean;
18
+ segmentVariants?: string;
18
19
  serverConfig: GlobalServerConfig;
19
20
  }
20
21
 
21
22
  const initialState: ServerConfigState = {
22
23
  featureFlags: DEFAULT_FEATURE_FLAGS,
24
+ segmentVariants: '',
23
25
  serverConfig: { aiProvider: {}, telemetry: {} },
24
26
  };
25
27