# Export to PDF

The export to PDF feature lets you generate a PDF file directly from the editor. It sends the editor’s content and styles to the CKEditor Cloud Services HTML-to-PDF converter, so the PDF preserves the document’s formatting and layout.

> **Unlock this feature with selected CKEditor Plans**
>
> Try all premium features – no credit card needed.
>
> [Sign up for a free trial ](https://portal.ckeditor.com/checkout?plan=free)[Select a Plan](https://ckeditor.com/pricing/)

<a id="demo">

## Demo

The demo below lets you generate a PDF file based on the editor’s content. Edit the document, then click the export to PDF toolbar button to save the content as a PDF.

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

This demo presents a limited set of features. Visit the [feature-rich editor example](../../examples/builds-custom/full-featured-editor.md) to see more in action.

<a id="how-it-works">

## How it works

The PDF export feature collects the HTML [generated with the `editor.getData()` method](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-dataCallback) and the [default editor content styles](../../getting-started/setup/css.md) combined with the styles provided by you in the configuration. It then sends them to the CKEditor Cloud Services HTML to PDF converter service. The service generates a PDF file and returns it to the user’s browser so they can save it in the PDF format on their disk.

The crucial aspect of this feature is its [configuration](#configuration). To ensure that the generated PDF looks as close as possible to the same content displayed in the WYSIWYG editor, the feature must be carefully configured.

The complementary [pagination feature](../pagination/pagination.md) allows you to see where page breaks would be after you export the document to PDF. Thanks to the live preview, the user can fine-tune the structure of the output document when editing it. The pagination feature also shows you the page count and lets you navigate between the document pages.

<a id="integration-with-merge-fields-content-placeholders">

## Integration with merge fields (content placeholders)

Merge fields are visually distinct placeholder elements you can put into the content to mark places where real values should be inserted. It is perfect for creating document templates and other kinds of personalized content. This allows for automation and creating batch output of personalized PDF files. Learn how to configure it in the [proper section of the merge fields guide](../merge-fields.md#using-callbacks-to-define-values).

<a id="before-you-start">

## Before you start

> **Note**
>
> On the Free Plan, file conversion is available in a limited capacity. Unlock significantly more conversions and full access with a [CKEditor Paid Plan](https://ckeditor.com/pricing/).
>
> You can also sign up for the [CKEditor Premium Features 14-day free trial](https://portal.ckeditor.com/checkout?plan=free) to test the feature.

After you select a plan, follow the steps below, as explained in the [Export to PDF quick start guide](../../../../cs/latest/guides/export-to-pdf/quick-start.md):

* [Log into the CKEditor Ecosystem customer dashboard](../../../../cs/latest/guides/export-to-pdf/quick-start.md#log-in-to-the-customer-portal).
* [Create the token endpoint needed for authorization](../../../../cs/latest/guides/export-to-pdf/quick-start.md#creating-token-endpoint).
* [Install](#installation) and [configure](#configuration) the CKEditor 5 export to PDF plugin.

<a id="installation">

## Installation

After [installing the editor](../../getting-started/installation/cloud/quick-start.md), add the feature to your plugin list and toolbar configuration:

**NPM**

```js
import { ClassicEditor } from 'ckeditor5';
import { ExportPdf } from 'ckeditor5-premium-features';

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>',
		plugins: [ ExportPdf, /* ... */ ],
		toolbar: [ 'exportPdf', '|', /* ... */ ],
		exportPdf: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

**CDN**

```js
const { ClassicEditor } = CKEDITOR;
const { ExportPdf } = CKEDITOR_PREMIUM_FEATURES;

ClassicEditor
	.create( {
		licenseKey: '<YOUR_LICENSE_KEY>',
		plugins: [ ExportPdf, /* ... */ ],
		toolbar: [ 'exportPdf', '|', /* ... */ ],
		exportPdf: {
			// Configuration.
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

<a id="configuration">

## Configuration

> **Note**
>
> For more technical details, please check the [plugin configuration API](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md).

The configuration is the key to allow the HTML to PDF converter service to generate PDF documents that look as close as possible to the content created in the rich-text editor.

The configuration consists of 3 main parts:

* The [converter options](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-converterOptions) that tell the HTML to PDF converter service what is the format of the page (A4, Letter), the page orientation, etc.
* The [style sheets](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets) sent to the service. They allow styling the content in the PDF document with the same styles that are applied to the content in the editor.
* The [content styles used in the editor](../../getting-started/setup/css.md) when rendered on the page.

These options need to stay in sync. For example:

* The style sheets sent to the service must define the same typography that is used in the editor.
* The editor’s content container should be styled in a way that reflects the page size and margins defined in the converter options.
* All web fonts defined on the page where the editor is used must be sent to the service as well.

Read on to learn how to achieve this.

<a id="default-configuration">

### Default configuration

This is the default configuration of the PDF export feature for CKEditor 5.

> **Note**
>
> Export to PDF uses version 2 of the converter API by default. Version 1 is deprecated and kept for backward compatibility only. See the [Export to PDF V1 (deprecated)](#export-to-pdf-v1-deprecated) section if you still need to use it.

```js
{
	exportPdf: {
		fileName: 'document.pdf',
		converterUrl: 'https://pdf-converter.cke-cs.com/v2/convert/html-pdf',
		stylesheets: [
			'./ckeditor5-content.css'
		],
		converterOptions: {
			document: {
				size: 'A4',
				orientation: 'portrait',
				margins: {
					top: '0mm',
					bottom: '0mm',
					right: '0mm',
					left: '0mm'
				}
			},
			rendering: {
				wait_for_network: true,
				wait_time: 0
			}
		},
		dataCallback: ( editor ) => editor.getData()
	}
}
```

If you are using the EU cloud region, remember to adjust the endpoint:

```js
exportPdf: {
	converterUrl: 'https://pdf-converter.cke-cs-eu.com/v2/convert/html-pdf'
}
```

<a id="stylesheets-option">

### `stylesheets` option

Use the `stylesheets` option to provide paths (relative or absolute URLs) to all style sheets that should be included during the HTML to PDF conversion.

The rule of thumb is if you want the export to preserve the styles, always add the style sheets with the content styles of the editor. Their path depends on your application setup, for example:

```js
{
	exportPdf: {
		stylesheets: [
			'./ckeditor5-content.css'
			'./styles.css'
		],
		// ...
	}
}
```

In the snippet above, we assume both style sheets are available via the relative path on the client side. For example, some frameworks allow to place files in the `public` folder.

<a id="plugin-options">

### Plugin options

For some use cases the default configuration will suffice. As you can see in the example above, you can improve how your PDF file will look by adjusting the PDF export plugin configuration.

* **[`config.exportPdf.stylesheets`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets)**

  You can set the paths (relative or absolute URLs) to the style sheets that should be included during the HTML to PDF conversion.

  > **Warning**
  >
  > **The order of the paths matters**. If you have custom elements or have overridden the default editor’s content styles, the paths to your file(s) should go after the editor content styles. See the examples in the `config.exportPdf.stylesheets` documentation.

* **[`config.exportPdf.fileName`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-fileName)**

  Sets the name for the generated PDF file (together with the extension). The default name is `document.pdf`. You can see it called in the [default configuration](#default-configuration) listing above.

  This option, however, also allows for using a callback to generate a dynamic file name. In the example below, the document’s title will be used as the file name of the generated PDF file.

  ```js
  // Dynamic file name.
  const exportPdfConfig = {
  	fileName: () => {
  		const articleTitle = document.querySelector( '#title' );
  		return `${ articleTitle.value }.pdf`;
  	}
  }
  ```

* **[`config.exportPdf.converterUrl`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-converterUrl)**

  By default, the PDF export feature is configured to use the CKEditor Cloud Services HTML to PDF converter service to generate the PDF files. You can, however, use this option to provide the URL to an on-premises converter. [Contact us](https://ckeditor.com/contact/) if you need this feature.

  If you are using the EU cloud region, adjust the endpoint accordingly:

  ```js
  exportPdf: {
  	converterUrl: 'https://pdf-converter.cke-cs-eu.com/v2/convert/html-pdf'
  }
  ```

* **[`config.exportPdf.tokenUrl`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-tokenUrl)**

  A token URL or a token request function. This field is optional and you should use it when you require a different [`tokenUrl`](../../api/module_cloud-services_cloudservicesconfig-CloudServicesConfig.md#member-tokenUrl) for the export to PDF feature. You can skip this option if you use the `cloudServices` configuration to provide the same `tokenUrl`. In most cases you will probably want to provide the token in `cloudServices`, as other plugins like [real-time collaboration](../collaboration/real-time-collaboration/real-time-collaboration.md) will use this token as well. In this guide, to explicitly show that this value is needed, we leave it the inside `exportPdf` configuration.

* **[`config.exportPdf.converterOptions`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-converterOptions)**

  The converter options control the PDF output: page size, margins, headers, footers, metadata, security, and more. See the [HTML to PDF Converter features](#html-to-pdf-converter-features) section for details on each capability, or refer to the [API documentation](../../api/module_export-pdf_exportpdf-ExportPdfConverterOptionsV2.md) for the full reference. Below is a sample configuration:

  ```js
  converterOptions: {
  	document: {
  		size: 'A4',
  		orientation: 'portrait',
  		margins: {
  			top: '20mm',
  			bottom: '20mm',
  			right: '12mm',
  			left: '12mm'
  		}
  	}
  }
  ```

* **[`config.exportPdf.dataCallback`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-dataCallback)**

  By default, the plugin uses `editor.getData()` to gather the HTML sent to the conversion service. You can use this option to customize the editor’s data. For example, use this setting to enable [highlighting tracked changes](../collaboration/track-changes/track-changes.md) and [comments](../collaboration/comments/comments.md) in the exported PDF file.

  ```js
  dataCallback: editor => editor.getData( {
  		showSuggestionHighlights: true,
  		showCommentHighlights: true
  	} ),
  ```

> **Note**
>
> The [`config.exportPdf.dataCallback`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-dataCallback) option may be useful when:
>
> * Handling [multi-root editor](../../examples/builds/multi-root-editor.md).
> * Handling [track changes suggestions preview](../collaboration/track-changes/track-changes.md#saving-the-data-with-suggestion-highlights).
> * [Adding a watermark](#adding-a-watermark-to-the-document) to the document.

<a id="export-to-pdf-v1-deprecated">

### Export to PDF V1 (deprecated)

> **Warning**
>
> Version 1 of the HTML to PDF converter API is deprecated. While it remains supported for backward compatibility, we strongly recommend migrating to V2, which is the default. Refer to the [migration guide from V1 to V2](https://pdf-converter.cke-cs.com/v2/convert/docs#section/Export-to-PDF-\(v2\)/Migration-guide-from-v1-to-v2) for details. To force V1, explicitly set `version: 1` in the `exportPdf` configuration.

The V1 API uses a flat configuration structure for `converterOptions`, unlike the nested structure in V2:

```js
{
	exportPdf: {
		version: 1, // Required to use V1
		converterOptions: {
			format: 'A4',
			margin_top: '0mm',
			margin_bottom: '0mm',
			margin_right: '0mm',
			margin_left: '0mm',
			page_orientation: 'portrait',
			header_html: '<div class="styled">Header content</div>',
			footer_html: '<div class="styled-counter"><span class="pageNumber"></span></div>',
			header_and_footer_css: '#header, #footer { background: hsl(0, 0%, 95%); } .styled { font-weight: bold; } .styled-counter { font-size: 1em; }',
			wait_for_network: true,
			wait_time: 0
		}
	}
}
```

For the complete list of V1 options, see the [V1 API documentation](../../api/module_export-pdf_exportpdf-ExportPdfConverterOptions.md) and the [V1 REST API documentation](https://pdf-converter.cke-cs.com/v1/convert/docs).

<a id="html-to-pdf-converter-features">

## HTML to PDF converter features

<a id="page-setup">

### Page setup

Configure the page size, orientation, and margins through the `document` object in `converterOptions`:

```js
converterOptions: {
	document: {
		size: 'A4',
		orientation: 'portrait',
		margins: {
			top: '20mm',
			bottom: '20mm',
			left: '15mm',
			right: '15mm'
		}
	}
}
```

The `size` property accepts predefined formats (`'A4'`, `'Letter'`, `'Legal'`, `'A3'`, etc.) or a custom object with `width` and `height`. For a complete example including matching editor CSS, see [Setting the page format](#setting-the-page-format).

```js
document: {
	size: { width: '210mm', height: '297mm' }
}
```

<a id="setting-the-base-url">

### Setting the base URL

To enable proper resolution of relative URLs for images and links, pass the `base_url` option:

```js
converterOptions: {
	base_url: 'https://example.com'
}
```

For editor content like:

```html
<p><a href="/">Homepage</a></p>
<p><img src="/logo.png" alt="Logo"></p>
```

this option will resolve the URLs into their absolute forms:

* `/` will become `https://example.com`,
* `/logo.png` will become `https://example.com/logo.png`.

<a id="images">

### Images

Currently, the converter only supports absolute URLs and `Base64`-encoded images. See the [REST API documentation](https://pdf-converter.cke-cs.com/v2/convert/docs) for details.

<a id="web-fonts">

### Web fonts

If you are using web fonts via an `@import` or `@font-face` declaration, you can pass the path(s) to the `.css` file(s) containing them to the [`config.exportPdf.stylesheets`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets). The order of the provided paths matters – you should list style sheets with web font declarations first. For more technical details, check the [API documentation](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md) and [REST API documentation](https://pdf-converter.cke-cs.com/v2/convert/docs).

<a id="rendering-options">

### Rendering options

Fine-tune how the converter renders the page before generating the PDF:

```js
converterOptions: {
	rendering: {
		wait_for_network: true,
		wait_time: 0,
		wait_for_selector: '.content-loaded'
	}
}
```

* `wait_for_network` – When `true`, the converter waits for all network requests to finish before rendering.
* `wait_time` – Additional wait time in milliseconds (0–15000) after the page loads.
* `wait_for_selector` – A CSS selector; the converter waits until an element matching this selector appears in the DOM.

<a id="headers-and-footers">

### Headers and footers

The converter lets you set the document’s header and footer similarly to Microsoft Word or Google Docs. Define a `default` header and footer applied to all pages:

```js
converterOptions: {
	document: {
		margins: {
			top: '15mm',
			bottom: '15mm',
			right: '15mm',
			left: '15mm'
		}
	},
	headers: {
		default: {
			html: '<div class="styled">Header content</div>',
			css: '#header { background: hsl(0, 0%, 95%); } .styled { font-weight: bold; text-align: center; }'
		}
	},
	footers: {
		default: {
			html: '<div class="styled-counter"><span class="pageNumber"></span></div>',
			css: '#footer { background: hsl(0, 0%, 95%); } .styled-counter { font-size: 1em; color: hsl(0, 0%, 60%); }'
		}
	}
}
```

> **Note**
>
> To ensure that the header or footer is displayed, the margin must be big enough to accommodate it. In the code above, `document.margins.top` corresponds with the header and `document.margins.bottom` – with the footer.

You can set a background for the header or footer using the `#header` or `#footer` selector in the `css` option. These wrapper elements are provided by the converter.

<a id="per-page-type-headers-and-footers">

#### Per-page-type headers and footers

You can define different headers and footers for the first page, odd pages, and even pages using the `first`, `odd`, and `even` keys. Each overrides the `default` for its respective pages:

```js
headers: {
	default: {
		html: '<div class="header">Company Name</div>',
		css: '.header { text-align: center; font-size: 10pt; }'
	},
	first: {
		html: '<div class="header-first">Report Title</div>',
		css: '.header-first { text-align: center; font-size: 14pt; font-weight: bold; }'
	},
	odd: {
		html: '<div class="header-odd">Section <span class="pageNumber"></span></div>',
		css: '.header-odd { text-align: right; }'
	},
	even: {
		html: '<div class="header-even"><span class="pageNumber"></span> Section</div>',
		css: '.header-even { text-align: left; }'
	}
}
```

The `footers` object follows the same structure. If a page type key is not defined, the `default` is used as a fallback.

As you can see in the examples above, you can use the `pageNumber` and `totalPages` placeholders. For more details, refer to the [REST API documentation](https://pdf-converter.cke-cs.com/v2/convert/docs).

If you import headers and footers from a Word document and want to preserve and reapply them when exporting, see the Import from Word guide’s [Preserving headers and footers](import-word/import-word.md#preserving-headers-and-footers). Note that when forwarding stored headers/footers into PDF export, you typically need to inject those header/footer converter options within the `execute` call of the `exportPdf` command. Hence, the converter receives them at export time.

<a id="mirror-margins">

### Mirror margins

Mirror margins (also known as “gutter” or “book” margins) are useful for documents intended for double-sided printing or binding. When `enable_mirror_margins` is set to `true`, the left and right margins swap between odd and even pages:

* **Odd pages (right-hand)**: `left` becomes the inner margin (near binding), `right` becomes the outer margin.
* **Even pages (left-hand)**: the margins are reversed – `right` becomes the inner margin, `left` becomes the outer margin.

```js
converterOptions: {
	document: {
		margins: {
			top: '20mm',
			bottom: '20mm',
			left: '25mm',
			right: '15mm',
			enable_mirror_margins: true
		}
	}
}
```

In this example, odd pages will have a 25 mm inner margin and 15 mm outer margin, while even pages will swap to 15 mm inner and 25 mm outer, creating a mirrored layout suitable for book binding.

> **Important**
>
> For mirror margins to work correctly, you must specify at least one of the `left` or `right` margins. If both are unset, the `enable_mirror_margins` option will have no effect.

<a id="document-metadata">

### Document metadata

Set PDF properties such as title, author, subject, keywords, and custom fields. PDF readers display this information in their document properties panel.

```js
converterOptions: {
	metadata: {
		title: 'Quarterly Report',
		author: 'Jane Smith',
		subject: 'Q1 2026 Financial Summary',
		keywords: [ 'finance', 'quarterly', 'report' ],
		custom_fields: {
			'Department': 'Marketing',
			'Document-ID': 'DOC-12345'
		}
	}
}
```

<a id="security-and-encryption">

### Security and encryption

Protect generated PDFs with an owner password. The owner password controls document permissions (printing, copying, modifying). The PDF is encrypted with AES-256 by default.

```js
converterOptions: {
	security: {
		owner_password: 'securePassword123'
	}
}
```

The `owner_password` is required when using this feature and must be between 6 and 64 characters.

<a id="digital-signatures">

### Digital signatures

Sign documents with PKCS#12 certificates to verify authenticity. The signature is embedded invisibly in the PDF metadata – it does not add visual elements to the document pages. PDF readers will show signature details in their signature panel.

```js
converterOptions: {
	signature: {
		certificate: 'base64EncodedPKCS12Certificate',
		certificate_password: 'certificatePassword',
		reason: 'Document approval',
		location: 'New York, USA'
	}
}
```

Both `certificate` (base64-encoded `.p12`/`.pfx` file) and `certificate_password` are required. The `reason` and `location` fields are optional metadata.

> **Note**
>
> PEM certificates are not supported. Convert to PKCS#12 (`.p12`/`.pfx`) format before use.

<a id="compression-control">

### Compression control

By default, the converter compresses PDF output for smaller file sizes. You can disable compression to preserve the original PDF structure:

```js
converterOptions: {
	disable_compression: true
}
```

<a id="other">

### Other

* By default, the generated PDF file is encoded with **`UTF-8`**.
* By default, the converter sets **`color-adjust: exact;`**. This means that your PDF document will preserve colors, images, and styles as you can see them in the editor.
* The generated document can be watermarked. [See the example and demo in the section below.](#adding-a-watermark-to-the-document)

<a id="examples">

## Examples

Check out some configuration examples that will show you how to customize the export to PDF feature. In the first example, you will learn how to add custom styling. The second example will show you how to set the page format. In the third one, you can see how to use web fonts in your configuration.

<a id="re-using-custom-editor-styling">

### Re-using custom editor styling

The default configuration of the [`ExportPdf`](../../api/module_export-pdf_exportpdf-ExportPdf.md) plugin attaches the default editor content styles to the HTML content sent to the converter.

However, if you need to, you can also set paths to additional CSS files. Let us assume that you already have a `my-custom-editor-styles.css` with your custom styling for the editor content that you use on your website, but you also want to include these styles in the generated PDF file.

Here is the example code:

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		exportPdf: {
			stylesheets: [
				'path/to/editor-styles.css',
				'path/to/my-styles.css'
			],
			fileName: 'my-document.pdf'
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

This is how the corresponding editor styles may look like:

```css
/* my-custom-editor-styles.css */

/* Custom link color. */
.ck.ck-content a {
	color: purple;
}

/* Custom header styling. */
.ck.ck-content h1 {
	border-bottom: 2px solid;
}

/* Another custom styling... */
/* ... */
```

With these settings, the content in the generated PDF file should have the same styling as it has in the WYSIWYG editor.

> **Note**
>
> You are not obligated to use `.ck.ck-content` selectors to style your content. If your implementation contains custom CSS classes, you can use them instead.

<a id="setting-the-page-format">

### Setting the page format

Consistency is an important factor. To make sure that the editor content and the generated PDF file look the same, you need to match their format settings. You can change your existing style sheet or use a new one, for example, `format.css`. By default, the CKEditor Cloud Services HTML to PDF converter is set to A4 format, but you may change this setting in your configuration.

Assuming that you want to create a document in the US Letter format, with the standard margins (`19mm` for each side), here is the example code you can use:

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		exportPdf: {
			stylesheets: [
				'path/to/editor-styles.css',
				'path/to/my-styles.css'
			],
			fileName: 'my-document.pdf',
			converterOptions: {
				document: {
					// Document format settings with proper margins.
					size: 'Letter',
					orientation: 'portrait',
					margins: {
						top: '19mm',
						bottom: '19mm',
						right: '19mm',
						left: '19mm'
					}
				}
			}
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

> **Note**
>
> This example focuses only on preparing the editable to match the converter settings. As a result, the appearance of your editor may change. Depending on your editor type and implementation or even some inherited global styles like `box-sizing`, applying new `padding` values may change the size of the editor on your website.
>
> For this example, `box-sizing: border-box` was implemented to make sure that the editor’s width would not change.

Now set the corresponding editor styles:

```css
/* format.css */

/* Styles for the editable. */
.ck.ck-content.ck-editor__editable {
	/* US Letter size. */
	width: 215.9mm;
	/* Padding is your document's margin. */
	padding: 19mm;
	/* You do not want to change the size of the editor by applying the new padding values. */
	box-sizing: border-box;
	/* ... */
}
```

With these settings, the content in the generated PDF file should have the same US Letter format layout as it has in the editor.

<a id="providing-web-font-styles">

### Providing web font styles

This time you want to add a web font to your plugin. Let us assume that the editor is used on a page with certain typography, so the content in the editor inherits the font styles from the page. As such, these styles need to be passed to the HTML to PDF converter service.

The example below uses a web font from the Google Fonts service. For your convenience, the `@import` declaration and any font styles needed for your website are kept in a separate file, for example, `fonts.css`.

```css
/* fonts.css */

@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;700&display=swap');

html, body {
	font-family: "Source Sans Pro", sans-serif;
	/* ... */
}

/* ... */
```

This allows you to use the web font settings in the plugin, without any additional tweaks. Just pass the path to the file in the [`config.exportPdf.stylesheets`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets) configuration option.

The order matters here. Font declarations should be at the beginning of the style sheets’ array. Otherwise, there is no guarantee that the font styling will be applied to the PDF file. Refer to the [`config.exportPdf.stylesheets`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets) API documentation for more details.

```js
ClassicEditor
	.create( {
		// ... Other configuration options ...
		exportPdf: {
			stylesheets: [
				'path/to/fonts.css',
				'path/to/editor-styles.css',
				'path/to/my-styles.css'
			],
			// More configuration of the export to PDF feature.
			// ...
		}
	} )
	.then( /* ... */ )
	.catch( /* ... */ );
```

Thanks to this, the editor inherits the font settings and you can be sure that they will be applied in the generated PDF file as well.

Take a look at another example of a `fonts.css` file. Suppose that your website uses the `Source Sans Pro` font as before but this time you want the `Inter` font to be used in the WYSIWYG editor. The file should look like this:

```css
/* fonts.css */

/* Import the web font for your website. */
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;700&display=swap');
/* Import the web font for your editor. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');

/* Use the Source Sans Pro web font in your website. */
html, body {
	font-family: "Source Sans Pro", sans-serif;
	/* ... */
}

/* Use the Inter web font in your editor. */
.ck.ck-content.ck-editor__editable {
	font-family: "Inter", sans-serif;
	/* ... */
}

/* ... */
```

Having the file set like this for your website and just re-using it in [`config.exportPdf.stylesheets`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-stylesheets) makes the whole setup as simple as possible.

<a id="adding-a-watermark-to-the-document">

### Adding a watermark to the document

Apart from adding a header and a footer, there is also the possibility of adding a watermark to the generated document. This can be achieved by utilizing [`config.exportPdf.dataCallback`](../../api/module_export-pdf_exportpdf-ExportPdfConfig.md#member-dataCallback).

To do this, you need to get the data that is being sent to the converter first and update it with a watermark markup:

```js
exportPdf: {
	// More configuration of the export to PDF.
	// ...
	dataCallback: ( editor ) => {
		return `
			${ editor.getData() }
			<div class="watermark">Draft document</div>
		`;
	},
	// More configuration of the export to PDF.
	// ...
}
```

Then [update the custom CSS file](#re-using-custom-editor-styling) with the proper styles:

```css
.watermark {
	font-size: 50px;
	opacity: 0.5;
	color: black;
	position: fixed;
	left: 20%;
	top: 50%;
	transform: rotate(25deg);
	letter-spacing: 10px
}
```

Below you can see a simplified demo with the final result. Click the toolbar button to generate the document with a watermark.

<!-- AI-AGENT-NOTE: An interactive demo is embedded here but is not represented in this Markdown file. If you need to see it in action, open this page in a browser (e.g. via a browser-automation MCP like Chrome DevTools or Playwright), or let the user know a live demo is available on this page. -->

---

Full index of the CKEditor 5 documentation: [llms.txt](../../../llms.txt)
