diff --git a/frontend/src/functions/APIClient.ts b/frontend/src/functions/APIClient.ts
index c01ba8b8..2c4a4110 100644
--- a/frontend/src/functions/APIClient.ts
+++ b/frontend/src/functions/APIClient.ts
@@ -55,6 +55,13 @@ const APIClient = async (
throw new Error('Forbidden: Access denied.');
}
+ if (response.status === 404) {
+ throw {
+ status: 404,
+ message: 'Resource not found',
+ } as ApiError;
+ }
+
let data;
// expected empty response
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 4fc91d7a..e7dce8bc 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -27,6 +27,7 @@ import ChannelAbout from './pages/ChannelAbout';
import Download from './pages/Download';
import loadUserAccount from './api/loader/loadUserAccount';
import loadAppsettingsConfig from './api/loader/loadAppsettingsConfig';
+import NotFound from './pages/404Page';
const router = createBrowserRouter(
[
@@ -145,6 +146,10 @@ const router = createBrowserRouter(
element: ,
errorElement: ,
},
+ {
+ path: '*',
+ element: ,
+ },
],
{ basename: import.meta.env.BASE_URL },
);
diff --git a/frontend/src/pages/404Page.tsx b/frontend/src/pages/404Page.tsx
new file mode 100644
index 00000000..1b75f7ab
--- /dev/null
+++ b/frontend/src/pages/404Page.tsx
@@ -0,0 +1,22 @@
+import { Link } from 'react-router-dom';
+import useColours from '../configuration/colours/useColours';
+import Routes from '../configuration/routes/RouteList';
+
+const NotFound = ({ failType = 'page' }) => {
+ useColours();
+ return (
+ <>
+
+
Oops!
+
+ 404
+ : That {failType} does not exist.
+
+
Go Home
+
+ >
+ );
+};
+
+export default NotFound;
diff --git a/frontend/src/pages/ChannelBase.tsx b/frontend/src/pages/ChannelBase.tsx
index 2da7c552..cb63e0e7 100644
--- a/frontend/src/pages/ChannelBase.tsx
+++ b/frontend/src/pages/ChannelBase.tsx
@@ -8,6 +8,8 @@ import ChannelBanner from '../components/ChannelBanner';
import loadChannelNav, { ChannelNavResponseType } from '../api/loader/loadChannelNav';
import loadChannelById from '../api/loader/loadChannelById';
import useIsAdmin from '../functions/useIsAdmin';
+import { ApiError } from '../functions/APIClient';
+import NotFound from './404Page';
type ChannelParams = {
channelId: string;
@@ -18,6 +20,7 @@ export type ChannelResponseType = ChannelType;
const ChannelBase = () => {
const { channelId } = useParams() as ChannelParams;
const { currentPage, setCurrentPage } = useOutletContext() as OutletContextType;
+ const [error, setError] = useState