Frontend Runtime
Role
The frontend runtime mounts the React app, reads the bootstrap payload, resolves templates, prepares assets, coordinates navigation, and re-syncs document head state after client-side route changes.
Main Files
src/themes/reactwp/js/App.jsxsrc/themes/reactwp/js/inc/Runtime.jssrc/themes/reactwp/js/inc/Loader.jssrc/themes/reactwp/js/inc/PageTransition.jssrc/themes/reactwp/js/inc/RouteService.jssrc/themes/reactwp/js/inc/TemplateRegistry.jssrc/themes/reactwp/js/inc/Scroller.jssrc/themes/reactwp/js/inc/motion.jssrc/themes/reactwp/js/inc/useRouteTransition.jssrc/themes/reactwp/js/inc/AppShell.jsx
Runtime Payload
Runtime.js reads the JSON payload injected by PHP and exposes it through runtime.
Common values:
runtime.bootstrapruntime.siteruntime.systemruntime.assetsruntime.navigationruntime.route
For the full payload contract, see Bootstrap and Route Payloads.
Example
import { runtime } from './inc/Runtime';
console.log(runtime.site.name);
console.log(runtime.system.routeEndpoint);
console.log(runtime.route.template);
App Entry
App.jsx is kept intentionally small.
It:
- initializes the template registry
- mounts the router
- resolves the active React template
- passes route readiness back to the route transition hook
- wraps the current route in
AppShell
Most navigation orchestration lives in useRouteTransition.js, not in the app entry itself.
Router Model
ReactWP still uses react-router-dom, but the route payload itself comes from WordPress.
That means:
- React Router owns browser history integration
- ReactWP owns the actual route payload and template selection
currentRouteinuseRouteTransition.jsis the runtime source of truth for template data
This is why a route change is more than a simple component switch. It includes payload fetch, asset preparation, route readiness, and animation timing.
Template Resolution
TemplateRegistry.js contains the registry mechanics.
Projects should usually register or override templates through:
src/themes/reactwp/js/inc/config/configureTemplateRegistry.js
That keeps the runtime implementation separate from project-level template decisions.
Template Props
When ReactWP resolves a route template, it passes a small standard prop set to the template component.
Current template props are:
routesitethemesystemnavigation
Example:
const Default = ({ route, site, theme, system, navigation }) => {
return (
<div>
<h1>{route.data.hero_title}</h1>
<p>{site.name}</p>
</div>
);
};
Notes:
routeis the most important prop and contains the active route payload, including values such aspath,search,query,template,data,seo, andheadsite,theme,system, andnavigationcome from the shared bootstrap runtime- if a project needs more standard props for every template,
App.jsxis the place where those props are injected
Loader and Preloading
Loader.js owns the first-load lifecycle.
It is responsible for:
- animating the initial loader
- preloading the next template
- loading critical fonts and media before a route becomes visible
- starting non-critical media downloads after the route is ready
Projects should customize loader behavior through:
src/themes/reactwp/js/inc/config/configureLoader.js
See Loader.
Page Transitions
PageTransition.js handles only the route transition animation layer.
By default, it fades #viewport out and back in while useRouteTransition.js coordinates:
- fetching the next route
- waiting for critical assets
- swapping the current route
- waiting for the next view to mount
- revealing the new view
Projects should customize this through:
src/themes/reactwp/js/inc/config/configurePageTransition.js
See Page Transitions.
Route Fetching
RouteService.js only fetches and normalizes route payloads.
The route hook and the loader decide when those routes should be prepared, revealed, and followed by deferred downloads.
RouteService.js also keeps an in-memory cache of visited route payloads for the current session, keyed by normalized pathname plus normalized search string.
Smooth Scrolling And Shell Boundaries
The frontend runtime also owns the smoother lifecycle through Scroller.js.
The smoother uses:
#pageWrapperas the wrapper#pageContentas the transformed content layer
Anything that must stay fixed outside the transformed scroll layer should mount outside that structure.
That is why Header.jsx uses a portal mount instead of staying inside the smoother tree.
Motion Helpers
motion.js is the small helper layer shared by the loader and transition runtime.
It centralizes:
gsapScrollTrigger- reduced motion detection
- Promise-based animation completion wiring
This is what allows ReactWP to support both:
- normal animated flows
- reduced-motion immediate fallbacks
Head Sync
After a client-side navigation, ReactWP can re-sync document head tags from route.head.
That flow is handled by:
src/themes/reactwp/js/inc/useDocumentMeta.js
If route.head exists, ReactWP applies those tags directly. Otherwise it falls back to the smaller SEO payload in route.seo.
This matters when you customize rwp_wp_head on the PHP side and expect those tags to survive React navigation.