Search Docs
Loading...
Skip to content

Export Print-Ready PDF/X Files

Export a CE.SDK design as PDF/X with the independently versioned @imgly/pdfx-exporter package. Choose PDF/X-1a, PDF/X-3 or PDF/X-4, apply your printer’s ICC profile and check the result before downloading it.

10 mins
estimated time
Download
StackBlitz
GitHub

Use exportPDFX when you have a running CE.SDK engine. It exports the selected blocks, converts their colors and combines them into one PDF/X file. Use convertToPDFX for a PDF Blob you already have.

This guide covers engine export, conformance checks, existing PDF conversion, ICC profiles and bleed limits.

Install the Exporter#

Install CE.SDK and the exporter. The exporter releases independently from CE.SDK:

Terminal window
npm install @cesdk/cesdk-js@1.84.0 @imgly/pdfx-exporter@^0.1.0

The exporter requires WebAssembly SIMD. Use a current Chrome, Firefox or Edge, or Safari 16.4 or later. This Safari requirement is higher than CE.SDK’s own minimum.

The WebAssembly module loads on first conversion. When serving the package directly, keep its dist/ and wasm/ directories beside each other. The example’s Vite configuration copies the required module into the production build. Deploy the complete build output and allow your application to fetch the module.

Initialize CE.SDK#

Import the public editor and exporter APIs:

import CreativeEditorSDK from '@cesdk/cesdk-js';
import { checkPDFX, convertToPDFX, exportPDFX } from '@imgly/pdfx-exporter';
import type { PDFXStandard } from '@imgly/pdfx-exporter';

Create the editor in your container. The downloadable example also includes a design-editor configuration and asset sources.

const cesdk = await CreativeEditorSDK.create('#cesdk-container', {
// license: 'YOUR_CESDK_LICENSE_KEY',
baseURL: import.meta.env.VITE_IMGLY_LOCAL_ASSETS_URL
});

The example sets millimeter units, 300 DPI and 3 mm page margins:

engine.scene.setDesignUnit('Millimeter');
engine.block.setFloat(scene, 'scene/dpi', 300);
engine.block.setWidth(page, 148);
engine.block.setHeight(page, 105);
engine.block.setBool(page, 'page/marginEnabled', true);
for (const side of ['top', 'bottom', 'left', 'right']) {
engine.block.setFloat(page, `page/margin/${side}`, 3);
}

It adds buttons for all three supported standards:

cesdk.ui.insertOrderComponent(
{ in: 'ly.img.navigation.bar', position: 'end' },
{
id: 'ly.img.actions.navigationBar',
children: (['PDF/X-4', 'PDF/X-3', 'PDF/X-1a'] as const).map(
(standard) => ({
key: `export-${standard}`,
id: 'ly.img.action.navigationBar',
label: `Export ${standard}`,
iconName: '@imgly/Download',
onClick: () => exportPrintReadyPDF(cesdk, standard)
})
)
}
);

Export from the Engine#

Pass the running engine and the printer’s output profile to exportPDFX. The example uses the selected standard with FOGRA39 and rejects profiles that do not describe a printing condition:

const printReadyPDF = await exportPDFX(cesdk.engine, {
outputStandard: standard,
outputProfile: 'fogra39',
nonPrinterProfile: 'reject',
title: 'Print-Ready Export'
});

Without blocks, the exporter includes every page in the current scene. Pass blocks: [pageId, otherPageId] to choose pages and their order. A group, image or text block becomes one output page at its own size. Scene and stack blocks expand to their pages.

For CMYK profiles, the exporter enables the engine’s DeviceCMYK export so existing CMYK and spot colors avoid an RGB round trip. High compatibility export is enabled by default. Pass engine options through exportOptions when you need a different setting, such as exportOptions: { exportPdfWithHighCompatibility: false }.

Check PDF/X Conformance#

Check against the same standard you selected for export:

const findings = await checkPDFX(printReadyPDF, standard);
if (findings.length > 0) {
throw new Error(
findings.map(({ rule, message }) => `${rule}: ${message}`).join('\n')
);
}

checkPDFX returns an array of findings. Each finding has rule, message and object; the object is a PDF object reference or null. An empty array means the checker found no violations of the selected PDF/X rules. Keep the findings available for your export error handling and complete your printer’s required preflight checks.

Download the File#

The exporter returns a PDF Blob. Create a download URL and release it after the download starts:

const url = URL.createObjectURL(printReadyPDF);
try {
const link = document.createElement('a');
link.href = url;
link.download = `design-${standard.replace('/', '-')}.pdf`;
link.click();
} finally {
URL.revokeObjectURL(url);
}

Convert an Existing PDF#

Pass an existing PDF Blob to convertToPDFX:

export async function convertExistingPDF(pdfBlob: Blob) {
return convertToPDFX(pdfBlob, {
outputStandard: 'PDF/X-4',
outputProfile: 'fogra39',
nonPrinterProfile: 'reject'
});
}

An array of PDF Blobs returns an array of converted Blobs in the same order. This path has no access to your scene’s page margins. Use exportPDFX when the exporter must derive bleed from CE.SDK pages.

Choose the PDF/X Standard#

Use the standard your printer requires:

outputStandard Transparency Color requirements
'PDF/X-4' (default) Keeps live transparency Use a printer ICC profile for compliant output
'PDF/X-3' Flattens by default Use a printer ICC profile for compliant output
'PDF/X-1a' Always flattens Allows CMYK and spot colors; rejects sRGB

flattenResolution controls the rasterization resolution for flattened pages and defaults to 300 DPI. Disabling flattenTransparency for PDF/X-3 can produce a noncompliant file when transparency remains. PDF/X-4 ignores that option; PDF/X-1a always flattens.

Choose an ICC Profile#

The required outputProfile accepts fogra39, gracol, srgb or custom. Use the profile requested by your printer. FOGRA39 and GRACoL 2013 are bundled CMYK printer profiles.

sRGB is a display profile, so output with outputProfile: 'srgb' is never PDF/X compliant. The default nonPrinterProfile: 'keep' still produces the file; checkPDFX reports 6.2.3 dest-profile-class. Set nonPrinterProfile: 'reject' to fail conversion for display, input or other non-printer profiles. PDF/X-1a rejects sRGB regardless of this setting.

For a custom profile, load the ICC file as a Blob and provide its printing condition:

import { exportPDFX } from '@imgly/pdfx-exporter';
const response = await fetch('/profiles/printer.icc');
if (!response.ok) {
throw new Error('Could not load the printer ICC profile.');
}
const customProfile = await response.blob();
const printReadyPDF = await exportPDFX(cesdk.engine, {
outputStandard: 'PDF/X-4',
outputProfile: 'custom',
customProfile,
nonPrinterProfile: 'reject',
outputConditionIdentifier: 'PrinterCondition',
outputCondition: 'Printing condition supplied by the printer'
});

An ICC file must have device class prtr to describe a printing condition. Use a CMYK printer profile for PDF/X-1a.

The exporter embeds the ICC profile by default. Setting embedICCProfile: false leaves the file without the embedded output intent required for PDF/X. The result is not a compliant PDF/X file; use that option only when a downstream prepress tool adds the final profile and metadata.

Bleed and Printer’s Marks#

exportPDFX reads page/marginEnabled and the four page/margin/* values in the scene’s design unit. For pages with bleed, it creates a temporary enlarged copy so artwork extending past the trim reaches the output. MediaBox and BleedBox contain the page plus bleed; TrimBox contains the trimmed page. Pages without bleed and non-page blocks use TrimBox equal to MediaBox.

The temporary copy is removed after export, including when export fails. Direct children use their current frames, and a page’s own background fill stretches across the bleed. The engine rounds dimensions to device pixels, so the trim can differ by up to 0.5 points at 300 DPI.

Crop and registration marks require CE.SDK 1.83 or later. Pass them in exportOptions only for pages without bleed. Combining marks with bleed throws an error because marks enlarge the MediaBox. Keep a CMYK printer profile when using registration marks.

See Export for Printing for page margins, DPI and underlayers, and Export to PDF for engine export options.

Migrate an Existing Integration#

Replace the old package dependency with @imgly/pdfx-exporter and update your imports. Existing convertToPDFX integrations can keep their supported conversion options; engine integrations can use exportPDFX to include page bleed.

Version 0.1.0 does not accept runtime, signal, timeoutMs, maxOutputBytes or custom converter command arguments. Remove the old conversion runtime and worker asset setup from this integration. An exportOptions.abortSignal controls the engine export step only; it does not cancel the conversion step.