diff --git a/frontend/app/[locale]/page.tsx b/frontend/app/[locale]/page.tsx
index 99624b80..42813f8b 100644
--- a/frontend/app/[locale]/page.tsx
+++ b/frontend/app/[locale]/page.tsx
@@ -1,9 +1,10 @@
import { getTranslations } from 'next-intl/server';
+import { Suspense } from 'react';
import FeaturesHeroSection from '@/components/home/FeaturesHeroSection';
import HomePageScroll from '@/components/home/HomePageScroll';
import WelcomeHeroSection from '@/components/home/WelcomeHeroSection';
-import Footer from '@/components/shared/Footer';
+import LazyFooter from '@/components/shared/LazyFooter';
export async function generateMetadata({
params,
@@ -75,9 +76,11 @@ export default function Home() {
data-home-step
className="min-h-[calc(100dvh-4rem)] shrink-0 snap-start [scroll-snap-stop:always]"
>
-
+
+
+
-
+
);
}
diff --git a/frontend/components/home/FeaturesHeroSection.tsx b/frontend/components/home/FeaturesHeroSection.tsx
index 2d5d2209..ddad24f8 100644
--- a/frontend/components/home/FeaturesHeroSection.tsx
+++ b/frontend/components/home/FeaturesHeroSection.tsx
@@ -1,8 +1,5 @@
-'use client';
-
import { BrainCircuit, MessageCircleQuestion, TrendingUp } from 'lucide-react';
-import { useTranslations } from 'next-intl';
-import * as React from 'react';
+import { getTranslations } from 'next-intl/server';
import { DynamicGridBackground } from '@/components/shared/DynamicGridBackground';
import { Link } from '@/i18n/routing';
@@ -10,8 +7,8 @@ import { Link } from '@/i18n/routing';
import { FlipCardQA } from './FlipCardQA';
import { FloatingCode } from './FloatingCode';
-export default function FeaturesHeroSection() {
- const t = useTranslations('homepage');
+export default async function FeaturesHeroSection() {
+ const t = await getTranslations('homepage');
return (
(
const [currentText, setCurrentText] = useState(t('cta'));
const [variantIndex, setVariantIndex] = useState(0);
- const [isFirstRender, setIsFirstRender] = useState(true);
const textVariants = [
t('cta'),
@@ -36,10 +35,6 @@ export const InteractiveCTAButton = React.forwardRef(
t('ctaVariants.8'),
];
- useEffect(() => {
- setIsFirstRender(false);
- }, []);
-
const x = useMotionValue(0);
const y = useMotionValue(0);
diff --git a/frontend/components/home/WelcomeHeroBackground.tsx b/frontend/components/home/WelcomeHeroBackground.tsx
index db6a4d24..f1f98d5d 100644
--- a/frontend/components/home/WelcomeHeroBackground.tsx
+++ b/frontend/components/home/WelcomeHeroBackground.tsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
export function WelcomeHeroBackground() {
return (
<>
diff --git a/frontend/components/shared/LazyFooter.tsx b/frontend/components/shared/LazyFooter.tsx
new file mode 100644
index 00000000..4387040d
--- /dev/null
+++ b/frontend/components/shared/LazyFooter.tsx
@@ -0,0 +1,35 @@
+'use client';
+
+import dynamic from 'next/dynamic';
+import { useEffect, useRef, useState } from 'react';
+
+const Footer = dynamic(() => import('./Footer'));
+
+export default function LazyFooter(props: { forceVisible?: boolean }) {
+ const sentinelRef = useRef(null);
+ const [nearViewport, setNearViewport] = useState(false);
+
+ useEffect(() => {
+ const node = sentinelRef.current;
+ if (!node) return;
+
+ const observer = new IntersectionObserver(
+ ([entry]) => {
+ if (entry.isIntersecting) {
+ setNearViewport(true);
+ observer.disconnect();
+ }
+ },
+ { rootMargin: '300px' }
+ );
+
+ observer.observe(node);
+ return () => observer.disconnect();
+ }, []);
+
+ if (!nearViewport) {
+ return ;
+ }
+
+ return ;
+}