diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json
index e49f8fff8e..7c490455ae 100644
--- a/packages/frontend/core/package.json
+++ b/packages/frontend/core/package.json
@@ -83,6 +83,7 @@
"react-transition-state": "^2.2.0",
"react-virtuoso": "^4.12.3",
"rxjs": "^7.8.1",
+ "semver": "^7.7.2",
"ses": "^1.10.0",
"shiki": "^3.7.0",
"socket.io-client": "^4.8.1",
@@ -100,6 +101,7 @@
"@types/bytes": "^3.1.5",
"@types/image-blob-reduce": "^4.1.4",
"@types/lodash-es": "^4.17.12",
+ "@types/semver": "^7",
"@vanilla-extract/css": "^1.17.0",
"fake-indexeddb": "^6.0.0",
"lodash-es": "^4.17.21",
diff --git a/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx b/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx
new file mode 100644
index 0000000000..03deadf703
--- /dev/null
+++ b/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx
@@ -0,0 +1,57 @@
+import type { Server } from '@affine/core/modules/cloud';
+import { useLiveData } from '@toeverything/infra';
+import { cssVarV2 } from '@toeverything/theme/v2';
+import semver from 'semver';
+
+const rules = [
+ {
+ min: '0.23.0',
+ tip: (receivedVersion: string, requiredVersion: string) => (
+
+
+ Your server version{' '}
+ {receivedVersion} is not compatible
+ with current client. Please upgrade your server to{' '}
+ {requiredVersion} or higher to use
+ this client.
+
+
+
+ ),
+ },
+];
+
+/**
+ * Return the error tip if the server version is not meet the requirement
+ */
+export const useSelfhostLoginVersionGuard = (server: Server) => {
+ const serverVersion =
+ useLiveData(server.config$.selector(c => c.version)) ?? '0.0.0';
+
+ for (const rule of rules) {
+ if (semver.lt(serverVersion, rule.min)) {
+ return rule.tip(serverVersion, rule.min);
+ }
+ }
+
+ return null;
+};
diff --git a/packages/frontend/core/src/components/sign-in/sign-in.tsx b/packages/frontend/core/src/components/sign-in/sign-in.tsx
index 09126c08c5..e9bf6d7c86 100644
--- a/packages/frontend/core/src/components/sign-in/sign-in.tsx
+++ b/packages/frontend/core/src/components/sign-in/sign-in.tsx
@@ -27,6 +27,7 @@ import {
useState,
} from 'react';
+import { useSelfhostLoginVersionGuard } from '../hooks/affine/use-selfhost-login-version-guard';
import type { SignInState } from '.';
import { Back } from './back';
import * as style from './style.css';
@@ -54,6 +55,7 @@ export const SignInStep = ({
const serverName = useLiveData(
serverService.server.config$.selector(c => c.serverName)
);
+ const versionError = useSelfhostLoginVersionGuard(serverService.server);
const isSelfhosted = useLiveData(
serverService.server.config$.selector(
c => c.type === ServerDeploymentType.Selfhosted
@@ -125,6 +127,20 @@ export const SignInStep = ({
}));
}, [changeState]);
+ if (versionError && isSelfhosted) {
+ return (
+
+
+
+ {versionError}
+
+
+ );
+ }
+
return (
{
ref={floatWorkspaceCardRef}
/>
}>
-
+
{notificationCount > 0 && (