# Profen Engineering — React SPA A React single-page application that recreates [profeneng.com](https://profeneng.com) (WordPress + Elementor + Rakar theme) as a fast, portable frontend. ## Architecture ``` src/ ├── main.jsx Entry — imports CSS (variables → kit → theme → layout → pages → services → dynamic), mounts React ├── App.jsx Router (BrowserRouter, Suspense, ErrorBoundary, lazy-loaded pages, 404 route) ├── config.js Central config: WhatsApp phone, brand colors, PAGE_IDS, SPA_ROUTES, POST_ID_TO_SLUG, SERVICE_SIDEBAR_ITEMS, MENU_ITEM_IDS ├── components/ │ ├── Layout.jsx Shared layout (Header + Outlet + Footer + WhatsAppButton + preloader + page‑id body class) │ ├── SafeHtml.jsx Parses HTML strings into React elements via html-react-parser (replaces dangerouslySetInnerHTML) │ ├── ErrorBoundary.jsx Catches render crashes, shows Try Again button │ ├── Loading.jsx Spinner for Suspense fallback │ ├── WhatsAppButton.jsx Floating WhatsApp widget │ └── sections/ │ ├── Header.jsx Proper React component with nav, active state from useLocation() │ ├── Footer.jsx Proper React component with contact data, social links, service links │ ├── Breadcrumb.jsx Reusable breadcrumb trail │ ├── SectionTitle.jsx Section heading with subtitle & icon │ ├── Button.jsx Reusable styled button │ ├── PhoneWidget.jsx Phone call widget │ ├── FeatureCards.jsx Feature card grid │ ├── ContactForm.jsx "Get a Quote" form │ ├── ContactInfo.jsx Address/phone/email display │ ├── GoogleMap.jsx Embedded Google Maps iframe │ ├── Divider.jsx Section divider │ ├── ProjectFilterGrid.jsx Filterable project grid │ ├── ServiceContentBlocks.jsx Renders structured service content (paragraphs, headings, lists) │ ├── ServiceGridSection.jsx Service listing grid │ ├── ServiceBreadcrumb.jsx Service detail breadcrumb │ ├── ServiceImage.jsx Service detail featured image │ ├── ServiceBody.jsx Service detail body (content blocks) │ └── ServiceSidebar.jsx Service detail sidebar nav ├── pages/ │ ├── Home.jsx Page: / — uses SafeHtml (parses home-content.html) │ ├── About.jsx Page: /about — uses SafeHtml (parses about-content.html) │ ├── Services.jsx Page: /service — uses SafeHtml (parses service-content.html) │ ├── ServiceDetail.jsx Page: /service/:slug — fully componentized, reads services.json │ ├── Project.jsx Page: /project — fully componentized, uses ProjectFilterGrid │ └── Contact.jsx Page: /contact — fully componentized, uses section components ├── hooks/ │ ├── useLayoutInit.js Re-initializes Elementor theme JS on route change (requestAnimationFrame polling) │ ├── useNavFix.js Intercepts links inside a ref for proper SPA routing │ └── useThemeAssets.js Injects and tags (OG, canonical, favicon) on mount ├── data/ Content sources │ ├── home-content.html Home page HTML content (parsed by SafeHtml) │ ├── about-content.html About page HTML content (parsed by SafeHtml) │ ├── service-content.html Services listing HTML content (parsed by SafeHtml) │ └── services.json Structured data for 9 service detail pages (contentBlocks, images, metadata) └── css/ Build-time CSS imports (all bundled into one index-*.css) ├── variables.css :root CSS custom properties for brand colors (imported first) ├── kit.css Elementor kit CSS (global styles) ├── theme.css Rakar theme overrides ├── layout.css Header (elementor-945) + Footer (elementor-1098 / elementor-128) CSS ├── pages.css Combined CSS for all 5 main pages ├── services.css Combined CSS for all 9 service detail pages ├── dynamic.css Dynamic overrides using var(--brand-*) with fallbacks └── pages/ Individual page CSS files (development reference — edit these, then regenerate combined) ├── page-23.css Home page ├── page-31.css About page ├── page-32.css Services listing ├── page-36.css Project page ├── page-48.css Contact page └── service-*.css Individual service detail pages (9 files) ``` ## Strategy: Hybrid React + WordPress Content The app uses a **hybrid approach**: 1. **Componentized pages** (Contact, Project, ServiceDetail) use proper React section components with structured data — no HTML strings. 2. **Transitional pages** (Home, About, Services) render raw Elementor HTML from `src/data/*.html` files, parsed at runtime by `html-react-parser` via `SafeHtml.jsx` — **no `dangerouslySetInnerHTML`** anywhere in the app. 3. **Styling** comes from two places: - Build-time CSS imports (`src/css/*.css`) — Elementor's page-specific CSS bundled by Vite - Runtime assets from `public/wp-content/` — theme stylesheets, fonts, images 4. **Behavior** comes from the original Rakar theme JS loaded via `