Data Import & Export
Overview
Section titled “Overview”Rebase includes built-in data import and export tools accessible directly from the admin panel. Import supports CSV, JSON, and Excel files with a column-mapping wizard. Export supports CSV and JSON with optional computed fields.
Both are available on every collection. Export can be configured per collection with computed fields, or switched off with exportable: false; import cannot be switched off per collection.
Importing Data
Section titled “Importing Data”How to Import
Section titled “How to Import”- Open a collection in the admin panel
- Click the Import button in the toolbar
- Select or drag-and-drop your file
- Map file columns to collection properties
- Preview the data, including any values that cannot be converted
- Click Save data to write the rows
Supported Formats
Section titled “Supported Formats”| Format | Extensions | Notes |
|---|---|---|
| CSV | .csv |
Auto-detects delimiters |
| JSON | .json |
Expects an array of objects |
| Excel | .xlsx |
Reads the first sheet |
Column Mapping
Section titled “Column Mapping”The import wizard automatically attempts to match file columns to collection properties by name. You can manually adjust mappings before importing:
- Exact matches are mapped automatically (e.g.
name→name) - Unmatched columns can be mapped manually or skipped
- Type conversion turns each cell into the type of the property it maps to, but only when nothing is lost (see below)
Type conversion
Section titled “Type conversion”A cell is converted only when the property’s type can hold exactly what it says:
| Property type | Converts | Does not convert |
|---|---|---|
| Number | 12, -3.5, 10.00, 1e3 |
02134 (a leading zero would be lost), numbers with more than 15 significant digits, 1,234, $5.00, 12%, N/A |
| Boolean | true/false, yes/no, y/n, 1/0, in any case |
anything else |
| Date | ISO 8601 (2024-01-05, 2024-01-05T10:00:00Z), written-out dates (5 Jan 2024), 05/01/2024, epoch seconds or milliseconds |
text that names no date |
| Geopoint | the object the export writes, {"latitude": 41.9, "longitude": 12.5}, or its JSON in a CSV cell |
anything else, or a coordinate out of range |
| Map without declared fields | an object, or its JSON in a CSV cell | anything else |
| Vector | a list of numbers ([0.1, 0.2], 0.1, 0.2), or the export’s {"value": [0.1, 0.2]} |
a list holding anything that is not a number |
A date without a time is that day in UTC. For dates written as 05/01/2024, the column decides the order: a first number above 12 makes the column day-first, a second number above 12 makes it month-first. When a column never says, the browser’s locale decides, and when it holds both orders, a date that either order could read is not converted.
A blank cell is no value: it sets nothing, and the default you chose for that property applies.
A file exported from a collection imports back into the same values, CSV or JSON. A map with declared fields is read one column per field (address.street), as the export writes it; any other value, a geopoint or a key-value map included, is one column. An epoch number between -100,000,000,000 and 100,000,000,000 is read as seconds, so a date between 31 October 1966 and 3 March 1973 exported as a timestamp does not come back: export those dates as text. A time-of-day field reads a number below one day (86,400,000) as the milliseconds since midnight the export writes.
Values that cannot be imported
Section titled “Values that cannot be imported”The preview lists every cell that does not convert, per column, with how many there are and the first few by row and reason. Those cells are left empty in the imported rows; nothing is turned into 0, false or an empty value without being listed. Go back to map the column to another property, or correct the file and upload it again.
The collection’s own rules — required fields, enum options, unique values — are checked by the server as the rows are written, in batches of up to 500 rows (fewer when the rows are wide, so a request stays under about 1 MB). A batch is saved whole or not at all. If a row is refused, the import stops and names it; the batches before it are already saved, and Retry resumes from the first row of the refused row’s batch.
A row whose id is already in the collection updates that record: the columns the file carries are written, and the others keep their stored values, so a file of id,price reprices existing products without repeating their required fields. A new row still needs every required field. A batch that mixes updates and new rows is written as two requests, so a refused new row can leave that batch’s updates saved; Retry writes them again with the same values.
Importing users
Section titled “Importing users”A new row in the users collection is a user creation: a password column is hashed, never stored as written, and a row without one gets a generated password or an invitation, as when an administrator adds a user. The passwords in such a file were usually set under another system’s rules, so the import asks the server to skip the password policy for those rows. The server agrees only when you are an administrator; anyone else importing users is held to the policy, and a weak password stops the import with WEAK_PASSWORD.
Creating a collection from a file
Section titled “Creating a collection from a file”When you create a collection from a file, each column’s type is inferred from its values. A column is a number only if every value in it is a number or text that converts to one exactly, so a column of zip codes, product codes with leading zeros, long SKUs or phone numbers stays text. A column that mixes types (numbers and words, booleans and numbers) is text. Blank cells do not count, so a mostly empty column is not marked required. A column of whole numbers whose name ends in a word that says it holds a moment (created_at, updatedAt, signup_date, timestamp) is a date when every value is an epoch timestamp of 2001–2103, in seconds or milliseconds; under any other name, or with any other value, it stays a number.
Import Configuration
Section titled “Import Configuration”Import is available on every collection. There is no per-collection setting that turns it off.
Exporting Data
Section titled “Exporting Data”How to Export
Section titled “How to Export”- Open a collection in the admin panel
- Optionally apply filters to export a subset of data
- Click the Export button in the toolbar
- Choose the format: CSV or JSON
- The file downloads immediately
Export Formats
Section titled “Export Formats”| Format | Description |
|---|---|
| CSV | Comma-separated values, compatible with Excel and Google Sheets |
| JSON | Array of objects, useful for programmatic consumption |
Filtering Before Export
Section titled “Filtering Before Export”Any active filters in the collection view are applied to the export. This lets you export only a subset of your data:
- Apply column filters or search terms in the collection view
- Click Export — only the filtered rows are included
Export Configuration
Section titled “Export Configuration”Export is available on every collection unless you turn it off. admin.exportable
configures it: exportable: false removes the Export button, and an
ExportConfig keeps it and adds computed columns, below.
Adding Computed Fields
Section titled “Adding Computed Fields”Use the ExportConfig object to add custom computed columns to your exports. These columns don’t exist in the database — they are calculated at export time:
import { defineCollection } from "@rebasepro/cms-types";
const productsCollection = defineCollection({ slug: "products", table: "products", name: "Products", properties: { /* ... */ }, admin: { exportable: { additionalFields: [ { key: "computed_margin", builder: ({ entity }) => { const price = entity.values.price as number; const cost = entity.values.cost as number; return String(price - cost); } }, { key: "full_url", builder: ({ entity }) => { return `https://mystore.com/products/${entity.id}`; } } ] } }});Each additionalFields entry has:
| Property | Type | Description |
|---|---|---|
key |
string |
Column name in the export |
builder |
({ entity, context }) => string | Promise<string> |
Function that computes the value |
The builder function receives the current entity and the RebaseContext (which includes the authenticated user), so you can compute values based on both data and permissions.
Async Computed Fields
Section titled “Async Computed Fields”The builder function can be async, which is useful when the computed value requires a database lookup or API call:
exportable: { additionalFields: [ { key: "author_name", builder: async ({ entity, context }) => { const author = await context.data.users.findById( entity.values.authorId as string ); return author?.values.displayName ?? "Unknown"; } } ]}Next Steps
Section titled “Next Steps”- Collections — Define your data model
- Frontend Overview — Admin panel and UI components
- Typed SDK — Programmatic data access