Isomorphic React
Understand how JopiJS handles code execution across both server and client environments.
Overview
In JopiJS, React components are isomorphic (also known as universal), meaning they can execute on both the server (for initial rendering) and the client browser (for interactivity).
This approach ensures:
- Fast Initial Load: Users see content immediately without waiting for JavaScript.
- Search Engine Optimization: Crawlers can index your content easily.
- Improved Performance: Reduced time-to-first-byte and smoother transitions.
1. Environment-Specific Logic
JopiJS provides built-in mechanisms to handle code that needs to behave differently depending on where it's running.
Automatic Import Swapping
The JopiJS bundler includes a unique feature for managing server vs. client implementations. If you use the string jBundler_ifServer in a file path, the bundler will automatically swap it for jBundler_ifBrowser when building the client-side bundle.
Example Usage:
Suppose you have two files:
db_service.jBundler_ifServer.ts(contains server-side database queries)db_service.jBundler_ifBrowser.ts(contains API calls to fetch data)
You can import them like this in your component:
// This path will be automatically swapped in the browser bundle
import { fetchData } from "./db_service.jBundler_ifServer.ts";
export default function MyComponent() {
// On the server, this uses the direct database logic.
// In the browser, the bundler swaps the import to the API-based logic.
const data = fetchData();
// ...
}UI Mode Detection
JopiJS provides a global constant JOPI_BUNDLER_UI_MODE that is replaced at build time. This is particularly useful for detecting if the application is running in development mode with Hot Module Replacement (HMR) enabled.
It can take values like "default" or "ReactHMR".
const isReactHMR = "JOPI_BUNDLER_UI_MODE" === "ReactHMR";2. Best Practices & Pitfalls
Because your code runs in two very different environments, there are important rules to follow to avoid bugs and performance issues.
⚠️ Avoid Global Variables
On the server, a single Node.js process might handle thousands of requests. If you store user-specific data in a global variable, that data could "leak" to another user’s request.
- Don't: Use top-level variables to store request-specific state.
- Do: Use React state, context, or pass data through props.
Server-Side Side Effects
Remember that traditional browser APIs (like window, document, or localStorage) do not exist on the server. Accessing them directly during the initial render will cause the server to crash.
Safety First: Always wrap browser-only logic in a useEffect hook (which only runs on the client) or check if the code is running in a browser environment:
if (typeof window !== 'undefined') {
// Safe to use window here
}3. Summarizing Isomorphism
Server-Side Rendering
JopiJS performs the first render on the server to generate HTML, improving SEO and perceived performance.
Client-Side Hydration
Once the HTML reaches the browser, React "hydrates" it, attaching event listeners and enabling full interactivity.
Shared Codebase
Write your UI logic once and let JopiJS handle the complexity of running it in both environments.