API Reference

Complete API documentation for ImportCSV

CSVImporter Props

PropTypeDefaultDescription
columnsColumn[]-Column definitions (required for local mode)
onComplete(data: ImportData) => void-Callback when import completes
isModalbooleantrueShow as modal vs embedded
modalIsOpenbooleantrueControl modal state
modalOnCloseTriggered() => void-Modal close callback
modalCloseOnOutsideClickbooleanfalseClose on outside click
themeThemeConfig | string-Theme configuration or preset name
darkModebooleanfalseEnable dark theme (backward compatibility)
primaryColorstring#2563ebPrimary color (hex)
customStylesobject | string-CSS variable overrides
classNamesobject-Custom class names for components
showDownloadTemplateButtonbooleantrueShow template download
skipHeaderRowSelectionbooleanfalseAuto-select first row as header
waitOnCompletebooleanfalseWait for async operations on complete
invalidRowHandling'include' | 'exclude' | 'block''block'How to handle rows with validation errors
includeUnmatchedColumnsbooleanfalseInclude CSV columns not defined in schema
languagestring-Language for internationalization
customTranslationsobject-Custom translation resources
importerKeystring-Importer key for backend mode
backendUrlstring-Backend API URL (for backend mode)
userobject-User context for backend mode
metadataobject-Additional metadata for import
demoDataobject-Demo data for testing

Import Behavior Options

Invalid Row Handling

The invalidRowHandling prop controls how the importer handles rows that fail validation:

ModeDescriptionUse Case
'block' (default)Prevents import if ANY row has validation errorsCritical data imports where integrity is paramount
'exclude'Filters out invalid rows, imports only valid onesClean data imports, removing problematic entries
'include'Imports all rows with warnings for invalid onesFlexible imports where you'll handle errors later

Examples

// Strict mode - blocks import on any error (default)
<CSVImporter
  columns={columns}
  invalidRowHandling="block"
  onComplete={(data) => console.log(data)}
/>

// Filter mode - imports only valid rows
<CSVImporter
  columns={columns}
  invalidRowHandling="exclude"
  onComplete={(data) => {
    // data contains only rows that passed validation
    console.log(`Imported ${data.num_rows} valid rows`);
  }}
/>

// Permissive mode - imports everything with warnings
<CSVImporter
  columns={columns}
  invalidRowHandling="include"
  onComplete={(data) => {
    // data contains all rows, check for errors separately
    console.log(`Imported ${data.num_rows} rows (may include invalid data)`);
  }}
/>

Include Unmatched Columns

The includeUnmatchedColumns prop allows importing columns from the CSV that aren't defined in your schema:

// Example CSV with extra columns:
// Name,Email,Department,Manager,Office
// John,john@example.com,Sales,Jane Smith,Building A

const columns = [
  { id: 'name', label: 'Name' },
  { id: 'email', label: 'Email' },
  { id: 'department', label: 'Department' }
];

// With includeUnmatchedColumns=true
<CSVImporter
  columns={columns}
  includeUnmatchedColumns={true}
  onComplete={(data) => {
    // data.mappedData includes defined columns
    // data.unmappedData includes Manager and Office columns
  }}
/>

This is useful for:

  • Dynamic CSV structures where users might add custom columns
  • Importing data where you want to preserve all information
  • Flexible schemas that adapt to user needs

Column Interface

interface Column {
  id: string;                      // Unique identifier
  label: string;                   // Display name
  type?: 'string' | 'number' | 'email' | 'date' | 'phone' | 'select';
  validators?: Validator[];        // Validation rules
  transformations?: Transformer[]; // Data transformations
  options?: string[];              // For select type
  description?: string;            // Help text
  placeholder?: string;            // Example value
}

Validators

type Validator =
  | { type: 'required'; message?: string }
  | { type: 'unique'; message?: string }
  | { type: 'regex'; pattern: string; message?: string }
  | { type: 'min'; value: number; message?: string }         // For number fields
  | { type: 'max'; value: number; message?: string }         // For number fields
  | { type: 'min_length'; value: number; message?: string }  // For string fields
  | { type: 'max_length'; value: number; message?: string }; // For string fields

Examples

validators: [
  { type: 'required' },
  { type: 'unique', message: 'Must be unique' },
  { type: 'regex', pattern: '^[A-Z]+$', message: 'Uppercase only' },
  { type: 'min', value: 0 },
  { type: 'max', value: 100 },
  { type: 'min_length', value: 3 },
  { type: 'max_length', value: 50 }
]

Transformers

Transformations are applied after validation, before data is returned. They process data silently without showing errors to users.

type Transformer =
  | { type: 'trim' }                    // Remove whitespace from start/end
  | { type: 'uppercase' }                // Convert to UPPERCASE
  | { type: 'lowercase' }                // Convert to lowercase
  | { type: 'capitalize' }               // Capitalize First Letter Of Each Word
  | { type: 'remove_special_chars' }     // Keep only alphanumeric and spaces
  | { type: 'normalize_phone' }          // Format as +1234567890
  | { type: 'normalize_date'; format?: string }  // Parse and format dates
  | { type: 'default'; value: string }   // Replace empty with default value
  | { type: 'replace'; find: string; replace: string }  // Find and replace
  | { type: 'custom'; fn: (value: any) => any }  // Custom transformation

Transformation Details

TypeDescriptionExample InputExample Output
trimRemoves leading/trailing whitespace" hello ""hello"
uppercaseConverts to uppercase"Hello""HELLO"
lowercaseConverts to lowercase"Hello""hello"
capitalizeCapitalizes first letter of each word"john doe""John Doe"
remove_special_charsKeeps only letters, numbers, spaces"hello@123!""hello123"
normalize_phoneFormats as US phone number"555-123-4567""(555) 123-4567"
normalize_dateParses and formats dates"01/15/24""2024-01-15"
defaultReplaces empty values"""N/A"
replaceString replacement"hello world""hello_world"
customCustom functionanyany

Examples

// Chain multiple transformations
transformations: [
  { type: 'trim' },                      // First: remove whitespace
  { type: 'lowercase' },                 // Then: convert to lowercase
  { type: 'default', value: 'unknown' }  // Finally: set default if empty
]

// Phone number normalization
transformations: [
  { type: 'normalize_phone' }  // "555-123-4567" → "(555) 123-4567"
]

// Date formatting
transformations: [
  { type: 'normalize_date', format: 'YYYY-MM-DD' }  // "1/15/24" → "2024-01-15"
]

// Custom transformation
transformations: [
  {
    type: 'custom',
    fn: (value) => {
      // Remove currency symbol and parse as number
      return parseFloat(value.replace(/[$,]/g, ''));
    }
  }
]

// Complex example: SKU formatting
transformations: [
  { type: 'trim' },
  { type: 'remove_special_chars' },
  { type: 'replace', find: ' ', replace: '-' },
  { type: 'uppercase' }
]  // "  prod #123  " → "PROD-123"

Transformation Order

Transformations are applied in the order they are defined:

// Order matters!
column: {
  id: 'email',
  transformations: [
    { type: 'trim' },        // 1st: "  JOHN@EXAMPLE.COM  "
    { type: 'lowercase' }    // 2nd: "john@example.com"
  ]
}

Response Format

interface ImportData {
  rows: Array<{
    index: number;
    values: Record<string, any>;
  }>;
  columns: Array<{
    id: string;
    label: string;
  }>;
  num_rows: number;
  num_columns: number;
  // When includeUnmatchedColumns is true:
  mappedData?: any[];      // Data for defined columns
  unmappedData?: any[];    // Data for extra columns
}

Example Response

{
  "num_rows": 2,
  "num_columns": 2,
  "columns": [
    { "id": "name", "label": "Name" },
    { "id": "email", "label": "Email" }
  ],
  "rows": [
    {
      "index": 0,
      "values": {
        "name": "John Doe",
        "email": "john@example.com"
      }
    },
    {
      "index": 1,
      "values": {
        "name": "Jane Smith",
        "email": "jane@example.com"
      }
    }
  ]
}

Performance Considerations

Large Datasets (1,000+ rows)

ImportCSV automatically enables performance optimizations for large files:

  • Virtual Scrolling: Only renders visible rows (~20) in the DOM
  • Progressive Validation: Validates first 50 rows instantly, rest asynchronously
  • Memory Management: Efficient data structures and cleanup
// No special configuration needed - optimizations are automatic
<CSVImporter
  columns={columns}
  onComplete={handleComplete}
/>

Performance Tips

  1. Use built-in validators over complex regex patterns
  2. Minimize transformations for better performance
  3. Keep validators simple for faster validation
  4. Consider server-side processing for files > 10,000 rows

See the Performance Guide for detailed information.

Component Class Names

Customize component classes with the classNames prop:

classNames={{
  root: 'my-importer',
  modal: 'my-modal',
  header: 'my-header',
  stepper: 'my-stepper',
  content: 'my-content',
  footer: 'my-footer',
  button: 'my-button',
  input: 'my-input',
  table: 'my-table',
  dropzone: 'my-dropzone'
}}

Custom Styles

Override CSS variables:

customStyles={{
  'font-family': 'Inter',
  'font-size': '14px',
  'border-radius': '8px',
  'color-primary': '#3B82F6',
  'color-primary-hover': '#2563EB',
  'color-border': '#E5E7EB',
  'color-text': '#111827',
  'color-background': '#FFFFFF',
  'color-background-modal': '#F9FAFB'
}}

All CSS Variables

--font-family
--font-size
--base-spacing
--border-radius
--color-primary
--color-primary-hover
--color-secondary
--color-secondary-hover
--color-tertiary
--color-tertiary-hover
--color-border
--color-text
--color-text-soft
--color-text-on-primary
--color-text-on-secondary
--color-background
--color-background-modal
--color-input-background
--color-input-background-soft
--color-background-menu-hover
--color-importer-link
--color-progress-bar

CSS Injection

Starting from v0.2.0, CSS is automatically injected when the component loads. No separate CSS import is needed:

// Just import the component - CSS is included!
import { CSVImporter } from '@importcsv/react';

// No need for: import '@importcsv/react/dist/style.css' ❌

The CSS is scoped using the .importcsv class to prevent style conflicts.

TypeScript

import { CSVImporter } from '@importcsv/react';
import type { Column, Validator, Transformer } from '@importcsv/react';

const columns: Column[] = [
  {
    id: 'email',
    label: 'Email',
    type: 'email',
    validators: [{ type: 'required' }] as Validator[]
  }
];

Methods (JavaScript SDK)

const importer = CSVImporter.createCSVImporter(config);

importer.showModal();   // Open modal
importer.closeModal();  // Close modal