Tables

Import and export

Both menus ship on, both are configurable, and both run in the browser until you point them somewhere else.

It is already there

A RecordView toolbar carries Import and Export by default. Export writes CSV, JSON or Excel from what is on screen; Import reads the same formats back. Turn either off with showImport or showExport.

What gets exported

The rows the table is currently showing, after search, filters and sorting, and the columns it is currently showing. That is usually what somebody clicking Export wants, and it is occasionally not: a filtered table exports the filtered set, never the database.

Change what the menus offer

exportActions and importActions take an array to replace the shipped entries, or a function that receives them so you can add to them.

add a server export, keep the rest
<RecordView<Customer>
  fields={CUSTOMER_FIELDS}
  exportActions={(shipped) => [
    ...shipped,
    {
      id: "server-csv",
      label: "Everything (CSV)",
      // ctx.query carries the current search, filters and sort, so the server can
      // answer for the whole result set rather than the page on screen.
      onAct: (ctx) => download("/api/customers.csv?" + new URLSearchParams(ctx.query)),
    },
  ]}
/>

⚠️ Hand the big ones to your server

The shipped actions build the file in the browser from rows already in memory, which is right for a page and wrong for a million records. ctx.query exists so a server action can answer for everything that matches instead.

Import writes nothing on its own

The shipped importer parses the file and hands you rows through onDataChange. It does not upload, does not merge and does not know which of your columns is a key. Deduplication, validation against your schema and the write itself are your application's.

When it did not work

The export is missing a column

Cause: it is hidden, by hideInTable or by the column menu. Export follows the table. Fix: show the column, or add a server action that does not depend on it.

Imported rows appear and then vanish

Cause: data is controlled and onDataChange did not store them. Fix: store them, or move to initialData.