diff --git a/app/(main)/ClientComponents/ServerListClient.tsx b/app/(main)/ClientComponents/ServerListClient.tsx deleted file mode 100644 index cc82121..0000000 --- a/app/(main)/ClientComponents/ServerListClient.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { ServerApi } from "@/app/types/nezha-api"; -import ServerCard from "@/components/ServerCard"; -import { nezhaFetcher } from "@/lib/utils"; -import useSWR from "swr"; -import getEnv from "@/lib/env-entry"; - -export default function ServerListClient() { - const { data } = useSWR("/api/server", nezhaFetcher, { - refreshInterval: Number(getEnv("NEXT_PUBLIC_NezhaFetchInterval")) || 2000, - }); - - if (!data) return null; - - const sortedServers = data.result.sort((a, b) => { - if (a.display_index && b.display_index) { - return b.display_index - a.display_index; - } - if (a.display_index) return -1; - if (b.display_index) return 1; - return a.id - b.id; - }); - - return ( -
- {sortedServers.map((serverInfo) => ( - - ))} -
- ); -} diff --git a/app/(main)/ClientComponents/ServerOverviewClient.tsx b/app/(main)/ClientComponents/ServerOverviewClient.tsx deleted file mode 100644 index 1450765..0000000 --- a/app/(main)/ClientComponents/ServerOverviewClient.tsx +++ /dev/null @@ -1,111 +0,0 @@ -"use client"; - -import { Card, CardContent } from "@/components/ui/card"; -import blogMan from "@/public/blog-man.webp"; -import Image from "next/image"; -import useSWR from "swr"; -import { formatBytes, nezhaFetcher } from "@/lib/utils"; -import { Loader } from "@/components/loading/Loader"; -import { ServerApi } from "@/app/types/nezha-api"; -import getEnv from "@/lib/env-entry"; - -export default function ServerOverviewClient() { - const { data } = useSWR("/api/server", nezhaFetcher); - - const disableCartoon = getEnv("NEXT_PUBLIC_DisableCartoon") === "true"; - - return ( -
- - -
-

Total servers

-
- - - - {data ? ( -
- {data?.result.length} -
- ) : ( -
- -
- )} -
-
-
-
- - -
-

Online servers

-
- - - - - {data ? ( -
- {data?.live_servers} -
- ) : ( -
- -
- )} -
-
-
-
- - -
-

Offline servers

-
- - - - - {data ? ( -
- {data?.offline_servers} -
- ) : ( -
- -
- )} -
-
-
-
- - -
-

Total bandwidth

- {data ? ( -

- {formatBytes(data?.total_bandwidth)} -

- ) : ( -
- -
- )} -
- {!disableCartoon && ( - {"Hamster1963"} - )} -
-
-
- ); -} diff --git a/app/(main)/footer.tsx b/app/(main)/footer.tsx deleted file mode 100644 index 5f8a5e3..0000000 --- a/app/(main)/footer.tsx +++ /dev/null @@ -1,22 +0,0 @@ -export default function Footer() { - return ( - - ); -} diff --git a/app/(main)/layout.tsx b/app/(main)/layout.tsx deleted file mode 100644 index 6a77ce3..0000000 --- a/app/(main)/layout.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; - -import Header from "@/app/(main)/header"; -import Footer from "./footer"; - -type DashboardProps = { - children: React.ReactNode; -}; - -export default function MainLayout({ children }: DashboardProps) { - return ( -
-
-
- {children} -
-
-
- ); -} diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx deleted file mode 100644 index 86719a1..0000000 --- a/app/(main)/page.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import ServerList from "@/components/ServerList"; -import ServerOverview from "@/components/ServerOverview"; -import getEnv from "@/lib/env-entry"; -import { GetNezhaData } from "@/lib/serverFetch"; - -import { SWRConfig } from "swr"; - -const disablePrefetch = getEnv("ServerDisablePrefetch") === "true"; - -const fallback = disablePrefetch - ? {} - : { - "/api/server": GetNezhaData(), - }; - -export default function Home() { - return ( - -
- - -
-
- ); -} diff --git a/app/[locale]/(main)/ClientComponents/ServerListClient.tsx b/app/[locale]/(main)/ClientComponents/ServerListClient.tsx new file mode 100644 index 0000000..c01f1b9 --- /dev/null +++ b/app/[locale]/(main)/ClientComponents/ServerListClient.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { useTranslations } from 'next-intl'; +import { ServerApi } from "../../types/nezha-api"; +import ServerCard from "../../../../components/ServerCard"; +import { nezhaFetcher } from "../../../../lib/utils"; +import useSWR from "swr"; +import getEnv from "../../../../lib/env-entry"; +export default function ServerListClient() { + const { + data + } = useSWR("/api/server", nezhaFetcher, { + refreshInterval: Number(getEnv("NEXT_PUBLIC_NezhaFetchInterval")) || 2000 + }); + if (!data) return null; + const sortedServers = data.result.sort((a, b) => { + if (a.display_index && b.display_index) { + return b.display_index - a.display_index; + } + if (a.display_index) return -1; + if (b.display_index) return 1; + return a.id - b.id; + }); + return
+ {sortedServers.map(serverInfo => )} +
; +} \ No newline at end of file diff --git a/app/[locale]/(main)/ClientComponents/ServerOverviewClient.tsx b/app/[locale]/(main)/ClientComponents/ServerOverviewClient.tsx new file mode 100644 index 0000000..4b4fdeb --- /dev/null +++ b/app/[locale]/(main)/ClientComponents/ServerOverviewClient.tsx @@ -0,0 +1,86 @@ +"use client"; + +import { useTranslations } from 'next-intl'; +import { Card, CardContent } from "../../../../components/ui/card"; +import blogMan from "../../../../public/blog-man.webp"; +import Image from "next/image"; +import useSWR from "swr"; +import { formatBytes, nezhaFetcher } from "../../../../lib/utils"; +import { Loader } from "../../../../components/loading/Loader"; +import { ServerApi } from "../../types/nezha-api"; +import getEnv from "../../../../lib/env-entry"; +export default function ServerOverviewClient() { + const t = useTranslations("ServerOverviewClient"); + const { + data + } = useSWR("/api/server", nezhaFetcher); + const disableCartoon = getEnv("NEXT_PUBLIC_DisableCartoon") === "true"; + return
+ + +
+

{t('p_816-881_Totalservers')}

+
+ + + + {data ?
+ {data?.result.length} +
:
+ +
} +
+
+
+
+ + +
+

{t('p_1610-1676_Onlineservers')}

+
+ + + + + {data ?
+ {data?.live_servers} +
:
+ +
} +
+
+
+
+ + +
+

{t('p_2532-2599_Offlineservers')}

+
+ + + + + {data ?
+ {data?.offline_servers} +
:
+ +
} +
+
+
+
+ + +
+

{t('p_3463-3530_Totalbandwidth')}

+ {data ?

+ {formatBytes(data?.total_bandwidth)} +

:
+ +
} +
+ {!disableCartoon && {"Hamster1963"}} +
+
+
; +} \ No newline at end of file diff --git a/app/[locale]/(main)/footer.tsx b/app/[locale]/(main)/footer.tsx new file mode 100644 index 0000000..920c271 --- /dev/null +++ b/app/[locale]/(main)/footer.tsx @@ -0,0 +1,14 @@ +import { useTranslations } from 'next-intl'; +export default function Footer() { + const t = useTranslations("Footer"); + return ; +} \ No newline at end of file diff --git a/app/(main)/header.tsx b/app/[locale]/(main)/header.tsx similarity index 53% rename from app/(main)/header.tsx rename to app/[locale]/(main)/header.tsx index 9be6e09..fcb3ac8 100644 --- a/app/(main)/header.tsx +++ b/app/[locale]/(main)/header.tsx @@ -1,86 +1,61 @@ "use client"; +import { useTranslations } from 'next-intl'; import React, { useEffect, useRef, useState } from "react"; import Image from "next/image"; -import { Separator } from "@/components/ui/separator"; +import { Separator } from "../../../components/ui/separator"; import { DateTime } from "luxon"; -import { ModeToggle } from "@/components/ThemeSwitcher"; - +import { ModeToggle } from "../../../components/ThemeSwitcher"; function Header() { - return ( -
+ const t = useTranslations("Header"); + return
- apple-touch-icon + apple-touch-icon
NezhaDash - -

- Simple and beautiful dashboard -

+ +

{t('p_1079-1199_Simpleandbeautifuldashbo')}

-
- ); +
; } // https://github.com/streamich/react-use/blob/master/src/useInterval.ts const useInterval = (callback: Function, delay?: number | null) => { const savedCallback = useRef(() => {}); - useEffect(() => { savedCallback.current = callback; }); - useEffect(() => { if (delay !== null) { const interval = setInterval(() => savedCallback.current(), delay || 0); return () => clearInterval(interval); } - return undefined; }, [delay]); }; - function Overview() { + const t = useTranslations("Overview"); const [mouted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); const timeOption = DateTime.TIME_SIMPLE; timeOption.hour12 = true; - const [timeString, setTimeString] = useState( - DateTime.now().setLocale("en-US").toLocaleString(timeOption), - ); - + const [timeString, setTimeString] = useState(DateTime.now().setLocale("en-US").toLocaleString(timeOption)); useInterval(() => { setTimeString(DateTime.now().setLocale("en-US").toLocaleString(timeOption)); }, 1000); - - return ( -
-

👋 Overview

+ return
+

{t('p_2277-2331_Overview')}

-

where the time is

- {mouted && ( -

{timeString}

- )} +

{t('p_2390-2457_wherethetimeis')}

+ {mouted &&

{timeString}

}
-
- ); +
; } - -export default Header; +export default Header; \ No newline at end of file diff --git a/app/[locale]/(main)/layout.tsx b/app/[locale]/(main)/layout.tsx new file mode 100644 index 0000000..bbaa151 --- /dev/null +++ b/app/[locale]/(main)/layout.tsx @@ -0,0 +1,18 @@ +import { useTranslations } from 'next-intl'; +import React from "react"; +import Header from "@/app/[locale]/(main)/header"; +import Footer from "./footer"; +type DashboardProps = { + children: React.ReactNode; +}; +export default function MainLayout({ + children +}: DashboardProps) { + return
+
+
+ {children} +
+
+
; +} \ No newline at end of file diff --git a/app/[locale]/(main)/page.tsx b/app/[locale]/(main)/page.tsx new file mode 100644 index 0000000..b3a0b2c --- /dev/null +++ b/app/[locale]/(main)/page.tsx @@ -0,0 +1,20 @@ +import { useTranslations } from 'next-intl'; +import ServerList from "../../../components/ServerList"; +import ServerOverview from "../../../components/ServerOverview"; +import getEnv from "../../../lib/env-entry"; +import { GetNezhaData } from "../../../lib/serverFetch"; +import { SWRConfig } from "swr"; +const disablePrefetch = getEnv("ServerDisablePrefetch") === "true"; +const fallback = disablePrefetch ? {} : { + "/api/server": GetNezhaData() +}; +export default function Home() { + return +
+ + +
+
; +} \ No newline at end of file diff --git a/app/android-chrome-192x192.png b/app/[locale]/android-chrome-192x192.png similarity index 100% rename from app/android-chrome-192x192.png rename to app/[locale]/android-chrome-192x192.png diff --git a/app/android-chrome-512x512.png b/app/[locale]/android-chrome-512x512.png similarity index 100% rename from app/android-chrome-512x512.png rename to app/[locale]/android-chrome-512x512.png diff --git a/app/apple-touch-icon.png b/app/[locale]/apple-touch-icon.png similarity index 100% rename from app/apple-touch-icon.png rename to app/[locale]/apple-touch-icon.png diff --git a/app/favicon-16x16.png b/app/[locale]/favicon-16x16.png similarity index 100% rename from app/favicon-16x16.png rename to app/[locale]/favicon-16x16.png diff --git a/app/favicon-32x32.png b/app/[locale]/favicon-32x32.png similarity index 100% rename from app/favicon-32x32.png rename to app/[locale]/favicon-32x32.png diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx new file mode 100644 index 0000000..f6b3307 --- /dev/null +++ b/app/[locale]/layout.tsx @@ -0,0 +1,22 @@ +// @auto-i18n-check. Please do not delete the line. + +import React from "react"; +import {NextIntlClientProvider, useMessages} from 'next-intl'; + +export default function LocaleLayout({ + children, + params: {locale} + }: { + children: React.ReactNode; params: { locale: string }; +}) { + const messages = useMessages(); + return ( + + + + {children} + + + + ); +} diff --git a/app/[locale]/not-found.tsx b/app/[locale]/not-found.tsx new file mode 100644 index 0000000..6f4d31a --- /dev/null +++ b/app/[locale]/not-found.tsx @@ -0,0 +1,16 @@ +import { useTranslations } from 'next-intl'; +import Image from "next/image"; +import Link from "next/link"; +export default function NotFoundPage() { + const t = useTranslations("NotFoundPage"); + return
+
+ TARDIS +
+

{t('h1_490-590_404NotFound')}

+

{t('p_601-665_TARDISERROR')}

+ {t('Link_676-775_Doctor')} +
+
+
; +} \ No newline at end of file diff --git a/app/types/nezha-api.ts b/app/[locale]/types/nezha-api.ts similarity index 100% rename from app/types/nezha-api.ts rename to app/[locale]/types/nezha-api.ts diff --git a/app/types/utils.ts b/app/[locale]/types/utils.ts similarity index 100% rename from app/types/utils.ts rename to app/[locale]/types/utils.ts diff --git a/app/not-found.tsx b/app/not-found.tsx deleted file mode 100644 index 3c78834..0000000 --- a/app/not-found.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import Image from "next/image"; -import Link from "next/link"; - -export default function NotFoundPage() { - return ( -
-
- TARDIS -
-

- 404 Not Found -

-

TARDIS ERROR!

- - Doctor? - -
-
-
- ); -} diff --git a/auto-i18n-config.json b/auto-i18n-config.json new file mode 100644 index 0000000..c7648db --- /dev/null +++ b/auto-i18n-config.json @@ -0,0 +1,15 @@ +{ + "defaultLang": "en", + "translatorServerName": "azure", + "needLangs": [ + "en", + "zh", + "zh-t", + "ja" + ], + "brandWords": [], + "unMoveToLocaleDirFiles": [], + "enableStaticRendering": false, + "enableSubPageRedirectToLocale": false, + "disableDefaultLangRedirect": true +} \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 4a5a2aa..5e3d148 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/ServerCard.tsx b/components/ServerCard.tsx index b0f63aa..a881292 100644 --- a/components/ServerCard.tsx +++ b/components/ServerCard.tsx @@ -1,4 +1,4 @@ -import { NezhaAPISafe } from "@/app/types/nezha-api"; +import { NezhaAPISafe } from "../app/[locale]/types/nezha-api"; import ServerUsageBar from "@/components/ServerUsageBar"; import { Card } from "@/components/ui/card"; import { diff --git a/components/ServerCardPopover.tsx b/components/ServerCardPopover.tsx index d678c3b..2b03835 100644 --- a/components/ServerCardPopover.tsx +++ b/components/ServerCardPopover.tsx @@ -1,4 +1,4 @@ -import { NezhaAPISafe } from "@/app/types/nezha-api"; +import { NezhaAPISafe } from "../app/[locale]/types/nezha-api"; import { cn, formatBytes } from "@/lib/utils"; export function ServerCardPopoverCard({ diff --git a/components/ServerList.tsx b/components/ServerList.tsx index 14c28d2..9448640 100644 --- a/components/ServerList.tsx +++ b/components/ServerList.tsx @@ -1,6 +1,6 @@ import React from "react"; -import ServerListClient from "@/app/(main)/ClientComponents/ServerListClient"; +import ServerListClient from "../app/[locale]/(main)/ClientComponents/ServerListClient"; export default async function ServerList() { return ; diff --git a/components/ServerOverview.tsx b/components/ServerOverview.tsx index 2e61c79..359dc63 100644 --- a/components/ServerOverview.tsx +++ b/components/ServerOverview.tsx @@ -1,4 +1,4 @@ -import ServerOverviewClient from "@/app/(main)/ClientComponents/ServerOverviewClient"; +import ServerOverviewClient from "../app/[locale]/(main)/ClientComponents/ServerOverviewClient"; export default async function ServerOverview() { return ; diff --git a/i18n-metadata.ts b/i18n-metadata.ts new file mode 100644 index 0000000..e7e755b --- /dev/null +++ b/i18n-metadata.ts @@ -0,0 +1,24 @@ +// @auto-i18n-check. Please do not delete the line. + +export const localeItems = [ +{code: 'en', name: 'English'}, +{code: 'ja', name: '日本語'}, +{code: 'zh-t', name: '中文繁體'}, +{code: 'zh', name: '中文简体'}, +//{code: 'ar', name: 'العربية'}, +//{code: 'de', name: 'Deutsch'}, +//{code: 'es', name: 'Español'}, +//{code: 'fr', name: 'Français'}, +//{code: 'hi', name: 'हिन्दी'}, +//{code: 'id', name: 'Bahasa Indonesia'}, +//{code: 'it', name: 'Italiano'}, +//{code: 'ko', name: '한국어'}, +//{code: 'ms', name: 'Bahasa Melayu'}, +//{code: 'pt', name: 'Português'}, +//{code: 'ru', name: 'Русский'}, +//{code: 'th', name: 'ไทย'}, +//{code: 'vi', name: 'Tiếng Việt'}, +]; + +export const locales = localeItems.map((item) => item.code); +export const defaultLocale = 'en'; diff --git a/i18n.ts b/i18n.ts new file mode 100644 index 0000000..941b5a6 --- /dev/null +++ b/i18n.ts @@ -0,0 +1,14 @@ +// @auto-i18n-check. Please do not delete the line. + +import {notFound} from 'next/navigation'; +import {getRequestConfig} from 'next-intl/server'; +import {locales} from "./i18n-metadata"; + +export default getRequestConfig(async ({locale}) => { + // Validate that the incoming `locale` parameter is valid + if (!locales.includes(locale as any)) notFound(); + + return { + messages: (await import(`./messages/${locale}.json`)).default + }; +}); diff --git a/lib/serverFetch.tsx b/lib/serverFetch.tsx index 020f162..51687a8 100644 --- a/lib/serverFetch.tsx +++ b/lib/serverFetch.tsx @@ -1,7 +1,7 @@ "use server"; -import { NezhaAPI, ServerApi } from "@/app/types/nezha-api"; -import { MakeOptional } from "@/app/types/utils"; +import { NezhaAPI, ServerApi } from "../app/[locale]/types/nezha-api"; +import { MakeOptional } from "../app/[locale]/types/utils"; import { error } from "console"; import { unstable_noStore as noStore } from "next/cache"; import getEnv from "./env-entry"; diff --git a/lib/utils.ts b/lib/utils.ts index ed8ba08..b60052f 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,4 +1,4 @@ -import { NezhaAPISafe } from "@/app/types/nezha-api"; +import { NezhaAPISafe } from "../app/[locale]/types/nezha-api"; import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; diff --git a/messages/en.json b/messages/en.json new file mode 100644 index 0000000..c9497a2 --- /dev/null +++ b/messages/en.json @@ -0,0 +1,26 @@ +{ + "ServerOverviewClient": { + "p_816-881_Totalservers": "Total servers", + "p_1610-1676_Onlineservers": "Online servers", + "p_2532-2599_Offlineservers": "Offline servers", + "p_3463-3530_Totalbandwidth": "Total bandwidth" + }, + "Footer": { + "p_146-598_Findthecodeon": "Find the code on", + "a_303-585_GitHub": "GitHub", + "section_607-869_2020": "© 2020-", + "a_800-850_Hamster1963": "@Hamster1963" + }, + "Header": { + "p_1079-1199_Simpleandbeautifuldashbo": "Simple and beautiful dashboard" + }, + "Overview": { + "p_2277-2331_Overview": "👋 Overview", + "p_2390-2457_wherethetimeis": "where the time is" + }, + "NotFoundPage": { + "h1_490-590_404NotFound": "404 Not Found", + "p_601-665_TARDISERROR": "TARDIS ERROR!", + "Link_676-775_Doctor": "Doctor?" + } +} \ No newline at end of file diff --git a/messages/ja.json b/messages/ja.json new file mode 100644 index 0000000..fe6a58a --- /dev/null +++ b/messages/ja.json @@ -0,0 +1,26 @@ +{ + "ServerOverviewClient": { + "p_816-881_Totalservers": "サーバーの総数", + "p_1610-1676_Onlineservers": "オンラインサーバー", + "p_2532-2599_Offlineservers": "オフラインサーバー", + "p_3463-3530_Totalbandwidth": "合計帯域幅" + }, + "Footer": { + "p_146-598_Findthecodeon": "でコードを見つけます", + "a_303-585_GitHub": "GitHubの", + "section_607-869_2020": "© 2020年〜", + "a_800-850_Hamster1963": "@Hamster1963" + }, + "Header": { + "p_1079-1199_Simpleandbeautifuldashbo": "シンプルで美しいダッシュボード" + }, + "Overview": { + "p_2277-2331_Overview": "👋 概要", + "p_2390-2457_wherethetimeis": "時間はどこにあるのか" + }, + "NotFoundPage": { + "h1_490-590_404NotFound": "404 見つかりませんでした", + "p_601-665_TARDISERROR": "ターディスエラー!", + "Link_676-775_Doctor": "医者。" + } +} \ No newline at end of file diff --git a/messages/zh-t.json b/messages/zh-t.json new file mode 100644 index 0000000..2df3f04 --- /dev/null +++ b/messages/zh-t.json @@ -0,0 +1,26 @@ +{ + "ServerOverviewClient": { + "p_816-881_Totalservers": "伺服器總數", + "p_1610-1676_Onlineservers": "在線伺服器", + "p_2532-2599_Offlineservers": "離線伺服器", + "p_3463-3530_Totalbandwidth": "總頻寬" + }, + "Footer": { + "p_146-598_Findthecodeon": "查找代碼", + "a_303-585_GitHub": "GitHub的", + "section_607-869_2020": "© 2020 年-", + "a_800-850_Hamster1963": "@Hamster1963" + }, + "Header": { + "p_1079-1199_Simpleandbeautifuldashbo": "簡單美觀的儀錶板" + }, + "Overview": { + "p_2277-2331_Overview": "👋 概述", + "p_2390-2457_wherethetimeis": "時間在哪裡" + }, + "NotFoundPage": { + "h1_490-590_404NotFound": "404 未找到", + "p_601-665_TARDISERROR": "TARDIS 錯誤!", + "Link_676-775_Doctor": "醫生?" + } +} \ No newline at end of file diff --git a/messages/zh.json b/messages/zh.json new file mode 100644 index 0000000..18d8f88 --- /dev/null +++ b/messages/zh.json @@ -0,0 +1,26 @@ +{ + "ServerOverviewClient": { + "p_816-881_Totalservers": "服务器总数", + "p_1610-1676_Onlineservers": "在线服务器", + "p_2532-2599_Offlineservers": "离线服务器", + "p_3463-3530_Totalbandwidth": "总带宽" + }, + "Footer": { + "p_146-598_Findthecodeon": "查找代码", + "a_303-585_GitHub": "GitHub的", + "section_607-869_2020": "© 2020 年-", + "a_800-850_Hamster1963": "@Hamster1963" + }, + "Header": { + "p_1079-1199_Simpleandbeautifuldashbo": "简单美观的仪表板" + }, + "Overview": { + "p_2277-2331_Overview": "👋 概述", + "p_2390-2457_wherethetimeis": "时间在哪里" + }, + "NotFoundPage": { + "h1_490-590_404NotFound": "404 未找到", + "p_601-665_TARDISERROR": "TARDIS 错误!", + "Link_676-775_Doctor": "医生?" + } +} \ No newline at end of file diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..f165337 --- /dev/null +++ b/middleware.ts @@ -0,0 +1,21 @@ +// @auto-i18n-check. Please do not delete the line. + +import createMiddleware from 'next-intl/middleware'; +import {locales} from "./i18n-metadata"; + +export default createMiddleware({ + // A list of all locales that are supported + locales: locales, + + // Used when no locale matches + defaultLocale: 'en', + + // 'always': This is the default, The home page will also be redirected to the default language, such as www.abc.com to www.abc.com/en + // 'as-needed': The default page is not redirected. For example, if you open www.abc.com, it is still www.abc.com + localePrefix: 'as-needed', +}); + +export const config = { + // Match only internationalized pathnames + matcher: ['/', '/(en|zh|zh-t|ja)/:path*'] +}; diff --git a/next.config.mjs b/next.config.mjs index 66a8f20..17c3658 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,5 +1,6 @@ +import createNextIntlPlugin from 'next-intl/plugin'; +const withNextIntl = createNextIntlPlugin(); import withPWAInit from "@ducanh2912/next-pwa"; - const withPWA = withPWAInit({ dest: "public", cacheOnFrontEndNav: true, @@ -7,14 +8,13 @@ const withPWA = withPWAInit({ reloadOnOnline: true, disable: false, workboxOptions: { - disableDevLogs: true, - }, + disableDevLogs: true + } }); /** @type {import('next').NextConfig} */ const nextConfig = { - output: "standalone", - reactStrictMode: true, + // output: "standalone", + reactStrictMode: true }; - -export default withPWA(nextConfig); +export default withPWA(withNextIntl(nextConfig)); \ No newline at end of file diff --git a/package.json b/package.json index bee0364..9849a1b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "dev": "next dev -p 3020", "start": "node .next/standalone/server.js", "lint": "next lint", - "build": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/" + "build": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/", + "build-dev": "next build", + "start-dev": "next start" }, "dependencies": { "@ducanh2912/next-pwa": "^10.2.9", @@ -28,6 +30,7 @@ "lucide-react": "^0.414.0", "luxon": "^3.5.0", "next": "^14.2.13", + "next-intl": "^3.20.0", "next-runtime-env": "^3.2.2", "next-themes": "^0.3.0", "react": "^18.3.1",