Troubleshooting
Common issues and solutions for landing components.
Scroll Animations Not Triggering
Problem: Components with scroll animations don't fade in when scrolling.
Solutions:
- Verify scroll animation CSS is added to
globals.css:
.scroll-fade-in {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.scroll-fade-in.visible {
opacity: 1;
transform: translateY(0);
}
- Check that
useScrollAnimationhook is imported:
import { useScrollAnimation } from '@/hooks';
- Ensure the hook is exported from
src/hooks/index.ts:
export { useScrollAnimation } from './useScrollAnimation';
Dark Mode Styles Not Applying
Problem: Components look broken in dark mode.
Solutions:
- Verify
ThemeProviderwraps your app insrc/app/layout.tsx:
import { ThemeProvider } from '@/contexts/ThemeContext';
export default function RootLayout({ children }) {
return (
<html suppressHydrationWarning>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}
- Check that dark mode classes are in your CSS:
.dark {
color-scheme: dark;
}
- Verify Tailwind config includes dark mode:
// tailwind.config.js
module.exports = {
darkMode: 'class',
// ...
};
Pricing Toggle Not Switching Prices
Problem: Clicking annual/monthly toggle doesn't update prices.
Solutions:
- Check that
isAnnualstate is properly initialized:
const [isAnnual, setIsAnnual] = useState(true);
- Verify price calculation uses the correct value:
${isAnnual ? plan.price.annual : plan.price.monthly}
- Ensure toggle button updates state:
onClick={() => setIsAnnual(!isAnnual)}
Translation Keys Showing Instead of Text
Problem: Seeing landing.hero.title instead of actual text.
Solutions:
- Verify translation keys exist in
src/locales/en.json:
{
"landing": {
"hero": {
"title": "Your actual title here"
}
}
}
- Check namespace matches in component:
const t = useTranslations('landing.hero');
{t('title')} // Will look for landing.hero.title
- Ensure
next-intlis configured innext.config.js.
FAQ Accordion Not Opening/Closing
Problem: Clicking FAQ items doesn't expand them.
Solutions:
- Verify
@radix-ui/react-accordionis installed:
npm install @radix-ui/react-accordion
- Check accordion animations are in
globals.css:
@keyframes accordion-down {
from { height: 0; }
to { height: var(--radix-accordion-content-height); }
}
- Ensure Accordion is properly configured:
<Accordion type="single" collapsible>
{/* items */}
</Accordion>
Mobile Menu Not Appearing
Problem: Hamburger menu doesn't open on mobile.
Solutions:
- Check that mobile menu state is managed:
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
- Verify menu toggle updates state:
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
- Ensure mobile menu has conditional rendering:
{mobileMenuOpen && (
<div className="md:hidden">
{/* menu content */}
</div>
)}
Images Not Loading
Problem: Hero or testimonial images show broken image icons.
Solutions:
- Place images in
public/directory:
public/
├── logo.png
├── hero-image.png
└── images/
└── testimonials/
└── avatar1.jpg
- Use correct paths in components:
<Image src="/logo.png" alt="Logo" width={32} height={32} />
- For external images, add domains to
next.config.js:
images: {
domains: ['example.com'],
}
Lazy Loading Not Working
Problem: All components load at once, slow initial page load.
Solutions:
- Use
React.lazy()for below-the-fold components:
const Features = lazy(() => import('@/components/landing/Features'));
- Wrap in
Suspensewith fallback:
<Suspense fallback={<div className="min-h-screen" />}>
<Features />
</Suspense>
- Only lazy load components below the fold (keep Hero, Navbar eager).
TypeScript Errors
Problem: Type errors when using components.
Solutions:
- Ensure IconProps type is imported:
import type { IconProps } from '@/components/icons';
import type { ComponentType } from 'react';
interface Feature {
icon: ComponentType<IconProps>;
// ...
}
Check that all required props are provided.
Run type checking:
npm run typecheck
Hydration Errors
Problem: "Text content does not match server-rendered HTML"
Solutions:
- Add
'use client'to components using hooks/state:
'use client';
export default function MyComponent() {
const [state, setState] = useState(false);
// ...
}
- Check for browser-only APIs (localStorage, window):
useEffect(() => {
// Access localStorage only in useEffect
const value = localStorage.getItem('key');
}, []);
- Add
suppressHydrationWarningfor dynamic content:
<html suppressHydrationWarning>
Component Not Rendering
Problem: Component is imported but not showing.
Solutions:
- Check component is exported correctly:
// Named export
export function MyComponent() {}
// Default export
export default function MyComponent() {}
- Verify import matches export:
// For named export
import { MyComponent } from './MyComponent';
// For default export
import MyComponent from './MyComponent';
- Check for errors in browser console.
Still Having Issues?
- Check browser console for errors
- Verify all dependencies are installed:
npm install - Clear Next.js cache:
rm -rf .next - Restart dev server:
npm run dev