Data import and export

Download a JSON copy of your content, users, audience, settings and email data, and a ZIP of your media files, then load them back into the same install or a new one.

What it is

The Data admin menu has four screens:

ScreenAddressDoes
Export Data/admin/data/export-dataDownloads chosen Firestore collections as one JSON file
Import Data/admin/data/import-dataWrites the collections of such a file back into Firestore
Export Files/admin/data/export-filesDownloads media library images and files as a ZIP with a manifest
Import Files/admin/data/import-filesUploads files to Storage and adds them to the media library; documents go to its Files

Everything runs in the admin's browser, with the admin's own permissions. There are no Cloud Functions involved.

For creating content entries from a spreadsheet, use the content type's Bulk Import instead (Content). For contacts from a CSV, see Audience.

Turn it on or off

Data import and export is a switchable feature with the id data. It is on by default and needs no other feature. To turn it off, list it in src/custom/features.ts:

export const CUSTOM_FEATURES: FeatureChoice = {
    off: ['data'],
};

When it is off, the Data menu goes and its addresses show the not-found page. Nothing is stored by this feature, so nothing is left behind. See Feature ids.

Set it up

Nothing to set up. The screens need an admin account and the deployed security rules.

Use it

Export data

  1. Open Data > Export Data.

  2. Pick a preset (Everything, All Content, All Settings) or tick collections by group. Picking a content type takes its drafts, its published entries and its tags together.

  3. Export. The browser downloads arccms-export-{date}.json.

GroupCollections
ContentContentTypes, and per type arc_{slug}_drafts, arc_{slug}, Tags_{slug}
Users and waitlistsusers, Waitlists with each form's users, WaitlistedUsers
AudienceContacts, Lists, ContactTags, Suppression
Settings and mediaSettings, media (the records, not the files)
EmailEmailTemplate, BroadcastEmails, EmailLogs

Collections of a feature that is off are not offered. Nothing else is exported: not Authors, not content translations or version history, not payments, feedback or notification data.

An export holds personal data (users, contacts with their consent state) and secrets (the Settings documents carry email provider passwords and API keys). Store the file as you would a database backup.

The file format

{
  "version": "1.0",
  "exportedAt": "2026-09-30T10:00:00.000Z",
  "collections": {
    "ContentTypes": { "articles": { "name": "Articles", "slug": "articles" } },
    "Waitlists/waitlist/users": { "abc123": { "email": "a@example.com" } }
  },
  "metadata": { "totalDocuments": 2, "collectionSummary": [ { "name": "ContentTypes", "count": 1 } ] }
}

Keys under collections are collection paths, then document ids. Firestore timestamps, document references and geo points are written as objects with a __type of timestamp, ref or geopoint, and turned back into those types on import.

Import data

  1. Open Data > Import Data and choose an export file. It is checked for a version and a collections object; unknown collections are flagged but can still be imported.

  2. Tick the collections to import.

  3. Choose what happens to a document that already exists:

    ModeExisting document
    Skip existing (default)Left as it is
    OverwriteReplaced by the file's version
    MergeThe file's fields are written over it; other fields stay
  4. Import. Document ids are kept. Collections go in a fixed order so that what others refer to comes first: content types and settings, then tags, users, drafts and published entries, media records and email templates, then signup forms, audience, broadcasts and email logs. Writes go in batches of 500. A content type whose slug another type on the site (or earlier in the file) already uses is not imported, and the result lists it as an error: the same type, with the same document id, is imported as usual. A type already on the site, by document id, whose slug in the file differs (or is missing, when existing documents are overwritten) is not imported either while entries, drafts or tags are stored under its current slug, since they would be left behind; the edit form locks the slug for the same reason. To restore a type over one the setup wizard created, such as Articles, delete the wizard's type first, then import.

Importing published entries restores the data, not the pages. Rebuild the pages on Hosting after an import with npm run seed:dev (or npm run seed:prod); see How publishing works.

Contacts and Suppression can only be written by Cloud Functions, so importing them fails with a permission error even for an admin. Rebuild an audience with the contact CSV import on the Audience page.

Importing users into another Firebase project creates the records but not the sign-in accounts, so those people cannot sign in until their accounts exist again. See Users and roles.

Export files

Data > Export Files lists the media library: its images, then its files (PDFs and other documents, shown with their first page or an icon). Select items and download arccms-media-{date}.zip: one file per item (the largest stored size of an image) and media-manifest.json with each item's name, URL, Storage path and upload time, its title, alt text and notes when it has them, and "collection": "mediaFiles" for a file.

Import files

Data > Import Files has two modes:

ModeDoes
Upload new files (recommended)Choose files and a Storage path prefix (default mediaImages/). Each file is uploaded under it. A document the library takes (PDF, Word, Excel, PowerPoint, CSV, text) goes to the library's Files instead, whatever the prefix, stored the way the Files tab stores it, with a fresh first-page picture for a PDF.
Restore from manifestChoose a media-manifest.json and the files. Files are matched by the name in the manifest and uploaded to the path it records, with the title, alt text and notes it carries. A library file goes back to Files with its title and notes.

With Update media collection metadata ticked (the default), each uploaded file also gets a new media record (a mediaFiles record for a document), with a new id. Unzip the export first: the screen takes files, not the ZIP. Imported files are stored as they are, at one size.

Content stores full image URLs. After moving to another project, entries still point at the old project's Storage, so images keep working only while the old files exist. Re-pick the images in the editor if the old project goes away.

Extend it

The exported collections are listed in KNOWN_COLLECTIONS in src/app/pages/admin/(data)/data-constants.ts, a core file. An app's own collections are not exported; back them up with your own tooling, or say so as a core feature request (Keep core generic).

What it stores

Nothing of its own. Export reads the collections above; import writes them, plus Storage files and media records (downloadURL, name, storagePath, uploadTime) for imported files. There are no Cloud Functions. Collection details are in Data model.

Who can do what

The Data screens are admin only. Every read and write is the admin's own, so each collection's security rules apply as usual: an admin can read and write everything offered except Contacts and Suppression, which admins can read but only Cloud Functions write. Storage uploads need an admin (or the reserved editor role). See Security rules.

Troubleshooting

SymptomCause and fix
Invalid JSON file or Missing "version" fieldThe file is not an Arc CMS export. Use a file from Export Data, unedited.
Some documents report "Missing or insufficient permissions"The collection is written only by Cloud Functions (Contacts, Suppression), or the rules are not deployed. A failure fails its whole batch of up to 500 documents.
Imported entries are not on the siteRun the seed to rebuild the pages.
Nothing is skipped although documents existMerge or Overwrite was chosen. Skip existing is the only mode that leaves them alone.
Restore from manifest uploads nothingNo chosen file has the exact name the manifest records; files in the export ZIP can carry an extra extension (photo-xl.webp.webp). Use Upload mode instead.
A large export stallsThe whole file is built in the browser's memory. Export one group at a time.