Getting started
Overview What is DWS Viewer API? Dashboard Trial limitations Language support Deployment options Security PrivacyIntegration
Overview Use with your backend Open document in Web SDKClient authentication
Authentication flow Generate a session tokenAPI
Overview Authentication Upload documents API referenceExamples
Node.js integration example Support About NutrientNode.js integration example
This example demonstrates a complete Node.js server implementation that handles document upload, session token generation, and provides the necessary endpoints for integrating with DWS Viewer API and Nutrient Web SDK.
Package dependencies
Install the required dependencies:
npm install express multer
Complete server implementation
const express = require('express');
const multer = require('multer');
const upload = multer();
const app = express();
app.use(express.json());
// Helper function to create session token for a document
const createSessionToken = async (documentId, apiKey) => {
const sessionPayload = {
allowed_documents: [{
document_id: documentId,
document_permissions: ['read', 'write', 'download']
}],
exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1 hour from now
};
const sessionResponse = await fetch('https://api.nutrient.io/viewer/sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(sessionPayload)
});
if (!sessionResponse.ok) {
throw new Error(`Session creation failed: ${sessionResponse.statusText}`);
}
const sessionResult = await sessionResponse.json();
return sessionResult.jwt;
};
// Upload document and generate session token
app.post('/api/upload-and-create-session', upload.single('file'), async (req, res) => {
try {
const apiKey = process.env.NUTRIENT_DWS_VIEWER_API_KEY;
if (!req.file) {
return res.status(400).json({
success: false,
error: 'No file uploaded'
});
}
// Step 1: Upload document to DWS
const uploadResponse = await fetch('https://api.nutrient.io/viewer/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': req.file.mimetype,
'Content-Length': req.file.size.toString()
},
body: req.file.buffer
});
if (!uploadResponse.ok) {
throw new Error(`Upload failed: ${uploadResponse.statusText}`);
}
const uploadResult = await uploadResponse.json();
// Step 2: Extract document ID from nested response
const documentId = uploadResult.data?.document_id;
if (!documentId) {
throw new Error('No document ID found in upload response');
}
// Step 3: Generate session token
const sessionToken = await createSessionToken(documentId, apiKey);
res.json({
success: true,
documentId: documentId,
sessionToken: sessionToken,
title: uploadResult.data?.title || 'Untitled Document'
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});
// Generate session token for existing document
app.post('/api/create-session', async (req, res) => {
try {
const { documentId } = req.body;
const apiKey = process.env.NUTRIENT_DWS_VIEWER_API_KEY;
if (!documentId) {
return res.status(400).json({
success: false,
error: 'Document ID is required'
});
}
// Generate session token
const sessionToken = await createSessionToken(documentId, apiKey);
res.json({
success: true,
sessionToken: sessionToken
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Frontend integration
Once your server is running, you can use the endpoints from your frontend to upload documents and load them in Nutrient Web SDK:
Security note: In production, implement proper authentication between your frontend and backend to prevent unauthorized users from uploading documents or creating session tokens. This could include user authentication, API keys, rate limiting, or other access control mechanisms appropriate for your application.
// Upload file and get session token
const uploadAndLoad = async (file) => {
try {
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/upload-and-create-session', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
// Load document in Nutrient Web SDK
await NutrientViewer.load({
container: document.querySelector('#viewer-container'),
session: result.sessionToken
});
} else {
console.error('Upload failed:', result.error);
}
} catch (error) {
console.error('Error:', error);
}
};
// Generate new session for existing document
const loadExistingDocument = async (documentId) => {
try {
const response = await fetch('/api/create-session', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ documentId })
});
const result = await response.json();
if (result.success) {
await NutrientViewer.load({
container: document.querySelector('#viewer-container'),
session: result.sessionToken
});
} else {
console.error('Session creation failed:', result.error);
}
} catch (error) {
console.error('Error:', error);
}
};
Environment setup
Make sure to set your API key as an environment variable:
export NUTRIENT_DWS_VIEWER_API_KEY=your_api_key_here
Or create a .env
file:
NUTRIENT_DWS_VIEWER_API_KEY=your_api_key_here
Error handling
The example includes comprehensive error handling for common scenarios:
- Missing files in upload requests
- Failed document uploads
- Missing document IDs in responses
- Session token generation failures
- Invalid document IDs for existing documents
Security considerations
- API keys are kept on the server side and never exposed to the frontend
- Session tokens have expiration times to limit access duration
- File uploads are processed on the server to maintain security
- Document permissions can be customized per session token