react-scripts 4 on React 17 no longer builds on a current toolchain. Move to Vite 8 with React 19 and TypeScript 7, and take the same shape as the other converted sites. - react-router-dom v5 -> react-router v8: Switch/Redirect become Routes/Navigate, and withRouter gives way to useLocation and useNavigate; the original /modules/... addresses are kept - swap the unmaintained dependencies: axios -> ky, react-html-parser -> @orrisroot/react-html-parser, react-ga -> react-ga4, react-helmet -> @dr.pogodin/react-helmet, moment -> date-fns, react-spinner-material -> a CSS spinner, and a local HashLink in place of react-router-hash-link - drop react-app-polyfill, the jest setup, xregexp and the unused async-lock, rc-tree, react-overlays and react-image-lightbox - replace ESLint with Biome, yarn with npm, and match the other sites' tsconfigs and sanitize.css base stylesheet - serve static-contents/ next to the repository with sirv in the dev and preview servers, keeping it out of dist/ - convert the page components to function components; each module loads its index once, sharing the request under StrictMode - resolve relative links in page bodies the way a browser does, since react-router 8 resolves them against the route hierarchy - fix the glossary search restricted to a category, whose query matched nothing - set the GA4 measurement ID replacing the shut-down UA property - correct the keywords meta tag copied from dynamicbrain - write down the data layout and the deployment procedure
45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import { Helmet } from '@dr.pogodin/react-helmet';
|
|
import { useEffect } from 'react';
|
|
import { useLocation, useNavigate } from 'react-router';
|
|
import type { MultiLang } from '../../config';
|
|
import Functions from '../../functions';
|
|
|
|
interface Props {
|
|
lang: MultiLang;
|
|
}
|
|
|
|
const TOP_URL = '/';
|
|
|
|
const PageNotFound = (props: Props) => {
|
|
const { lang } = props;
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (location.pathname === TOP_URL) {
|
|
return;
|
|
}
|
|
const timer = setTimeout(() => {
|
|
void navigate(TOP_URL);
|
|
}, 5000);
|
|
return () => clearTimeout(timer);
|
|
}, [location.pathname, navigate]);
|
|
|
|
return (
|
|
<div>
|
|
<Helmet>
|
|
<title>Page Not Found - {Functions.siteTitle(lang)}</title>
|
|
</Helmet>
|
|
<h1>Page Not Found</h1>
|
|
<section>
|
|
<p>The page you were trying to access doesn't exist.</p>
|
|
<p>
|
|
If the page does not automatically reload, please go to the <a href={TOP_URL}>top page</a>
|
|
</p>
|
|
</section>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PageNotFound;
|