diff --git a/apps/website/app/[locale]/[...rest]/page.tsx b/apps/website/app/[locale]/[...rest]/page.tsx new file mode 100644 index 000000000..0ff96242f --- /dev/null +++ b/apps/website/app/[locale]/[...rest]/page.tsx @@ -0,0 +1,5 @@ +import { notFound } from 'next/navigation' + +export default function CatchAll() { + notFound() +} diff --git a/apps/website/app/[locale]/layout.tsx b/apps/website/app/[locale]/layout.tsx new file mode 100644 index 000000000..e1edcf5b8 --- /dev/null +++ b/apps/website/app/[locale]/layout.tsx @@ -0,0 +1,101 @@ +import clsx from 'clsx' +import { Inter, Lexend } from 'next/font/google' +import '@/styles/tailwind.css' +import GoogleAnalytics from '@/components/analitycs/google' + +import { NextIntlClientProvider } from 'next-intl' +import { getMessages } from 'next-intl/server' + +import type { Metadata } from 'next' + +export const metadata: Metadata = { + title: { + default: 'Dokploy - Effortless Deployment Solutions', + template: '%s | Simplify Your DevOps', + }, + alternates: { + canonical: 'https://dokploy.com', + languages: { + en: 'https://dokploy.com', + }, + }, + description: + 'Streamline your deployment process with Dokploy. Effortlessly manage applications and databases on any VPS using Docker and Traefik for improved performance and security.', + applicationName: 'Dokploy', + keywords: [ + 'Dokploy', + 'Docker', + 'Traefik', + 'deployment', + 'VPS', + 'application management', + 'database management', + 'DevOps', + 'cloud infrastructure', + 'UI Self hosted', + ], + referrer: 'origin', + robots: 'index, follow', + openGraph: { + type: 'website', + url: 'https://dokploy.com', + title: 'Dokploy - Effortless Deployment Solutions', + description: + 'Simplify your DevOps with Dokploy. Deploy applications and manage databases efficiently on any VPS.', + siteName: 'Dokploy', + images: [ + { + url: 'http://dokploy.com/og.png', + }, + ], + }, + twitter: { + card: 'summary_large_image', + site: '@Dokploy', + creator: '@Dokploy', + title: 'Dokploy - Simplify Your DevOps', + description: + 'Deploy applications and manage databases with ease using Dokploy. Learn how our platform can elevate your infrastructure management.', + images: 'https://dokploy.com/og.png', + }, +} + +const inter = Inter({ + subsets: ['latin'], + display: 'swap', + variable: '--font-inter', +}) + +const lexend = Lexend({ + subsets: ['latin'], + display: 'swap', + variable: '--font-lexend', +}) + +export default async function RootLayout({ + children, + params, +}: { + children: React.ReactNode + params: { locale: string } +}) { + const { locale } = params + const messages = await getMessages() + return ( + + + + + {children} + + + + ) +} diff --git a/apps/website/app/[locale]/not-found.tsx b/apps/website/app/[locale]/not-found.tsx new file mode 100644 index 000000000..1eee59466 --- /dev/null +++ b/apps/website/app/[locale]/not-found.tsx @@ -0,0 +1,27 @@ +import Link from 'next/link' + +import { SlimLayout } from '../../components/SlimLayout' +// import { Button } from "../components/Button"; +import { Logo } from '../../components/shared/Logo' + +export default function NotFound() { + return ( + +
+ + + +
+

404

+

+ Page not found +

+

+ Sorry, we couldn’t find the page you’re looking for. +

+ {/* */} +
+ ) +} diff --git a/apps/website/app/layout.tsx b/apps/website/app/layout.tsx index fc43d46d3..b7bc5467b 100644 --- a/apps/website/app/layout.tsx +++ b/apps/website/app/layout.tsx @@ -1,85 +1,11 @@ -import clsx from "clsx"; -import { Inter, Lexend } from "next/font/google"; -import "@/styles/tailwind.css"; -import GoogleAnalytics from "@/components/analitycs/google"; -import type { Metadata } from "next"; +import { ReactNode } from 'react' -export const metadata: Metadata = { - title: { - default: "Dokploy - Effortless Deployment Solutions", - template: "%s | Simplify Your DevOps", - }, - alternates: { - canonical: "https://dokploy.com", - languages: { - en: "https://dokploy.com", - }, - }, - description: - "Streamline your deployment process with Dokploy. Effortlessly manage applications and databases on any VPS using Docker and Traefik for improved performance and security.", - applicationName: "Dokploy", - keywords: [ - "Dokploy", - "Docker", - "Traefik", - "deployment", - "VPS", - "application management", - "database management", - "DevOps", - "cloud infrastructure", - "UI Self hosted", - ], - referrer: "origin", - robots: "index, follow", - openGraph: { - type: "website", - url: "https://dokploy.com", - title: "Dokploy - Effortless Deployment Solutions", - description: - "Simplify your DevOps with Dokploy. Deploy applications and manage databases efficiently on any VPS.", - siteName: "Dokploy", - images: [ - { - url: "http://dokploy.com/og.png", - }, - ], - }, - twitter: { - card: "summary_large_image", - site: "@Dokploy", - creator: "@Dokploy", - title: "Dokploy - Simplify Your DevOps", - description: - "Deploy applications and manage databases with ease using Dokploy. Learn how our platform can elevate your infrastructure management.", - images: "https://dokploy.com/og.png", - }, -}; - -const inter = Inter({ - subsets: ["latin"], - display: "swap", - variable: "--font-inter", -}); - -const lexend = Lexend({ - subsets: ["latin"], - display: "swap", - variable: "--font-lexend", -}); - -export default function RootLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( - - - {children} - - ); +type Props = { + children: ReactNode +} + +// Since we have a `not-found.tsx` page on the root, a layout file +// is required, even if it's just passing children through. +export default function RootLayout({ children }: Props) { + return children } diff --git a/apps/website/app/not-found.tsx b/apps/website/app/not-found.tsx index 5225642b4..699156150 100644 --- a/apps/website/app/not-found.tsx +++ b/apps/website/app/not-found.tsx @@ -1,27 +1,48 @@ -import Link from "next/link"; +'use client' -import { SlimLayout } from "../components/SlimLayout"; -// import { Button } from "../components/Button"; -import { Logo } from "../components/shared/Logo"; +import { Logo } from '@/components/shared/Logo' +import { SlimLayout } from '@/components/SlimLayout' +import Error from 'next/error' +import Link from 'next/link' + +// Render the default Next.js 404 page when a route +// is requested that doesn't match the middleware and +// therefore doesn't have a locale associated with it. + +// export default function NotFound() { +// return ( +// +// +// +//
+// +// +// +//
+//

+// 404 +//

+//

+// Page not found +//

+//

+// Sorry, we couldn’t find the page you’re looking for. +//

+// {/* */} +//
+// +// +// ) +// } export default function NotFound() { return ( - -
- - - -
-

404

-

- Page not found -

-

- Sorry, we couldn’t find the page you’re looking for. -

- {/* */} -
- ); + + + + + + ) } diff --git a/apps/website/i18n/routing.ts b/apps/website/i18n/routing.ts index b647e4fed..a60e3d1a5 100644 --- a/apps/website/i18n/routing.ts +++ b/apps/website/i18n/routing.ts @@ -2,15 +2,15 @@ import { defineRouting } from 'next-intl/routing' import { createSharedPathnamesNavigation } from 'next-intl/navigation' export const routing = defineRouting({ - // A list of all locales that are supported - locales: ['en', 'zh-Hans'], + // A list of all locales that are supported + locales: ['en', 'zh-Hans'], - // Used when no locale matches - defaultLocale: 'en', - localePrefix: 'as-needed', + // Used when no locale matches + defaultLocale: 'en', + localePrefix: 'as-needed', }) // Lightweight wrappers around Next.js' navigation APIs // that will consider the routing configuration export const { Link, redirect, usePathname, useRouter } = - createSharedPathnamesNavigation(routing) + createSharedPathnamesNavigation(routing) diff --git a/apps/website/middleware.ts b/apps/website/middleware.ts index 5eb5b6046..ada4177a6 100644 --- a/apps/website/middleware.ts +++ b/apps/website/middleware.ts @@ -1,9 +1,9 @@ -import createMiddleware from 'next-intl/middleware'; -import {routing} from './i18n/routing'; - -export default createMiddleware(routing); - +import createMiddleware from 'next-intl/middleware' +import { routing } from './i18n/routing' + +export default createMiddleware(routing, { localeDetection: false }) + export const config = { - // Match only internationalized pathnames - matcher: ['/', '/(zh-Hans|en)/:path*'] -}; \ No newline at end of file + // Match only internationalized pathnames + matcher: ['/((?!_next|.*\\..*).*)'] +}