92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { lazy, Suspense, useEffect } from 'react';
|
|
import { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
|
import '../scss/App.scss';
|
|
import Navbar from '../components/layout/Navigation';
|
|
import Footer from '../components/layout/Footer';
|
|
import BackToTopButton from '../components/BackToTopButton';
|
|
import { useLanguage } from '../contexts/LanguageContext';
|
|
|
|
const HomePage = lazy(() => import('../pages/HomePage'));
|
|
const LandingPage = lazy(() => import('../pages/LandingPage'));
|
|
const AuditPage = lazy(() => import('../pages/AuditPage'));
|
|
const QuickcheckPage = lazy(() => import('../pages/QuickcheckPage'));
|
|
const ImprintPage = lazy(() => import('../pages/ImprintPage'));
|
|
const PrivacyPolicy = lazy(() => import('../pages/PrivacyPolicy'));
|
|
|
|
function LegacyLanguageRedirect() {
|
|
const { setLanguage } = useLanguage();
|
|
const location = useLocation();
|
|
|
|
const legacyLanguage = location.pathname.startsWith('/en') ? 'en' : 'de';
|
|
const targetPathname = location.pathname.replace(/^\/(de|en)(?=\/|$)/, '') || '/';
|
|
|
|
useEffect(() => {
|
|
setLanguage(legacyLanguage);
|
|
}, [legacyLanguage, setLanguage]);
|
|
|
|
return (
|
|
<Navigate
|
|
to={{ pathname: targetPathname, search: location.search, hash: location.hash }}
|
|
replace
|
|
/>
|
|
);
|
|
}
|
|
|
|
function AppShell() {
|
|
const location = useLocation();
|
|
const { texts } = useLanguage();
|
|
|
|
useEffect(() => {
|
|
const hash = location.hash.substring(1);
|
|
if (hash) {
|
|
setTimeout(() => {
|
|
const element = document.getElementById(hash);
|
|
if (element) {
|
|
element.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
}, 100);
|
|
}
|
|
}, [location.hash]);
|
|
|
|
return (
|
|
<div className="app">
|
|
<a href="#main-content" className="skip-link">
|
|
{texts.accessibility.skipLinks.skipToHero}
|
|
</a>
|
|
<Navbar />
|
|
<main id="main-content" className="app__main">
|
|
<Suspense fallback={<p role="status" className="sr-only">Loading…</p>}>
|
|
<Routes>
|
|
{/* Legacy locale-prefixed URLs → clean URLs */}
|
|
<Route path="/de/*" element={<LegacyLanguageRedirect />} />
|
|
<Route path="/en/*" element={<LegacyLanguageRedirect />} />
|
|
|
|
{/* Canonical, language-neutral routes */}
|
|
<Route path="/" element={<LandingPage />} />
|
|
<Route path="/technical" element={<HomePage />} />
|
|
<Route path="/audit" element={<AuditPage />} />
|
|
<Route path="/schnellcheck" element={<QuickcheckPage />} />
|
|
|
|
{/* Shared pages (noindex, language-independent) */}
|
|
<Route path="/imprint" element={<ImprintPage />} />
|
|
<Route path="/privacy-policy" element={<PrivacyPolicy />} />
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Routes>
|
|
</Suspense>
|
|
</main>
|
|
<Footer />
|
|
<BackToTopButton />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function AppRouter() {
|
|
return (
|
|
<Router>
|
|
<AppShell />
|
|
</Router>
|
|
);
|
|
}
|
|
|
|
export default AppRouter;
|