Features

Data Export

Export collection data to CSV and JSON formats for reporting, backups, and data migration.

Data Export

Export collection data to CSV and JSON formats for reporting, backups, and data migration.

Status: Stable

Overview

The export feature provides a composable and a ready-to-use button component for exporting collection data. It works with useCollectionQuery for client-side data or can fetch directly from the API for server-filtered exports.

Features:

  • CSV and JSON export formats
  • Custom field selection and labeling
  • Field transformations
  • Row transformations
  • Metadata and ID exclusion
  • Server-side query exports
  • i18n support for labels

Quick Start

Basic Export with Component

<script setup lang="ts">
const { items } = await useCollectionQuery('products')
</script>

<template>
  <CroutonExportButton
    collection="products"
    :rows="items"
  />
</template>

Basic Export with Composable

<script setup lang="ts">
const { items } = await useCollectionQuery('products')
const { exportCSV, exportJSON } = useCollectionExport('products')
</script>

<template>
  <div class="flex gap-2">
    <UButton @click="exportCSV(items)">Export CSV</UButton>
    <UButton @click="exportJSON(items)">Export JSON</UButton>
  </div>
</template>

Composable API

useCollectionExport(collection)

interface UseCollectionExportReturn {
  exportCSV: (rows: any[], options?: ExportOptions) => void
  exportJSON: (rows: any[], options?: ExportOptions) => void
  exportWithQuery: (
    format: 'csv' | 'json',
    query?: Record<string, any>,
    options?: ExportOptions
  ) => Promise<void>
  isExporting: Ref<boolean>
}

Export Options

interface ExportOptions {
  // Field selection
  fields?: (string | ExportField)[]
  excludeFields?: string[]

  // What to include
  includeId?: boolean        // default: false
  includeMetadata?: boolean  // default: false (createdAt, updatedAt, etc.)

  // Transformations
  transformRow?: (row: any) => any

  // Output
  filename?: string          // default: collection name
  dateFormat?: 'iso' | 'locale' | 'timestamp'
  flattenNested?: boolean    // Stringify nested objects
}

interface ExportField {
  key: string
  label?: string
  transform?: (value: any, row: any) => any
}

Examples

Custom Fields and Labels

const { exportCSV } = useCollectionExport('products')

exportCSV(items.value, {
  fields: [
    { key: 'name', label: 'Product Name' },
    { key: 'price', label: 'Price ($)', transform: (v) => v.toFixed(2) },
    { key: 'category', label: 'Category' }
  ],
  filename: 'product-report'
})

Flatten Nested Data

const { exportCSV } = useCollectionExport('orders')

exportCSV(orders.value, {
  transformRow: (row) => ({
    ...row,
    customerName: row.customer?.name,
    customerEmail: row.customer?.email,
    items: row.items?.map(i => i.name).join(', ')
  }),
  excludeFields: ['customer']  // Exclude original nested object
})

Export with Current Filters

const searchQuery = ref('')
const statusFilter = ref('active')

const query = computed(() => ({
  search: searchQuery.value,
  status: statusFilter.value
}))

const { items } = await useCollectionQuery('products', { query })
const { exportWithQuery, isExporting } = useCollectionExport('products')

// Export ALL data matching filters (not just current page)
async function handleExport() {
  await exportWithQuery('csv', query.value, {
    filename: `products-${statusFilter.value}`
  })
}

Include Metadata

const { exportCSV } = useCollectionExport('products')

exportCSV(items.value, {
  includeId: true,
  includeMetadata: true,  // Includes createdAt, updatedAt, etc.
  dateFormat: 'locale'    // Format dates for local timezone
})

Component API

CroutonExportButton

<CroutonExportButton
  collection="products"
  :rows="items"
  :formats="['csv', 'json']"
  :options="{ excludeFields: ['internalCode'] }"
  variant="ghost"
  size="sm"
  @export="handleExport"
  @error="handleError"
/>

Props

PropTypeDefaultDescription
collectionstringrequiredCollection name
rowsany[]requiredData to export
formats('csv' | 'json')[]['csv', 'json']Available formats
optionsExportOptions{}Export options
variantstring'ghost'Button variant
sizestring'sm'Button size
colorstring-Button color
disabledbooleanfalseDisable button

Events

EventPayloadDescription
export[format, rows]Fired on successful export
error[Error]Fired on export error

Slots

<CroutonExportButton collection="products" :rows="items">
  Download Report
</CroutonExportButton>

Integration Examples

Table Header with Export

<script setup lang="ts">
const { items } = await useCollectionQuery('products')
</script>

<template>
  <CroutonCollection :rows="items" collection="products">
    <template #header>
      <div class="flex justify-between items-center p-4">
        <h2 class="text-lg font-semibold">Products</h2>
        <div class="flex gap-2">
          <CroutonExportButton
            collection="products"
            :rows="items"
            :options="{ excludeFields: ['teamId'] }"
          />
          <UButton @click="open('create', 'products')">
            Add Product
          </UButton>
        </div>
      </div>
    </template>
  </CroutonCollection>
</template>

Export Selected Rows

<script setup lang="ts">
const { items } = await useCollectionQuery('products')
const { exportCSV } = useCollectionExport('products')

const selectedRows = ref<string[]>([])

function exportSelected() {
  const selected = items.value.filter(item =>
    selectedRows.value.includes(item.id)
  )
  exportCSV(selected, { filename: 'selected-products' })
}
</script>

Default Exclusions

The following fields are excluded by default:

FieldReasonOverride
teamIdInternal identifierN/A (always excluded)
idOften not needed in exportsincludeId: true
createdAtMetadataincludeMetadata: true
updatedAtMetadataincludeMetadata: true
createdByMetadataincludeMetadata: true
updatedByMetadataincludeMetadata: true

CSV Handling

The export handles special characters properly:

  • Commas: Values containing commas are quoted
  • Quotes: Double quotes are escaped as ""
  • Newlines: Multi-line values are quoted
  • Unicode: UTF-8 BOM is added for Excel compatibility

i18n Support

The component uses translation keys for labels:

KeyDefault
export.buttonExport
export.csvExport as CSV
export.jsonExport as JSON
export.noDataNo data to export
export.successExport completed
export.errorExport failed

Limitations

  • Maximum 10,000 rows for exportWithQuery (configurable server-side)
  • Large exports may cause browser memory pressure
  • No Excel (XLSX) format (coming in future release)