---
title: "Save & download PDF from server with JavaScript viewer | Nutrient"
canonical_url: "https://www.nutrient.io/guides/web/save-a-document/to-remote-server/"
md_url: "https://www.nutrient.io/guides/web/save-a-document/to-remote-server.md"
last_updated: "2026-05-25T17:21:17.322Z"
description: "Learn how to use Nutrient Web SDK to programmatically upload PDF documents to a remote server using the Fetch API and FormData in JavaScript."
---

# Save PDFs to a remote server using JavaScript

Nutrient Web SDK makes it possible to upload a document to a remote server. This can be done programmatically by exporting the document and sending it to the destination server.

The following example shows how to use the `Fetch` Web API to send the `ArrayBuffer` resolved to by [`instance.exportPDF()`](https://www.nutrient.io/api/web/classes/NutrientViewer.Instance.html#exportpdf) to a remote server ([try it in the Playground](https://www.nutrient.io/demo/sandbox?p=eyJ2IjoxLCJjc3MiOiIvKiBBZGQgeW91ciBDU1MgaGVyZSAqL1xuIiwianMiOiJjb25zb2xlLmxvZyhcIkRlbW9uc3RyYXRpbmcgUERGIGV4cG9ydC4uLlwiKTtcblxuTnV0cmllbnRWaWV3ZXIubG9hZCh7XG4gIC4uLmJhc2VPcHRpb25zLFxufSkudGhlbihhc3luYyAoaW5zdGFuY2UpID0%252BIHtcbiAgY29uc29sZS5sb2coXCJOdXRyaWVudCBsb2FkZWQhXCIpO1xuXG4gIC8vIENyZWF0ZSBhIHNhbXBsZSBhbm5vdGF0aW9uIHRvIGRlbW9uc3RyYXRlIGV4cG9ydCB3aXRoIGNoYW5nZXNcbiAgY29uc3QgYW5ub3RhdGlvbiA9IG5ldyBOdXRyaWVudFZpZXdlci5Bbm5vdGF0aW9ucy5Ob3RlQW5ub3RhdGlvbih7XG4gICAgcGFnZUluZGV4OiAwLFxuICAgIGJvdW5kaW5nQm94OiBuZXcgTnV0cmllbnRWaWV3ZXIuR2VvbWV0cnkuUmVjdCh7XG4gICAgICBsZWZ0OiA1MCxcbiAgICAgIHRvcDogNTAsXG4gICAgICB3aWR0aDogMzAsXG4gICAgICBoZWlnaHQ6IDMwLFxuICAgIH0pLFxuICAgIHRleHQ6IHtcbiAgICAgIGZvcm1hdDogXCJwbGFpblwiLFxuICAgICAgdmFsdWU6IFwiVGhpcyBub3RlIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIGV4cG9ydGVkIFBERlwiLFxuICAgIH0sXG4gIH0pO1xuXG4gIGF3YWl0IGluc3RhbmNlLmNyZWF0ZShhbm5vdGF0aW9uKTtcbiAgY29uc29sZS5sb2coXCJDcmVhdGVkIHNhbXBsZSBhbm5vdGF0aW9uIGZvciBleHBvcnRcIik7XG5cbiAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDUwMCkpO1xuXG4gIGNvbnNvbGUubG9nKFwiRXhwb3J0aW5nIFBERi4uLlwiKTtcbiAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCBpbnN0YW5jZS5leHBvcnRQREYoKTtcbiAgY29uc29sZS5sb2coXCJQREYgZXhwb3J0ZWQgc3VjY2Vzc2Z1bGx5IVwiKTtcbiAgY29uc29sZS5sb2coXCJBcnJheUJ1ZmZlciBzaXplOlwiLCBhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoLCBcImJ5dGVzXCIpO1xuXG4gIC8vIENvbnZlcnQgdG8gQmxvYlxuICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2FycmF5QnVmZmVyXSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL3BkZlwiIH0pO1xuICBjb25zb2xlLmxvZyhcIkNvbnZlcnRlZCB0byBCbG9iOlwiLCBibG9iLnNpemUsIFwiYnl0ZXNcIik7XG5cbiAgLy8gU2ltdWxhdGUgdXBsb2FkIHByZXBhcmF0aW9uIChub3QgYWN0dWFsbHkgdXBsb2FkaW5nIGluIHBsYXlncm91bmQpXG4gIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gIGZvcm1EYXRhLmFwcGVuZChcImZpbGVcIiwgYmxvYiwgXCJleHBvcnRlZC1kb2N1bWVudC5wZGZcIik7XG5cbiAgY29uc29sZS5sb2coXCJGb3JtRGF0YSBwcmVwYXJlZCBmb3IgdXBsb2FkXCIpO1xuICBjb25zb2xlLmxvZyhcIkluIHByb2R1Y3Rpb24sIHlvdSB3b3VsZCBzZW5kIHRoaXMgdG8geW91ciBzZXJ2ZXI6XCIpO1xuICBjb25zb2xlLmxvZyhcIiAgYXdhaXQgZmV0Y2goJy91cGxvYWQnLCB7IG1ldGhvZDogJ1BPU1QnLCBib2R5OiBmb3JtRGF0YSB9KVwiKTtcblxuICAvLyBJbnN0ZWFkIG9mIHVwbG9hZGluZywgZG93bmxvYWQgdGhlIGZpbGUgdG8gZGVtb25zdHJhdGVcbiAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgY29uc3QgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICBhLmhyZWYgPSB1cmw7XG4gIGEuZG93bmxvYWQgPSBcImV4cG9ydGVkLWRvY3VtZW50LnBkZlwiO1xuICBhLmNsaWNrKCk7XG4gIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcblxuICBjb25zb2xlLmxvZyhcIlBERiBkb3dubG9hZGVkIHRvIGRlbW9uc3RyYXRlIGV4cG9ydCBmdW5jdGlvbmFsaXR5IVwiKTtcbn0pO1xuIn0%253D)):

```js

try {
  const arrayBuffer = await instance.exportPDF();
  const blob = new Blob([arrayBuffer], { type: "application/pdf" });
  const formData = new FormData();
  formData.append("file", blob);
  const response = await fetch("/upload", {
    method: "POST",
    body: formData
  });
  if (!response.ok) {
    throw new Error(`Upload failed: ${response.statusText}`);
  }
  console.log("PDF uploaded successfully");
} catch (error) {
  console.error("Failed to save PDF to server:", error.message);
}

```

In the example above, the backend server expects to receive a `POST` request with a content type of `multipart/form-data` through an `/upload` endpoint it exposes. The payload of the request will depend upon your specific backend implementation.

When exporting a document, you have several options. Refer to our guides on [flattening annotations](https://www.nutrient.io/guides/web/annotations/flatten.md) and [incremental saving](https://www.nutrient.io/guides/web/features/document-processing.md) for more details.

Auto saving can be configured for different scenarios and use cases. You can find more information in our [auto save](https://www.nutrient.io/guides/web/features/saving.md) guide.
---

## Related pages

- [Auto-saving PDF changes in our JavaScript viewer](/guides/web/features/saving.md)
- [Enable incremental saving of PDFs using JavaScript](/guides/web/features/document-processing.md)
- [Save PDF files using JavaScript](/guides/web/save-a-document.md)
- [Detecting unsaved changes in PDFs](/guides/web/save-a-document/detect-unsaved-changes.md)
- [Save PDFs to an ArrayBuffer using JavaScript](/guides/web/save-a-document/to-arraybuffer.md)
- [Save documents as PDFs on the web](/guides/web/save-a-document/save-as.md)
- [Save PDFs to Document Engine using JavaScript](/guides/web/save-a-document/to-document-engine.md)
- [Save PDFs to local storage using JavaScript](/guides/web/save-a-document/to-local-storage.md)
- [Save PDF without annotations using JavaScript](/guides/web/save-a-document/without-annotations.md)

