Split a PDF by Text in JavaScript Using PDF.co
Split a PDF at pages containing specified text, such as an invoice heading. This Node.js example starts an asynchronous job, checks its status, and downloads the resulting PDFs.
Prepare Your Project
Install Node.js 20 or newer and create a project folder.
Create a file named index.cjs. This example uses Node.js’s built-in features, so no additional packages are required.
Add the Code
Paste this complete script into index.cjs:
const { createWriteStream, mkdirSync } = require("node:fs");
const { join } = require("node:path");
const { Readable } = require("node:stream");
const { pipeline } = require("node:stream/promises");
const { setTimeout: delay } = require("node:timers/promises");
const API_KEY = "YOUR_PDFCO_API_KEY";
const SOURCE_URL = "https://bytescout-com.s3-us-west-2.amazonaws.com/files/demo-files/cloud-api/pdf-split/multiple-invoices.pdf";
const SEARCH_TEXT = "Invoice Number";
const OUTPUT_DIR = join(process.cwd(), "split-output");
async function apiPost(endpoint, body) {
const response = await fetch(`https://api.pdf.co/v1/${endpoint}`, {
method: "POST",
headers: {
"x-api-key": API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(30000)
});
const data = await response.json();
if (!response.ok || data.error) {
throw new Error(data.message || `API request failed: ${response.status}`);
}
return data;
}
async function waitForJob(jobId) {
const deadline = Date.now() + 5 * 60 * 1000;
while (Date.now() < deadline) {
await delay(3000);
const job = await apiPost("job/check", { jobid: jobId });
console.log(`Job status: ${job.status}`);
if (job.status === "success") return job;
if (job.status !== "working") {
throw new Error(job.message || `Job ended: ${job.status}`);
}
}
throw new Error("Stopped waiting after five minutes.");
}
async function main() {
if (API_KEY === "YOUR_PDFCO_API_KEY") {
throw new Error("Set API_KEY before running this example.");
}
const started = await apiPost("pdf/split2", {
url: SOURCE_URL,
searchString: SEARCH_TEXT,
caseSensitive: false,
regexSearch: false,
excludeKeyPages: false,
async: true
});
if (!started.jobId) throw new Error("The API did not return a job ID.");
const completed = await waitForJob(started.jobId);
const resultUrl = completed.url || started.url;
if (!resultUrl) throw new Error("The job did not return a result URL.");
const result = await fetch(resultUrl, {
signal: AbortSignal.timeout(30000)
});
if (!result.ok) throw new Error(`Cannot read results: ${result.status}`);
const manifest = await result.json();
const urls = Array.isArray(manifest) ? manifest : manifest.urls;
if (!Array.isArray(urls) || urls.length === 0) {
throw new Error("The result contains no output PDF URLs.");
}
// Keep each run separate to avoid overwriting earlier results.
const folder = join(OUTPUT_DIR, `run-${Date.now()}`);
mkdirSync(folder, { recursive: true });
for (const [index, url] of urls.entries()) {
const response = await fetch(url, {
signal: AbortSignal.timeout(120000)
});
if (!response.ok || !response.body) {
throw new Error(`PDF download failed: ${response.status}`);
}
const filename = join(folder, `part${index + 1}.pdf`);
await pipeline(
Readable.fromWeb(response.body),
createWriteStream(filename, { flags: "wx" })
);
console.log(`Saved: ${filename}`);
}
}
main().catch(error => {
console.error(error.message);
process.exitCode = 1;
});Configure the Example
Replace YOUR_PDFCO_API_KEY with your key from the PDF.co dashboard.
Keep the sample SOURCE_URL or replace it with a direct download URL for your PDF. Set SEARCH_TEXT to the text that identifies your split points.
This example uses case-insensitive matching and retains the pages containing the search text. See the Split PDF by Text documentation for available settings.
Run and Review the Results
Open a terminal in your project folder and run:
node index.cjsThe script checks the background job status every three seconds. After completion, it downloads the PDFs into a new folder under split-output, named part1.pdf, part2.pdf, and so on.
Open the files and confirm the split points. The sample PDF contains “Invoice Number” on all three pages, so the expected result is three one-page PDFs.
In this tutorial, you learned how to split a PDF by text from a URL in JavaScript using PDF.co Web API with asynchronous processing. By taking advantage of async mode, your application can efficiently handle large files without delays. You also discovered how to quickly get started by modifying just a few lines in the sample code.
Related Tutorials
