diff --git a/app/[locale]/error.tsx b/app/[locale]/error.tsx
index 3022c2f6b9f46..09751a84cd7df 100644
--- a/app/[locale]/error.tsx
+++ b/app/[locale]/error.tsx
@@ -1,10 +1,16 @@
'use client';
import { captureException } from '@sentry/nextjs';
+import { useTranslations } from 'next-intl';
import type { FC } from 'react';
import { useMemo } from 'react';
-const ErrorPage: FC<{ error: Error }> = ({ error }) => {
+import Button from '@/components/Common/Button';
+import CenteredLayout from '@/layouts/New/Centered';
+import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
+
+/** @deprecated remove legacy component when website redesign is done */
+const LegacyErrorPage: FC<{ error: Error }> = ({ error }) => {
useMemo(() => captureException(error), [error]);
return (
@@ -15,4 +21,26 @@ const ErrorPage: FC<{ error: Error }> = ({ error }) => {
);
};
-export default ErrorPage;
+const ErrorPage: FC<{ error: Error }> = ({ error }) => {
+ captureException(error);
+ const t = useTranslations();
+
+ return (
+
+
+
+
+ 500
+
+ {t('layouts.error.internalServerError.title')}
+
+
+ {t('layouts.error.internalServerError.description')}
+
+
+
+
+ );
+};
+
+export default ENABLE_WEBSITE_REDESIGN ? ErrorPage : LegacyErrorPage;
diff --git a/app/[locale]/not-found.tsx b/app/[locale]/not-found.tsx
index 15c704c55d4cc..a49f5100116c4 100644
--- a/app/[locale]/not-found.tsx
+++ b/app/[locale]/not-found.tsx
@@ -3,7 +3,12 @@
import { useTranslations } from 'next-intl';
import type { FC } from 'react';
-const LocalizedNotFound: FC = () => {
+import Button from '@/components/Common/Button';
+import CenteredLayout from '@/layouts/New/Centered';
+import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
+
+/** @deprecated remove legacy component when website redesign is done */
+const LegacyNotFoundPage: FC = () => {
const t = useTranslations();
return (
@@ -14,4 +19,23 @@ const LocalizedNotFound: FC = () => {
);
};
-export default LocalizedNotFound;
+const NotFoundPage: FC = () => {
+ const t = useTranslations();
+
+ return (
+
+
+
+
+ 404
+ {t('layouts.error.notFound.title')}
+
+ {t('layouts.error.notFound.description')}
+
+
+
+
+ );
+};
+
+export default ENABLE_WEBSITE_REDESIGN ? NotFoundPage : LegacyNotFoundPage;
diff --git a/app/global-error.tsx b/app/global-error.tsx
index d8653f56254e5..e67915b8c536a 100644
--- a/app/global-error.tsx
+++ b/app/global-error.tsx
@@ -5,7 +5,13 @@ import ErrorComponent from 'next/error';
import type { FC } from 'react';
import { useMemo } from 'react';
-const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
+import Button from '@/components/Common/Button';
+import BaseLayout from '@/layouts/BaseLayout';
+import CenteredLayout from '@/layouts/New/Centered';
+import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
+
+/** @deprecated remove legacy component when website redesign is done */
+const LegacyGlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
useMemo(() => captureException(error), [error]);
return (
@@ -17,4 +23,31 @@ const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
);
};
-export default GlobalErrorPage;
+const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
+ captureException(error);
+
+ return (
+
+
+
+
+
+
+
+ 500
+ Internal Server Error
+
+ This page has thrown a non-recoverable error.
+
+
+
+
+
+
+
+ );
+};
+
+export default ENABLE_WEBSITE_REDESIGN
+ ? GlobalErrorPage
+ : LegacyGlobalErrorPage;
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index 51814c4f8cf38..9f9167c82ceb5 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -208,6 +208,17 @@
"weekly-updates": "Weekly Updates",
"wg": "Working Groups"
}
+ },
+ "error": {
+ "notFound": {
+ "title": "Page could not be found",
+ "description": "Sorry, we couldn’t find the page you’re after! Try starting again from the homepage."
+ },
+ "internalServerError": {
+ "title": "Internal Server Error",
+ "description": "This page has thrown a non-recoverable error."
+ },
+ "backToHome": "Back to Home"
}
},
"pages": {
diff --git a/layouts/New/Centered.tsx b/layouts/New/Centered.tsx
new file mode 100644
index 0000000000000..f63f312b451aa
--- /dev/null
+++ b/layouts/New/Centered.tsx
@@ -0,0 +1,18 @@
+import type { FC, PropsWithChildren } from 'react';
+
+import WithFooter from '@/components/withFooter';
+import WithNavBar from '@/components/withNavBar';
+
+import styles from './layouts.module.css';
+
+const CenteredLayout: FC = ({ children }) => (
+ <>
+
+
+ {children}
+
+
+ >
+);
+
+export default CenteredLayout;
diff --git a/layouts/New/Home.tsx b/layouts/New/Home.tsx
index a947f049bb1a2..2a313f3e07b69 100644
--- a/layouts/New/Home.tsx
+++ b/layouts/New/Home.tsx
@@ -1,22 +1,15 @@
import type { FC, PropsWithChildren } from 'react';
-import WithFooter from '@/components/withFooter';
-import WithNavBar from '@/components/withNavBar';
+import CenteredLayout from '@/layouts/New/Centered';
import styles from './layouts.module.css';
const HomeLayout: FC = ({ children }) => (
- <>
-
+
+
-
-
-
- >
+ {children}
+
);
export default HomeLayout;
diff --git a/layouts/New/layouts.module.css b/layouts/New/layouts.module.css
index 91fdf4626f6ae..bdfa1be9e529e 100644
--- a/layouts/New/layouts.module.css
+++ b/layouts/New/layouts.module.css
@@ -58,7 +58,7 @@
}
}
-.homeLayout {
+.centeredLayout {
@apply flex
w-full
items-center
@@ -70,77 +70,80 @@
main {
@apply items-center
- justify-center
- gap-8
- md:flex-row
- md:gap-14
- xl:gap-28
- 2xl:gap-32;
-
- section {
- &:nth-of-type(1) {
- @apply flex
- max-w-[500px]
- flex-[1_0]
- flex-col
- gap-8;
-
- > div {
- @apply flex
- max-w-[400px]
- flex-col
- gap-4;
-
- p {
- @apply text-base
- md:text-lg;
- }
+ justify-center;
+ }
+}
- small {
- @apply text-center
- text-sm
- text-neutral-800
- xs:text-xs
- dark:text-neutral-400;
- }
- }
- }
+.homeLayout {
+ @apply gap-8
+ md:flex-row
+ md:gap-14
+ xl:gap-28
+ 2xl:gap-32;
+
+ section {
+ &:nth-of-type(1) {
+ @apply flex
+ max-w-[500px]
+ flex-[1_0]
+ flex-col
+ gap-8;
- &:nth-of-type(2) {
+ > div {
@apply flex
- max-w-md
- flex-[1_1]
+ max-w-[400px]
flex-col
- items-center
- gap-4
- md:max-w-2xl
- lg:max-w-3xl;
-
- > div {
- @apply w-fit;
-
- div[data-state='active'] a {
- @apply border-none
- bg-neutral-900
- px-3
- py-1.5
- text-sm
- font-medium;
-
- &:hover {
- @apply bg-neutral-800;
- }
- }
+ gap-4;
+
+ p {
+ @apply text-base
+ md:text-lg;
}
- > p {
+ small {
@apply text-center
text-sm
text-neutral-800
- dark:text-neutral-200;
+ xs:text-xs
+ dark:text-neutral-400;
}
}
}
+
+ &:nth-of-type(2) {
+ @apply flex
+ max-w-md
+ flex-[1_1]
+ flex-col
+ items-center
+ gap-4
+ md:max-w-2xl
+ lg:max-w-3xl;
+
+ > div {
+ @apply w-fit;
+
+ div[data-state='active'] a {
+ @apply border-none
+ bg-neutral-900
+ px-3
+ py-1.5
+ text-sm
+ font-medium;
+
+ &:hover {
+ @apply bg-neutral-800;
+ }
+ }
+ }
+
+ > p {
+ @apply text-center
+ text-sm
+ text-neutral-800
+ dark:text-neutral-200;
+ }
+ }
}
}
diff --git a/next.dynamic.constants.mjs b/next.dynamic.constants.mjs
index bbe4da5aa1096..f9dbedd6a5126 100644
--- a/next.dynamic.constants.mjs
+++ b/next.dynamic.constants.mjs
@@ -15,8 +15,6 @@ import { defaultLocale } from './next.locales.mjs';
* @type {((route: import('./types').RouteSegment) => boolean)[]} A list of Ignored Routes by Regular Expressions
*/
export const IGNORED_ROUTES = [
- // This is used to ignore the 404 route for the static generation (/404)
- ({ pathname }) => pathname === '404',
// This is used to ignore all blog routes except for the English language
({ locale, pathname }) =>
locale !== defaultLocale.code && /^blog\//.test(pathname),
diff --git a/pages/en/404.md b/pages/en/404.md
deleted file mode 100644
index f3e5a0fc4d15f..0000000000000
--- a/pages/en/404.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-layout: page.hbs
-permalink: false
-title: 404
----
-
-## 404: Page could not be found
-
-### ENOENT: no such file or directory
diff --git a/styles/new/markdown.css b/styles/new/markdown.css
index c7e951a6a07db..b3c38b4af92b3 100644
--- a/styles/new/markdown.css
+++ b/styles/new/markdown.css
@@ -73,6 +73,10 @@ main {
dark:text-green-300;
}
+ &[role='button'] {
+ @apply xs:no-underline;
+ }
+
&:has(code) {
@apply xs:decoration-neutral-800
dark:xs:decoration-neutral-200;
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 6badfc908c5d0..54767ff20f8cb 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -8,6 +8,7 @@ export default {
'./layouts/**/*.tsx',
'./.storybook/preview.tsx',
'./.storybook/main.ts',
+ './app/**/*.tsx',
],
theme: {
colors: {