Troubleshooting

Common issues and solutions for landing components.

Scroll Animations Not Triggering

Problem: Components with scroll animations don't fade in when scrolling.

Solutions:

  1. 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);
}
  1. Check that useScrollAnimation hook is imported:
import { useScrollAnimation } from '@/hooks';
  1. 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:

  1. Verify ThemeProvider wraps your app in src/app/layout.tsx:
import { ThemeProvider } from '@/contexts/ThemeContext';

export default function RootLayout({ children }) {
  return (
    <html suppressHydrationWarning>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  );
}
  1. Check that dark mode classes are in your CSS:
.dark {
  color-scheme: dark;
}
  1. 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:

  1. Check that isAnnual state is properly initialized:
const [isAnnual, setIsAnnual] = useState(true);
  1. Verify price calculation uses the correct value:
${isAnnual ? plan.price.annual : plan.price.monthly}
  1. Ensure toggle button updates state:
onClick={() => setIsAnnual(!isAnnual)}

Translation Keys Showing Instead of Text

Problem: Seeing landing.hero.title instead of actual text.

Solutions:

  1. Verify translation keys exist in src/locales/en.json:
{
  "landing": {
    "hero": {
      "title": "Your actual title here"
    }
  }
}
  1. Check namespace matches in component:
const t = useTranslations('landing.hero');
{t('title')} // Will look for landing.hero.title
  1. Ensure next-intl is configured in next.config.js.

FAQ Accordion Not Opening/Closing

Problem: Clicking FAQ items doesn't expand them.

Solutions:

  1. Verify @radix-ui/react-accordion is installed:
npm install @radix-ui/react-accordion
  1. Check accordion animations are in globals.css:
@keyframes accordion-down {
  from { height: 0; }
  to { height: var(--radix-accordion-content-height); }
}
  1. Ensure Accordion is properly configured:
<Accordion type="single" collapsible>
  {/* items */}
</Accordion>

Mobile Menu Not Appearing

Problem: Hamburger menu doesn't open on mobile.

Solutions:

  1. Check that mobile menu state is managed:
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  1. Verify menu toggle updates state:
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
  1. 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:

  1. Place images in public/ directory:
public/
├── logo.png
├── hero-image.png
└── images/
    └── testimonials/
        └── avatar1.jpg
  1. Use correct paths in components:
<Image src="/logo.png" alt="Logo" width={32} height={32} />
  1. 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:

  1. Use React.lazy() for below-the-fold components:
const Features = lazy(() => import('@/components/landing/Features'));
  1. Wrap in Suspense with fallback:
<Suspense fallback={<div className="min-h-screen" />}>
  <Features />
</Suspense>
  1. Only lazy load components below the fold (keep Hero, Navbar eager).

TypeScript Errors

Problem: Type errors when using components.

Solutions:

  1. Ensure IconProps type is imported:
import type { IconProps } from '@/components/icons';
import type { ComponentType } from 'react';

interface Feature {
  icon: ComponentType<IconProps>;
  // ...
}
  1. Check that all required props are provided.

  2. Run type checking:

npm run typecheck

Hydration Errors

Problem: "Text content does not match server-rendered HTML"

Solutions:

  1. Add 'use client' to components using hooks/state:
'use client';

export default function MyComponent() {
  const [state, setState] = useState(false);
  // ...
}
  1. Check for browser-only APIs (localStorage, window):
useEffect(() => {
  // Access localStorage only in useEffect
  const value = localStorage.getItem('key');
}, []);
  1. Add suppressHydrationWarning for dynamic content:
<html suppressHydrationWarning>

Component Not Rendering

Problem: Component is imported but not showing.

Solutions:

  1. Check component is exported correctly:
// Named export
export function MyComponent() {}

// Default export
export default function MyComponent() {}
  1. Verify import matches export:
// For named export
import { MyComponent } from './MyComponent';

// For default export
import MyComponent from './MyComponent';
  1. Check for errors in browser console.

Still Having Issues?

  1. Check browser console for errors
  2. Verify all dependencies are installed: npm install
  3. Clear Next.js cache: rm -rf .next
  4. Restart dev server: npm run dev