These practices protect server-side rendering, user data, and the state of the FDK Store. Apply them to every React theme.
1. Do not fetch user data during server-side rendering
The theme engine caches the rendered HTML of a page. The cache key uses these request values, in this order:
| # | Parameter | Source | Purpose |
|---|---|---|---|
| 1 | Domain or website | Host header | The domain of the website |
| 2 | Page URL and query parameters | Request URI and query string | The requested path |
| 3 | Geographic location | x-location-detail header or app_location_details cookie | Country and pin code |
| 4 | Authentication status | Session cookies or x-external-user-data header | Login state of the user |
| 5 | Device platform | User-Agent header | Web, iOS, or Android |
| 6 | User segmentation | user_groups cookie | Group-specific content |
| 7 | Featured store context | x-featured-store-data header | Store-specific content |
| 8 | Feature flags | x-experimental-features header | A/B test variants |
| 9 | Customer type | x-user-status header | New or existing customer |
The cache key holds the login state only. The cache key does not hold the identity of the user.
A theme that fetches a user profile during server-side rendering writes that profile into the state, and the state goes into the cached HTML. A second user can then receive the personal data of the first user.
Do not fetch private user data on the server. Guard every such call with isRunningOnClient.
Incorrect:
await fpi.auth.getLoggedInUser();
Correct:
if (isRunningOnClient()) {
await fpi.auth.getLoggedInUser();
}
Apply the same rule to user groups:
if (isRunningOnClient()) {
await fpi.auth.getUserGroupsForUser();
}
2. Do not run browser-only code on the server
The server has no window, document, localStorage, or sessionStorage object. A section that
uses one of these objects at module level or during the first render breaks server-side rendering.
Put browser-only code inside an isRunningOnClient guard:
if (isRunningOnClient()) {
window.scrollTo(0, 0);
}
An ESLint rule can find these calls before a build.
3. Prefer cookies and FPI state over web storage
localStorage and sessionStorage are not available during server-side rendering, and the browser
does not send them to the server. Use one of these instead:
- A cookie, for values that must survive a page reload and reach the server.
- The FPI custom state, for values that only the current session needs.
// Set a value
fpi.custom.setValue("someKey", value);
// Read the same value
const state = fpi.store.getState();
const someKey = state?.custom?.someKey;
4. Do not add the FDK client as a direct dependency
The FDK Store already installs @gofynd/fdk-client-javascript and calls the platform through it. A
second copy of the package in the theme causes method failures.
Call the FPI method. The FPI method keeps the Redux state consistent:
await fpi.content.getNavigations();
Call fpi.sdk only when a request must not write to the state:
await fpi.sdk.content.getNavigations();
If the FDK Store has no method for the operation that you need, request the method in the FDK Store. Do not add the client package to the theme.