Skip to content

Latest commit

 

History

History
214 lines (130 loc) · 7.48 KB

File metadata and controls

214 lines (130 loc) · 7.48 KB

Common Pitfalls & Solutions

Documented issues and their solutions to prevent recurring mistakes.

Layout Flash on Page Load

Problem: When users refresh the page with isLayoutLarge preference saved, the layout would flash from constrained (max-w-7xl) to full-width before React hydrates.

Root Cause: React state initialization happens after prerendered HTML renders, causing a visual mismatch.

Solution:

  1. Inline script in prerendered HTML reads localStorage before React loads
  2. Script adds layout-large class to html element immediately
  3. CSS rule overrides max-w-7xl with max-width: none !important when class is present
  4. React state syncs with the already-correct DOM

Files Involved:

  • vite.config.ts - Inline script injection (lines 152-164)
  • src/index.css - CSS override (lines 58-62)
  • src/contexts/AppContextProvider.tsx - State initialization and sync

Key Learning: For persistent UI state, always apply changes at the DOM/CSS level before React hydrates.


Type Mismatches Between JSON Resume and ProfileData

Problem: JSON Resume Reference type has optional fields, but ProfileData Reference requires all fields, causing TypeScript errors.

Root Cause: Different interface definitions for the same data concept.

Solution:

  • Define Reference in src/types/profile.ts with required fields
  • Define Reference in src/types/json-resume.ts with optional fields
  • Use type assertion when mapping: as Reference with fallback values (|| "")

Files Involved:

  • src/types/profile.ts - Required fields definition
  • src/types/json-resume.ts - Optional fields definition
  • src/hooks/useJSONResumeAdapter.ts - Type assertion during mapping

Key Learning: When adapting between schemas, use type assertions with fallback values rather than trying to force type compatibility.


Missing Translations Across Languages

Problem: Adding a translation key to en.json but forgetting to add it to it.json, fr.json, es.json, ar.json causes missing translation errors in other languages.

Root Cause: Manual process with 5 separate files makes it easy to miss languages.

Solution:

  1. Always update all 5 language files simultaneously when adding new keys
  2. Use consistent key structure across all files
  3. Test all languages before committing

Files Involved:

  • src/messages/en.json - English (base)
  • src/messages/it.json - Italian
  • src/messages/fr.json - French
  • src/messages/es.json - Spanish
  • src/messages/ar.json - Arabic

Key Learning: Treat translation updates as atomic operations across all 5 languages.


Prerendering Routing Issues

Problem: Non-English prerendered pages (e.g., /fr/recommendations/) would fall back to English default instead of loading the correct language version.

Root Cause: Overly broad catch-all redirect rule /${LOCALE_DEFAULT}/* /:splat 302 was intercepting all requests, including other language routes.

Solution:

  1. Remove the broad catch-all redirect
  2. Add specific redirects only for default language routes without trailing slash
  3. Language-specific redirects are processed first, preventing interception

Files Involved:

  • vite.config.ts - Redirect configuration (lines 178-195)

Redirect Rules Order:

1. Language-specific redirects (e.g., /fr  /fr/)
2. Default language specific routes (e.g., /experience  /experience/)

Key Learning: Redirect rules are processed in order; more specific rules must come before catch-all rules.


Sidebar Scrolling Conflicts

Problem: Pages with many sidebar blocks (3+) would have excessive scrolling, making the layout feel broken.

Root Cause: Sticky positioning with max-height applied to all sidebars regardless of content volume.

Solution:

  1. Add disableSidebarScroll prop to PageLayout
  2. Disable scrolling for pages with 3+ sidebar blocks (MainPage, ExperiencePage)
  3. Keep scrolling enabled for pages with 2 blocks (SkillsPage, RecommendationsPage)

Files Involved:

  • src/components/layout/PageLayout.tsx - Conditional scroll classes
  • src/pages/MainPage.tsx - disableSidebarScroll prop
  • src/pages/ExperiencePage.tsx - disableSidebarScroll prop

Key Learning: Sticky scrolling works best with limited content; disable for content-heavy sidebars.


Conditional Tailwind Classes Not Overriding

Problem: When toggling layout size, the max-w-7xl class wouldn't be removed even though React state changed.

Root Cause: Tailwind classes are static in the HTML; conditional className logic doesn't override them at runtime.

Solution:

  1. Always apply max-w-7xl in the HTML
  2. Use CSS to override it: html.layout-large main { max-width: none !important; }
  3. Let CSS handle the override, not React conditional logic

Files Involved:

  • src/components/layout/Navbar.tsx - Always include max-w-7xl
  • src/components/layout/PageLayout.tsx - Always include max-w-7xl
  • src/index.css - CSS override rule

Key Learning: For layout constraints, use CSS overrides rather than conditional Tailwind classes.


Highlights Synchronization Across Locales

Problem: English resume was missing highlights that existed in Italian version, causing inconsistent project descriptions.

Root Cause: Manual data entry across multiple locale files without cross-checking.

Solution:

  1. Use Italian version as reference (most complete)
  2. Compare each project's highlights between locales
  3. Add missing highlights to English version
  4. Verify all locales have consistent project information

Files Involved:

  • src/data/resume-en.json
  • src/data/resume-it.json
  • src/data/resume-fr.json
  • src/data/resume-es.json
  • src/data/resume-ar.json

Key Learning: When maintaining multi-locale data, establish one locale as the source of truth for structure, then translate content.


Skills Accordion Default State

Problem: Skills section on homepage had accordion collapsed by default, requiring users to click to see content.

Root Cause: Accordion type was "single" with collapsible, no default open values.

Solution:

  1. Change accordion type to "multiple" to allow multiple open items
  2. Set defaultOpenValues array with all category IDs
  3. Pass value={defaultOpenValues} to Accordion component

Files Involved:

  • src/components/profile/SkillsSection.tsx - Lines 32-50

Key Learning: For preview sections, expand all items by default to showcase content immediately.


9. Manual Code Chunking Incompatible with Prerendering

Problem: Attempting to optimize bundle size by splitting vendor libraries into separate chunks causes build to fail with TypeError: Cannot read properties of undefined (reading 'createContext').

Root Cause: The vite-prerender-plugin renders pages during build using Node.js SSR. When manualChunks splits React/ReactDOM into separate bundles, those modules aren't available during the SSR phase, causing createContext and other React APIs to be undefined.

Solution:

Keep manualChunks: undefined in vite.config.ts:

build: {
  rollupOptions: {
    output: {
      manualChunks: undefined, // Required for prerendering
    },
  },
}

Files Involved:

  • vite.config.ts - Build configuration

Key Learning: Prerendered apps (SSR) require all code to be synchronously available during build. Code splitting with dynamic imports (React.lazy) and vendor chunking both break prerendering. The 821KB bundle size is expected and correct for this architecture.