API Reference
Complete API documentation for ImportCSV
CSVImporter Props
Prop | Type | Default | Description |
---|---|---|---|
columns | Column[] | - | Column definitions (required for local mode) |
onComplete | (data: ImportData) => void | - | Callback when import completes |
isModal | boolean | true | Show as modal vs embedded |
modalIsOpen | boolean | true | Control modal state |
modalOnCloseTriggered | () => void | - | Modal close callback |
modalCloseOnOutsideClick | boolean | false | Close on outside click |
theme | ThemeConfig | string | - | Theme configuration or preset name |
darkMode | boolean | false | Enable dark theme (backward compatibility) |
primaryColor | string | #2563eb | Primary color (hex) |
customStyles | object | string | - | CSS variable overrides |
classNames | object | - | Custom class names for components |
showDownloadTemplateButton | boolean | true | Show template download |
skipHeaderRowSelection | boolean | false | Auto-select first row as header |
waitOnComplete | boolean | false | Wait for async operations on complete |
invalidRowHandling | 'include' | 'exclude' | 'block' | 'block' | How to handle rows with validation errors |
includeUnmatchedColumns | boolean | false | Include CSV columns not defined in schema |
language | string | - | Language for internationalization |
customTranslations | object | - | Custom translation resources |
importerKey | string | - | Importer key for backend mode |
backendUrl | string | - | Backend API URL (for backend mode) |
user | object | - | User context for backend mode |
metadata | object | - | Additional metadata for import |
demoData | object | - | Demo data for testing |
Import Behavior Options
Invalid Row Handling
The invalidRowHandling
prop controls how the importer handles rows that fail validation:
Mode | Description | Use Case |
---|---|---|
'block' (default) | Prevents import if ANY row has validation errors | Critical data imports where integrity is paramount |
'exclude' | Filters out invalid rows, imports only valid ones | Clean data imports, removing problematic entries |
'include' | Imports all rows with warnings for invalid ones | Flexible 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
Type | Description | Example Input | Example Output |
---|---|---|---|
trim | Removes leading/trailing whitespace | " hello " | "hello" |
uppercase | Converts to uppercase | "Hello" | "HELLO" |
lowercase | Converts to lowercase | "Hello" | "hello" |
capitalize | Capitalizes first letter of each word | "john doe" | "John Doe" |
remove_special_chars | Keeps only letters, numbers, spaces | "hello@123!" | "hello123" |
normalize_phone | Formats as US phone number | "555-123-4567" | "(555) 123-4567" |
normalize_date | Parses and formats dates | "01/15/24" | "2024-01-15" |
default | Replaces empty values | "" | "N/A" |
replace | String replacement | "hello world" | "hello_world" |
custom | Custom function | any | any |
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
- Use built-in validators over complex regex patterns
- Minimize transformations for better performance
- Keep validators simple for faster validation
- 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