---
title: "Node.js rendering and font diagnostics"
canonical_url: "https://www.nutrient.io/guides/dws-viewer/examples/nodejs-rendering-font-diagnostics/"
md_url: "https://www.nutrient.io/guides/dws-viewer/examples/nodejs-rendering-font-diagnostics.md"
last_updated: "2026-06-08T17:11:05.521Z"
description: "Collect DWS Viewer rendering and font diagnostics in Node.js by fetching fonts, substitutions, document metadata, and a rendered page preview."
---

# Node.js rendering and font diagnostics

This example shows how to collect the most useful diagnostics for rendering and font investigations in DWS Viewer API.

The script fetches:

- Document fonts

- Global fonts

- Global font substitutions

- Document information

- Document properties

- A rendered preview image for one page

It then saves the results locally so they can be attached to a support ticket or compared across environments.

## Prerequisites

- A DWS Viewer API key in `NUTRIENT_DWS_VIEWER_API_KEY`

- A `documentId` for the file you want to investigate

- Node.js 18 or later

## Complete example

The following code is a complete example. You can copy and paste it into a file named `diagnostics.mjs` and run it with Node.js:

```js

import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";

const apiKey = process.env.NUTRIENT_DWS_VIEWER_API_KEY;
const documentId = process.argv[2];
const pageIndex = Number(process.argv[3]?? 0);
const outputDir = path.resolve(process.argv[4]?? `./dws-diagnostics-${documentId}`);

if (!apiKey) {
  throw new Error("Missing NUTRIENT_DWS_VIEWER_API_KEY");
}

if (!documentId) {
  throw new Error("Usage: node diagnostics.mjs <documentId> [pageIndex] [outputDir]");
}

await mkdir(outputDir, { recursive: true });

const requestJson = async (pathname) => {
  const response = await fetch(`https://api.nutrient.io${pathname}`, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: "application/json",
    },
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`${pathname} failed: ${response.status} ${errorText}`);
  }

  return response.json();
};

const requestBinary = async (pathname, accept) => {
  const response = await fetch(`https://api.nutrient.io${pathname}`, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: accept,
    },
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`${pathname} failed: ${response.status} ${errorText}`);
  }

  return Buffer.from(await response.arrayBuffer());
};

const diagnostics = {
  documentFonts: await requestJson(`/viewer/documents/${documentId}/fonts`),
  globalFonts: await requestJson("/viewer/fonts"),
  fontSubstitutions: await requestJson("/viewer/font_substitutions"),
  documentInfo: await requestJson(`/viewer/documents/${documentId}/document_info`),
  documentProperties: await requestJson(`/viewer/documents/${documentId}/properties`),
};

const previewImage = await requestBinary(
  `/viewer/documents/${documentId}/pages/${pageIndex}/image?width=1600`,
  "image/png",
);

await Promise.all([
  writeFile(
    path.join(outputDir, "document-fonts.json"),
    JSON.stringify(diagnostics.documentFonts, null, 2),
  ),
  writeFile(
    path.join(outputDir, "global-fonts.json"),
    JSON.stringify(diagnostics.globalFonts, null, 2),
  ),
  writeFile(
    path.join(outputDir, "font-substitutions.json"),
    JSON.stringify(diagnostics.fontSubstitutions, null, 2),
  ),
  writeFile(
    path.join(outputDir, "document-info.json"),
    JSON.stringify(diagnostics.documentInfo, null, 2),
  ),
  writeFile(
    path.join(outputDir, "document-properties.json"),
    JSON.stringify(diagnostics.documentProperties, null, 2),
  ),
  writeFile(path.join(outputDir, `page-${pageIndex}.png`), previewImage),
]);

console.log(`Saved diagnostics to ${outputDir}`);

```

## Run the script

Run the script with your API key and a document ID. Optionally, specify a page index (default 0) and an output directory (default `./dws-diagnostics-<documentId>`):

```shell

export NUTRIENT_DWS_VIEWER_API_KEY=your_api_key_here
node diagnostics.mjs <document_id> 0

```

Example output directory:

```text./dws-diagnostics-<document_id>/
├── document-fonts.json
├── document-info.json
├── document-properties.json
├── font-substitutions.json
├── global-fonts.json
└── page-0.png

```

## How to read the output

- `document-fonts.json` — Font faces referenced by the document

- `global-fonts.json` — Font faces globally available in DWS Viewer API

- `font-substitutions.json` — Configured replacement patterns for missing fonts

- `document-info.json` — Page count, page sizes, metadata, and permissions

- `document-properties.json` — File properties such as byte size, SHA-256, storage type, and password-protection status

- `page-0.png` — A server-rendered preview you can compare with what you see in the browser

## Related guides

- [Rendering and font diagnostics](https://www.nutrient.io/guides/dws-viewer/troubleshooting/rendering-and-font-diagnostics.md)

- [Support](https://www.nutrient.io/guides/dws-viewer/support.md)
---

## Related pages

- [Examples](/guides/dws-viewer/examples.md)
- [Node.js integration example](/guides/dws-viewer/examples/nodejs-integration-example.md)
- [Node.js large document triage](/guides/dws-viewer/examples/nodejs-large-document-triage.md)
- [Build secure PDF viewers with table extraction functionality](/guides/dws-viewer/examples/build-secure-pdf-viewers-with-table-extraction.md)

