diff --git a/.github/workflows/Deploy.yml b/.github/workflows/Deploy.yml
index 76be8c1..6440c3f 100644
--- a/.github/workflows/Deploy.yml
+++ b/.github/workflows/Deploy.yml
@@ -30,13 +30,6 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Login to AliYun Container Registry
- uses: docker/login-action@v3
- with:
- registry: registry.cn-guangzhou.aliyuncs.com
- username: ${{ secrets.ALI_USERNAME }}
- password: ${{ secrets.ALI_TOKEN }}
-
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index e917047..ac09e07 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -25,8 +25,8 @@ jobs:
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
with:
upstream_sync_repo: hamster1963/nezha-dash
- upstream_sync_branch: main
- target_sync_branch: main
+ upstream_sync_branch: cloudflare
+ target_sync_branch: cloudflare
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set
# Set test_mode true to run tests instead of the true action!!
diff --git a/README.md b/README.md
index 3857359..12dc995 100644
--- a/README.md
+++ b/README.md
@@ -8,34 +8,26 @@
| 一键部署到 Vercel-推荐 | Docker部署 | Cloudflare部署 | 如何更新? |
| ----------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------- |
| [部署简易教程](https://buycoffee.top/blog/tech/nezha) | [Docker 部署教程](https://buycoffee.top/blog/tech/nezha-docker) | [Cloudflare 部署教程](https://buycoffee.top/blog/tech/nezha-cloudflare) | [更新教程](https://buycoffee.top/blog/tech/nezha-upgrade) |
-| [Vercel-demo](https://nezha-dash-ruddy.vercel.app) | [Docker-demo](https://nezha-docker.buycoffee.tech) | [Cloudflare-demo](https://nezha-cloudflare.buycoffee.tech) |
+| [Vercel-demo](https://nezha-vercel.buycoffee.top) | [Docker-demo](https://nezha-docker.buycoffee.tech) | [Cloudflare-demo](https://nezha-cloudflare.buycoffee.tech) |
#### 环境变量
-| 变量名 | 含义 | 示例 |
-| ------------------------------ | -------------------------------- | ------------------------------------------------------------- |
-| NezhaBaseUrl | nezha 面板地址 | http://120.x.x.x:8008 |
-| NezhaAuth | nezha 面板 API Token | 5hAY3QX6Nl9B3Uxxxx26KMvOMyXS1Udi |
-| DefaultLocale | 面板默认显示语言(代码参考下表) | **默认**:en |
-| ForceShowAllServers | 是否强制显示所有服务器 | **默认**:false |
-| NEXT_PUBLIC_NezhaFetchInterval | 获取数据间隔(毫秒) | **默认**:2000 |
-| NEXT_PUBLIC_ShowFlag | 是否显示旗帜 | **默认**:false |
-| NEXT_PUBLIC_DisableCartoon | 是否禁用卡通人物 | **默认**:false |
-| NEXT_PUBLIC_ShowTag | 是否显示标签 | **默认**:false |
-| NEXT_PUBLIC_ShowNetTransfer | 是否显示流量信息 | **默认**:false |
-| NEXT_PUBLIC_ForceUseSvgFlag | 是否强制使用SVG旗帜 | **默认**:false |
-| NEXT_PUBLIC_CustomLogo | 自定义Logo | **示例**:https://nezha-cf.buycoffee.top/apple-touch-icon.png |
-| NEXT_PUBLIC_CustomTitle | 自定义标题 | |
-| NEXT_PUBLIC_CustomDescription | 自定义描述(无多语言支持) | |
-
-#### 多语言支持
-
-| 语言 | 代码 | 是否完成翻译 |
-| -------- | ---- | ------------ |
-| 简体中文 | zh | 是 |
-| 繁体中文 | zh-t | 是 |
-| 英语 | en | 是 |
-| 日语 | ja | 是 |
+| 变量名 | 含义 | 示例 |
+| ------------------------------ | ------------------------ | ------------------------------------------------------------- |
+| NezhaBaseUrl | nezha 面板地址 | http://120.x.x.x:8008 |
+| NezhaAuth | nezha 面板 API Token | 5hAY3QX6Nl9B3Uxxxx26KMvOMyXS1Udi |
+| SitePassword | 页面密码 | 123456 |
+| DefaultLocale | 面板默认显示语言 | **默认**:en [简中:zh 繁中:zh-t 英语:en 日语:ja] |
+| ForceShowAllServers | 是否强制显示所有服务器 | **默认**:false |
+| NEXT_PUBLIC_NezhaFetchInterval | 获取数据间隔(毫秒) | **默认**:2000 |
+| NEXT_PUBLIC_ShowFlag | 是否显示旗帜 | **默认**:false |
+| NEXT_PUBLIC_DisableCartoon | 是否禁用卡通人物 | **默认**:false |
+| NEXT_PUBLIC_ShowTag | 是否显示标签 | **默认**:false |
+| NEXT_PUBLIC_ShowNetTransfer | 是否显示流量信息 | **默认**:false |
+| NEXT_PUBLIC_ForceUseSvgFlag | 是否强制使用SVG旗帜 | **默认**:false |
+| NEXT_PUBLIC_CustomLogo | 自定义Logo | **示例**:https://nezha-cf.buycoffee.top/apple-touch-icon.png |
+| NEXT_PUBLIC_CustomTitle | 自定义标题 | |
+| NEXT_PUBLIC_CustomDescription | 自定义描述(无多语言支持) | |


diff --git a/app/[locale]/(main)/ClientComponents/ServerDetailChartClient.tsx b/app/[locale]/(main)/ClientComponents/ServerDetailChartClient.tsx
index 9e05bcb..43e41cc 100644
--- a/app/[locale]/(main)/ClientComponents/ServerDetailChartClient.tsx
+++ b/app/[locale]/(main)/ClientComponents/ServerDetailChartClient.tsx
@@ -1,5 +1,7 @@
"use client";
+import { ServerDetailChartLoading } from "@/app/[locale]/(main)/ClientComponents/ServerDetailLoading";
+import { NezhaAPISafe } from "@/app/[locale]/types/nezha-api";
import AnimatedCircularProgressBar from "@/components/ui/animated-circular-progress-bar";
import { Card, CardContent } from "@/components/ui/card";
import { ChartConfig, ChartContainer } from "@/components/ui/chart";
@@ -18,8 +20,6 @@ import {
} from "recharts";
import useSWR from "swr";
-import { NezhaAPISafe } from "../../types/nezha-api";
-
type cpuChartData = {
timeStamp: string;
cpu: number;
@@ -83,7 +83,7 @@ export default function ServerDetailChartClient({
>
);
}
- if (!data) return null;
+ if (!data) return ;
return (
diff --git a/app/[locale]/(main)/ClientComponents/ServerDetailClient.tsx b/app/[locale]/(main)/ClientComponents/ServerDetailClient.tsx
index 718f814..1c05446 100644
--- a/app/[locale]/(main)/ClientComponents/ServerDetailClient.tsx
+++ b/app/[locale]/(main)/ClientComponents/ServerDetailClient.tsx
@@ -1,5 +1,6 @@
"use client";
+import { ServerDetailLoading } from "@/app/[locale]/(main)/ClientComponents/ServerDetailLoading";
import { NezhaAPISafe } from "@/app/[locale]/types/nezha-api";
import { BackIcon } from "@/components/Icon";
import { Badge } from "@/components/ui/badge";
@@ -10,8 +11,6 @@ import { useLocale, useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import useSWR from "swr";
-import ServerDetailLoading from "./ServerDetailLoading";
-
export default function ServerDetailClient({
server_id,
}: {
diff --git a/app/[locale]/(main)/ClientComponents/ServerDetailLoading.tsx b/app/[locale]/(main)/ClientComponents/ServerDetailLoading.tsx
index 2dc538b..1036e3e 100644
--- a/app/[locale]/(main)/ClientComponents/ServerDetailLoading.tsx
+++ b/app/[locale]/(main)/ClientComponents/ServerDetailLoading.tsx
@@ -1,25 +1,11 @@
import { BackIcon } from "@/components/Icon";
-import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { useLocale } from "next-intl";
import { useRouter } from "next/navigation";
-export default function ServerDetailLoading() {
- const router = useRouter();
- const locale = useLocale();
+export function ServerDetailChartLoading() {
return (
-
{
- router.push(`/${locale}/`);
- }}
- className="flex flex-none cursor-pointer font-semibold leading-none items-center break-all tracking-tight gap-0.5 text-xl"
- >
-
-
-
-
-
@@ -31,3 +17,23 @@ export default function ServerDetailLoading() {
);
}
+
+export function ServerDetailLoading() {
+ const router = useRouter();
+ const locale = useLocale();
+
+ return (
+ <>
+ {
+ router.push(`/${locale}/`);
+ }}
+ className="flex flex-none cursor-pointer font-semibold leading-none items-center break-all tracking-tight gap-0.5 text-xl"
+ >
+
+
+
+
+ >
+ );
+}
diff --git a/app/[locale]/(main)/header.tsx b/app/[locale]/(main)/header.tsx
index a7d9ec7..e09323f 100644
--- a/app/[locale]/(main)/header.tsx
+++ b/app/[locale]/(main)/header.tsx
@@ -3,6 +3,7 @@
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
import { ModeToggle } from "@/components/ThemeSwitcher";
import { Separator } from "@/components/ui/separator";
+import { Skeleton } from "@/components/ui/skeleton";
import getEnv from "@/lib/env-entry";
import { DateTime } from "luxon";
import { useTranslations } from "next-intl";
@@ -20,7 +21,6 @@ function Header() {
const router = useRouter();
const locale = useLocale();
-
return (
@@ -63,7 +63,7 @@ function Header() {
// https://github.com/streamich/react-use/blob/master/src/useInterval.ts
const useInterval = (callback: Function, delay?: number | null) => {
- const savedCallback = useRef(() => { });
+ const savedCallback = useRef(() => {});
useEffect(() => {
savedCallback.current = callback;
});
@@ -96,9 +96,9 @@ function Overview() {
{t("p_2390-2457_wherethetimeis")}
- {mouted && (
+ {mouted ? (
{timeString}
- )}
+ ) : }
);
diff --git a/app/[locale]/(main)/layout.tsx b/app/[locale]/(main)/layout.tsx
index dd0530d..bb2a8de 100644
--- a/app/[locale]/(main)/layout.tsx
+++ b/app/[locale]/(main)/layout.tsx
@@ -1,20 +1,23 @@
import Footer from "@/app/[locale]/(main)/footer";
import Header from "@/app/[locale]/(main)/header";
import { auth } from "@/auth";
+import { SignIn } from "@/components/sign-in";
import getEnv from "@/lib/env-entry";
-import React from "react";
import { redirect } from "next/navigation";
-import { getLocale } from "next-intl/server";
+import React from "react";
type DashboardProps = {
children: React.ReactNode;
};
export default async function MainLayout({ children }: DashboardProps) {
- const session = await auth()
- const locale = await getLocale()
+ const session = await auth();
- if (!session && getEnv("SITE_PASSWORD")) {
- redirect(`/${locale}/login`);
+ if (!session && getEnv("SitePassword")) {
+ if (getEnv("CF_PAGES")) {
+ redirect("/api/auth/signin");
+ } else {
+ return ;
+ }
}
return (
diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx
index 2b2864f..db96506 100644
--- a/app/[locale]/layout.tsx
+++ b/app/[locale]/layout.tsx
@@ -1,4 +1,5 @@
// @auto-i18n-check. Please do not delete the line.
+import { auth } from "@/auth";
import { locales } from "@/i18n-metadata";
import getEnv from "@/lib/env-entry";
import { cn } from "@/lib/utils";
@@ -13,7 +14,6 @@ import { Inter as FontSans } from "next/font/google";
import React from "react";
import "/node_modules/flag-icons/css/flag-icons.min.css";
-import { auth } from "@/auth";
const fontSans = FontSans({
subsets: ["latin"],
@@ -41,6 +41,11 @@ export const viewport: Viewport = {
userScalable: false,
};
+// optimization: force static for vercel
+export const dynamic = process.env.VERCEL ? "force-static" : "auto";
+
+export const runtime = "edge";
+
export async function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}
diff --git a/app/[locale]/not-found.tsx b/app/[locale]/not-found.tsx
index 07cd8d6..237a1e0 100644
--- a/app/[locale]/not-found.tsx
+++ b/app/[locale]/not-found.tsx
@@ -2,7 +2,7 @@ import { useTranslations } from "next-intl";
import Image from "next/image";
import Link from "next/link";
-export const runtime = 'edge';
+export const runtime = "edge";
export default function NotFoundPage() {
const t = useTranslations("NotFoundPage");
diff --git a/app/api/detail/route.ts b/app/api/detail/route.ts
index 81538db..0cc589b 100644
--- a/app/api/detail/route.ts
+++ b/app/api/detail/route.ts
@@ -1,8 +1,10 @@
import { NezhaAPISafe } from "@/app/[locale]/types/nezha-api";
+import { auth } from "@/auth";
+import getEnv from "@/lib/env-entry";
import { GetServerDetail } from "@/lib/serverFetch";
import { NextResponse } from "next/server";
-import { auth } from "@/auth"
-import getEnv from "@/lib/env-entry";
+
+export const runtime = 'edge';
export const dynamic = "force-dynamic";
export const runtime = 'edge';
@@ -13,8 +15,7 @@ interface NezhaDataResponse {
}
export const GET = auth(async function GET(req) {
-
- if (!req.auth && getEnv("SITE_PASSWORD")) {
+ if (!req.auth && getEnv("SitePassword")) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
}
diff --git a/app/api/monitor/route.ts b/app/api/monitor/route.ts
index 0f44513..f37462a 100644
--- a/app/api/monitor/route.ts
+++ b/app/api/monitor/route.ts
@@ -4,6 +4,8 @@ import getEnv from "@/lib/env-entry";
import { GetServerMonitor } from "@/lib/serverFetch";
import { NextResponse } from "next/server";
+export const runtime = "edge";
+
export const dynamic = "force-dynamic";
export const runtime = 'edge';
@@ -13,8 +15,7 @@ interface NezhaDataResponse {
}
export const GET = auth(async function GET(req) {
-
- if (!req.auth && getEnv("SITE_PASSWORD")) {
+ if (!req.auth && getEnv("SitePassword")) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
}
diff --git a/app/api/server/route.ts b/app/api/server/route.ts
index 41db0d5..1fe524d 100644
--- a/app/api/server/route.ts
+++ b/app/api/server/route.ts
@@ -1,13 +1,12 @@
-
import { NezhaAPI, ServerApi } from "@/app/[locale]/types/nezha-api";
-import { auth } from "@/auth";
import { MakeOptional } from "@/app/[locale]/types/utils";
+import { auth } from "@/auth";
import getEnv from "@/lib/env-entry";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
-export const runtime = 'edge';
+export const runtime = "edge";
interface NezhaDataResponse {
error?: string;
@@ -15,8 +14,7 @@ interface NezhaDataResponse {
}
export const GET = auth(async function GET(req) {
-
- if (!req.auth && getEnv("SITE_PASSWORD")) {
+ if (!req.auth && getEnv("SitePassword")) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
}
diff --git a/auth.ts b/auth.ts
index a908388..d53aeae 100644
--- a/auth.ts
+++ b/auth.ts
@@ -1,20 +1,21 @@
-import NextAuth from "next-auth"
-import Credentials from "next-auth/providers/credentials"
-import getEnv from "./lib/env-entry"
-
+import NextAuth from "next-auth";
+import Credentials from "next-auth/providers/credentials";
+
+import getEnv from "./lib/env-entry";
+
export const { handlers, signIn, signOut, auth } = NextAuth({
- secret:"this_is_nezha_dash_web_secret",
+ secret: "this_is_nezha_dash_web_secret",
providers: [
Credentials({
credentials: {
password: {},
},
authorize: async (credentials) => {
- if (credentials.password === getEnv("SITE_PASSWORD")) {
- return { id: "0" }
+ if (credentials.password === getEnv("SitePassword")) {
+ return { id: "0" };
}
- return null
+ return null;
},
}),
],
-})
\ No newline at end of file
+});
diff --git a/components/sign-in.tsx b/components/sign-in.tsx
index 033ccf0..e16ccc3 100644
--- a/components/sign-in.tsx
+++ b/components/sign-in.tsx
@@ -1,42 +1,47 @@
-import Footer from "@/app/[locale]/(main)/footer"
-import Header from "@/app/[locale]/(main)/header"
-import { signIn } from "@/auth"
-import { useLocale } from "next-intl"
-import { redirect } from "next/navigation"
+import Footer from "@/app/[locale]/(main)/footer";
+import Header from "@/app/[locale]/(main)/header";
+import { signIn } from "@/auth";
+import { useLocale } from "next-intl";
+import { redirect } from "next/navigation";
export const runtime = 'edge';
export function SignIn() {
- const locale = useLocale()
+ const locale = useLocale();
-
- async function handleSubmit(formData: FormData) {
- 'use server'
- try {
- await signIn("credentials", formData)
- } catch (error) {
- redirect(`/${locale}`)
- }
+ async function handleSubmit(formData: FormData) {
+ "use server";
+ try {
+ await signIn("credentials", formData);
+ } catch (error) {
+ redirect(`/${locale}`);
}
+ }
- return (
-
- )
+ return (
+
+ );
}
diff --git a/docker/docker-compose.yml.cn b/docker/docker-compose.yml.cn
deleted file mode 100644
index 99a97c7..0000000
--- a/docker/docker-compose.yml.cn
+++ /dev/null
@@ -1,10 +0,0 @@
-version: "3"
-services:
- nezha-dash:
- container_name: nezha-dash
- image: registry.cn-guangzhou.aliyuncs.com/hamster-home/nezha-dash:latest
- volumes:
- - ./.env:/app/.env
- restart: always
- ports:
- - "4123:3000"
diff --git a/next.config.mjs b/next.config.mjs
index 5713407..a68be47 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -25,7 +25,7 @@ const nextConfig = {
reactStrictMode: true,
experimental: {
serverActions: {
- allowedOrigins: ['*'],
+ allowedOrigins: ["*"],
},
},
logging: {