This plugin adds features that give admin users the ability to download or create export data as an upload collection and import it back into a project.
Install the plugin using any JavaScript package manager like pnpm, npm, or Yarn:
In the plugins array of your Payload Config, call the plugin with options:
Property | Type | Description |
|---|---|---|
| array | Collections to include Import/Export controls in. Array of collection configs with per-collection options. Defaults to all. |
| boolean | If true, enables debug logging. |
| function | Function to override the default export collection. Receives |
| function | Function to override the default import collection. Receives |
Each item in the collections array can have the following properties:
Property | Type | Description |
|---|---|---|
| string | The collection slug to configure. |
| boolean \ | ExportConfig | Set to |
| boolean \ | ImportConfig | Set to |
Property | Type | Description |
|---|---|---|
| number | Documents per batch during export. Default: |
| boolean | Disable download button for this collection. |
| boolean | Run exports synchronously for this collection. |
| boolean | Disable save button for this collection. |
| string | Force format ( |
| function | Override the export collection config for this specific target. |
Property | Type | Description |
|---|---|---|
| number | Documents per batch during import. Default: |
| string | Default status for imported docs ( |
| boolean | Run imports synchronously for this collection. |
| function | Override the import collection config for this specific target. |
By default, the plugin creates a single exports collection and a single imports collection that handle all import/export operations across your enabled collections. However, you can create separate import and export targets for specific collections by overriding the collection slug.
When you change the slug using the overrideCollection function at the per-collection level, this creates an entirely separate uploads collection for that specific source collection. This is useful when you need:
In this example:
user-exports collection with restricted accessuser-imports collectionexports and imports collectionsYou can combine the top-level overrideExportCollection / overrideImportCollection functions with per-collection overrides. The top-level override is applied first, then the per-collection override:
In addition to the above plugin configuration options, you can granularly set the following field level options using the custom['plugin-import-export'] properties in any of your collections.
Property | Type | Description |
|---|---|---|
| boolean | When |
| function | Custom function used to modify the outgoing CSV data by manipulating the data, siblingData or by returning the desired value. |
| function | Custom function used to transform incoming CSV data during import. |
To completely exclude a field from import and export operations:
When a field is disabled:
To manipulate the data that a field exports, you can add toCSV custom functions. This allows you to modify the outgoing CSV data by manipulating the row object or by returning the desired value.
The toCSV function receives an object with the following properties:
Property | Type | Description |
|---|---|---|
| string | The CSV column name given to the field. |
| object | The top level document. |
| object | The object data that can be manipulated to assign data to the CSV |
| object | The document data at the level where it belongs. |
| unknown | The data for the field. |
Example - splitting a relationship into multiple columns:
To transform data during import, add fromCSV custom functions. This allows you to transform incoming CSV data before it's saved to the database.
The fromCSV function receives an object with the following properties:
Property | Type | Description |
|---|---|---|
| string | The CSV column name for the field. |
| object | The full document data being built. |
| object | The data at the sibling level of the field. |
| unknown | The raw CSV value for the field. |
Return values:
undefined to skip setting the field (keeps existing value)null to explicitly set the field to nullExample - reconstructing a relationship from split columns:
Virtual fields (fields with virtual: true) are handled differently during import and export:
There are four possible ways that the plugin allows for exporting documents, the first two are available in the admin UI from the list view of a collection:
POST to /api/exports/download and streams the response as a file downloadexports collection as an uploads enabled collectionpayload.create({ slug: 'uploads', ...parameters })payload.jobs.queue({ task: 'createCollectionExport', input: parameters })By default, a user can use the Export drawer to create a file download by choosing Save or stream a downloadable file directly without persisting it by using the Download button. Either option can be disabled to provide the export experience you desire for your use-case.
The UI for creating exports provides options so that users can be selective about which documents to include and also which columns or fields to include.
When opening the export drawer from a collection's list view, you can choose which documents to export:
Mode | Description |
|---|---|
Use all documents | Export the entire collection (respects any limit you set) |
Use current filters | Export only documents matching your active list view filters |
Use current selection | Export only the documents you've checked in the list view |
It is necessary to add access control to the uploads collection configuration using the overrideExportCollection function if you have enabled this plugin on collections with data that some authenticated users should not have access to.
The following parameters are used by the export function to handle requests:
Property | Type | Description |
|---|---|---|
| string | Either |
| number | The max number of documents to export. Leave empty to export all matching documents. |
| number | The page of documents to start from (used with limit for pagination). |
| string | The field to use for ordering documents (e.g., |
| number | How deeply to populate relationships. Default: |
| string | The locale code to query documents or |
| boolean | When |
| string[] | Which collection fields to include in the export. Defaults to all fields. |
| string | The collection slug to export from. |
| object | The WhereObject used to query documents to export. This is set by making selections or filters from the list view |
| string | The name for the exported file (without extension). |
The plugin allows importing data from CSV or JSON files. There are several ways to import:
imports collection with an uploaded filepayload.create({ collection: 'imports', data: { collectionSlug: 'pages', importMode: 'create' }, file: { ... } })payload.jobs.queue({ task: 'createCollectionImport', input: parameters })Property | Type | Description |
|---|---|---|
| string | The collection to import into. |
| string | |
| string | The field to use for matching existing documents during |
| string | The locale to use for localized fields. |
The matchField option allows you to match documents by a field other than id. For example, if importing users, you could match by email instead of id:
Mode | Description |
|---|---|
create | Only creates new documents. Documents with existing IDs will fail. |
update | Only updates existing documents. Requires |
upsert | Creates new documents or updates existing ones based on |
After an import completes, the import document is updated with a summary:
Property | Type | Description |
|---|---|---|
| string | |
| number | Total number of rows processed |
| number | Number of successfully imported documents |
| number | Number of updated documents (update/upsert modes) |
| number | Number of rows that failed |
| array | Details about each failure |
CSV columns use underscore (_) notation to represent nested fields:
Field Path | CSV Column Name |
|---|---|
| |
| |
| |
| |
| |
For relationship fields, the column format varies based on the relationship type:
Relationship Type | Column(s) |
|---|---|
hasOne (monomorphic) | |
hasOne (polymorphic) | |
hasMany (monomorphic) | |
hasMany (polymorphic) | |
During CSV import, certain values are automatically converted:
CSV Value | Converted To | Notes |
|---|---|---|
| | Case-insensitive |
| | Case-insensitive |
| | Use |
Empty string | | Depends on field type |
Numeric strings | | Auto-detected for integers and floats |
To preserve literal strings like "null" or "true", use a fromCSV function:
When exporting with a specific locale selected, localized fields appear without a locale suffix:
When exporting with locale set to all, each localized field gets a column per configured locale:
For single-locale import, data goes into the locale specified in the import settings:
For multi-locale import, use locale suffixes in column names to import multiple locales at once:
When using JSON format for import/export:
JSON format preserves the exact structure of your data, including:
Example JSON export: