Client authentication and session renewal
When you use Nutrient Web SDK with Document Engine, the viewer is authenticated using a JSON Web Token (JWT). Each JWT has an expiration time, and once it expires, the existing viewer instance will no longer be authorized to communicate with Document Engine. Long-running sessions, therefore, need a refresh strategy that recreates the viewer with a new token while preserving the user’s context.
Runtime JWT replacement
The Web SDK doesn’t currently provide an API to update the JWT of an already running viewer. Authentication is established when the viewer is created and can’t be changed afterward. To continue using a document after the token expires, the viewer needs to be unloaded and loaded again with a fresh JWT.
Supported refresh pattern
Applications can renew authentication by recreating the viewer shortly before the JWT expires:
- Decode the JWT and read its
exptimestamp. - Calculate when the token will expire and schedule a refresh shortly before that time.
- Request a new JWT from your backend.
- Capture the current view state (for example, page, zoom, and scroll position).
- Unload the existing viewer instance.
- Load a new instance with the updated JWT and restore the previous view state.
This minimizes visual disruption and keeps the document open across the refresh.
Example: Timer-based refresh
- The code below is a minimal payload decoder for demonstration purposes. In production, we’d advocate a well-tested library to parse JWTs like
jwt-decode:
function parseJwt(token) { const [, payload] = token.split("."); return JSON.parse(atob(payload));}
function scheduleJwtRefresh(instance, jwt, { documentId, serverUrl }) { const { exp } = parseJwt(jwt); const refreshBuffer = 5 * 60 * 1000; // Refresh 5 minutes early. const timeout = Math.max(exp * 1000 - Date.now() - refreshBuffer, 0);
setTimeout(async () => { const viewState = instance.viewState; const newJwt = await fetchNewJwt(); // Implement this to call your backend.
await NutrientViewer.unload(instance);
const newInstance = await NutrientViewer.load({ documentId, serverUrl, authPayload: { jwt: newJwt }, initialViewState: viewState, });
// Optionally reschedule for the next token. scheduleJwtRefresh(newInstance, newJwt, { documentId, serverUrl }); }, timeout);}This example refreshes the JWT before it expires, recreates the viewer, and restores its previous state. You can adapt the timing and state handling to match your user experience — for example, refreshing during idle periods or combining this with a user prompt.
Considerations for long-running sessions
For workflows where documents stay open for extended periods, proactively refreshing the JWT helps avoid unexpected errors when the token expires. Using a timed refresh and restoring view state keeps the session stable and reduces visible interruptions. Each application can choose how early to refresh and which parts of the view state to preserve based on its specific requirements.