Migrate from Vite to Next.js 15 with SSR
- Replace Vite + React Router with Next.js 15 App Router - Implement i18n with next-intl (URL-based: /de, /en, /sr) - Add SSR/SSG for all pages (48 static pages generated) - Setup Supabase SSR client for auth - Migrate all pages: Home, About, Portfolio, Blog, Contact, Login, Dashboard, Imprint, Privacy, Terms - Add Docker support with standalone output - Replace i18next with next-intl JSON translations - Use next/image for optimized images Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
// routes.tsx
|
||||
import React, { Suspense } from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import RouteErrorBoundary from './components/RouteErrorBoundary';
|
||||
import PageContainer from './components/PageContainer';
|
||||
|
||||
// Lazy load components
|
||||
const HomePage = React.lazy(() => import('./pages/home'));
|
||||
const AboutPage = React.lazy(() => import('./pages/about'));
|
||||
const PortfolioPage = React.lazy(() => import('./pages/portfolio'));
|
||||
const ProjectPage = React.lazy(() => import('./pages/portfolio/ProjectPage'));
|
||||
const BlogPage = React.lazy(() => import('./pages/blog'));
|
||||
const BlogPostPage = React.lazy(() => import('./pages/blog/components/BlogPost'));
|
||||
const ContactPage = React.lazy(() => import('./pages/contact'));
|
||||
const LoginPage = React.lazy(() => import('./pages/LoginPage'));
|
||||
const DashboardPage = React.lazy(() => import('./pages/DashboardPage'));
|
||||
const PrivacyPolicyPage = React.lazy(() => import('./pages/PrivacyPolicyPage'));
|
||||
const TermsPage = React.lazy(() => import('./pages/TermsPage'));
|
||||
const ImprintPage = React.lazy(() => import('./pages/ImprintPage'));
|
||||
|
||||
const AppRoutes = () => {
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<HomePage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/about"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<AboutPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
{/* Rest of the routes follow the same pattern */}
|
||||
<Route
|
||||
path="/portfolio"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<PortfolioPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/portfolio/:slug"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<ProjectPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/blog"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<BlogPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/blog/:slug"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<BlogPostPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/contact"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<ContactPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/login"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<LoginPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/dashboard"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<DashboardPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/privacy"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<PrivacyPolicyPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/terms"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<TermsPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
<Route
|
||||
path="/imprint"
|
||||
element={
|
||||
<PageContainer>
|
||||
<Suspense fallback={null}>
|
||||
<ImprintPage />
|
||||
</Suspense>
|
||||
</PageContainer>
|
||||
}
|
||||
errorElement={<RouteErrorBoundary />}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppRoutes;
|
||||
Reference in New Issue
Block a user