Skip to content

Image loading and cancellation

Pardown discovers images in the parsed document, loads each unique source, and resolves its dimensions before rendering the PDF. This reference covers default path handling, custom loaders, browser loading, failures, and cancellation.

Use the default image loader

defaultImageLoader fetches valid http: and https: URLs. It treats every other source as a file path and reads it with Node.js file-system APIs.

Set cwd to the directory that contains the Markdown file when it uses relative image paths:

ts
import { markdownToPdf } from '@pardown/core';

const markdown = `
# Trail report

![River beside the trail](images/river.jpg)

![Regional map](https://assets.example.com/maps/region.png)
`;

const pdf = await markdownToPdf(markdown, {
  cwd: '/srv/trail-reports',
});

The local image resolves to /srv/trail-reports/images/river.jpg. If you omit cwd, relative file paths use the runtime's current working directory.

IMPORTANT

Local image loading requires a Node.js-compatible environment. Provide a custom loader for relative image sources in a browser.

Provide a custom image loader

Set imageLoader when images require authentication, come from object storage, or use application-specific identifiers. An image loader receives the source and context, then returns the raw image bytes as a Uint8Array.

ts
import { markdownToPdf, type ImageLoader } from '@pardown/core';

const assetToken = process.env.ASSET_TOKEN;
if (!assetToken) {
  throw new Error('ASSET_TOKEN is required');
}

const imageLoader: ImageLoader = async (source, { signal }) => {
  const response = await fetch(`https://assets.example.com/${source}`, {
    headers: { Authorization: `Bearer ${assetToken}` },
    signal,
  });

  if (!response.ok) {
    throw new Error(`Image request failed with status ${response.status}`);
  }

  return new Uint8Array(await response.arrayBuffer());
};

const pdf = await markdownToPdf('![Warehouse plan](plans/warehouse.png)', {
  imageLoader,
});

Pardown calls the loader once for each distinct source string and loads distinct sources concurrently. It passes cwd and signal through the loader context.

Load images in a browser

Provide a browser-safe loader when Markdown contains relative images. Resolve each source against a known base URL rather than using the default loader's Node.js file-system branch.

ts
import { markdownToPdf, type ImageLoader } from '@pardown/core';

const imageLoader: ImageLoader = async (source, { signal }) => {
  const imageUrl = new URL(source, document.baseURI);
  const response = await fetch(imageUrl, { signal });

  if (!response.ok) {
    throw new Error(`Image request failed with status ${response.status}`);
  }

  return new Uint8Array(await response.arrayBuffer());
};

const pdf = await markdownToPdf('![Office entrance](images/entrance.jpg)', {
  imageLoader,
});

Your site's cross-origin and content security policies still apply to these requests.

Handle image failures

A failed fetch, file read, or image decode emits an IMAGE_LOAD_FAILED diagnostic. Pardown continues conversion and renders the image's alternative text, or [Image not found] when the source has no alternative text.

md
![Weekly sales chart](charts/missing.png)

Use a diagnostic handler when you need to collect the source and underlying cause. Read Diagnostics for the structured diagnostic type.

Cancel image loading

Pass an AbortSignal to markdownToPdf. The default loader forwards it to fetch or readFile, and a custom loader must forward it to its own underlying operation.

ts
import { markdownToPdf } from '@pardown/core';

const markdown = '# Live status\n\n![Current status](https://assets.example.com/status.png)';
const controller = new AbortController();

const conversion = markdownToPdf(markdown, {
  signal: controller.signal,
});

controller.abort();

try {
  await conversion;
} catch (error) {
  console.error('Conversion cancelled', error);
}

When an image load fails after the signal is aborted, Pardown rejects the conversion instead of emitting IMAGE_LOAD_FAILED.

NOTE

The signal applies to image loading. It doesn't cancel Markdown parsing or final PDF rendering, and it has no effect when the document doesn't contain images.

API types

The public image-loading types define the custom loader contract and its context.

ts
type ImageLoaderContext = {
  cwd?: string;
  signal?: AbortSignal;
};

type ImageLoader = (
  source: string,
  context: ImageLoaderContext,
) => Promise<Uint8Array>;

Read the @pardown/core API reference for defaultImageLoader and the complete package exports.

Released under the MIT License.