Add a complete CSV and Excel importer to your Next.js app, with column mapping, real-time validation, and API integration built in.

Installation

Install both packages:

1npm install @importok/javascript @importok/react

Note: The trial version is available on NPM. When you upgrade, you'll get access to our private packages with full features. No code changes required.

Your first importer

Create a basic contact importer:

1import dynamic from 'next/dynamic';
2 
3const ImportokWizard = dynamic(() => import('@importok/react'), {
4 ssr: false
5});
6 
7export default function Home() {
8 // Define the fields you want to import
9 const fields = {
10 first_name: { label: 'First Name' },
11 last_name: { label: 'Last Name' },
12 email: { label: 'Email' },
13 phone: { label: 'Phone' },
14 country: { label: 'Country' }
15 };
16 
17 return (
18 <div className="App">
19 <ImportokWizard
20 title="Import Contacts"
21 fields={fields}
22 />
23 </div>
24 );
25}

That's it. Users can now upload CSV or Excel files and map columns to your fields.

Make it production-ready

Add data transformations

Clean up data before validation using transformers:

1const fields = {
2 first_name: {
3 label: 'First Name',
4 transformers: 'trim|capitalize' // Built-in transformers
5 },
6 last_name: {
7 label: 'Last Name',
8 transformers: 'trim|capitalize'
9 },
10 email: {
11 label: 'Email',
12 transformers: 'trim'
13 }
14};

See all built-in transformers →

Add validation rules

Catch errors before they reach your API using validators:

1const fields = {
2 first_name: {
3 label: 'First Name',
4 transformers: 'trim|capitalize'
5 },
6 last_name: {
7 label: 'Last Name',
8 transformers: 'trim|capitalize',
9 validators: 'required' // Built-in validators
10 },
11 email: {
12 label: 'Email',
13 transformers: 'trim',
14 validators: 'email|required'
15 }
16};

See all built-in validators →

Connect to your API

Send validated data to your backend:

1export default function Home() {
2 const fields = { /* ... */ };
3 
4 const handleImport = async function (records, meta) {
5 const response = await fetch('/api/contacts/imports', {
6 method: 'POST',
7 headers: { 'Content-Type': 'application/json' },
8 body: JSON.stringify(records)
9 });
10 
11 return response;
12 };
13 
14 return (
15 <ImportokWizard
16 title="Import Contacts"
17 fields={fields}
18 onImportReady={handleImport}
19 />
20 );
21}

Complete example

Here's everything together:

1import dynamic from 'next/dynamic';
2 
3const ImportokWizard = dynamic(() => import('@importok/react'), {
4 ssr: false
5});
6 
7export default function Home() {
8 const fields = {
9 first_name: {
10 label: 'First Name',
11 transformers: 'trim|capitalize'
12 },
13 last_name: {
14 label: 'Last Name',
15 transformers: 'trim|capitalize',
16 validators: 'required'
17 },
18 email: {
19 label: 'Email',
20 transformers: 'trim',
21 validators: 'email|required'
22 },
23 phone: {
24 label: 'Phone',
25 transformers: 'trim'
26 },
27 country: {
28 label: 'Country',
29 transformers: 'trim',
30 validators: 'in:countries'
31 }
32 };
33 
34 const handleImport = async function (records, meta) {
35 return await fetch('/api/contacts/imports', {
36 method: 'POST',
37 headers: { 'Content-Type': 'application/json' },
38 body: JSON.stringify(records)
39 });
40 };
41 
42 return (
43 <div className="App">
44 <ImportokWizard
45 title="Import Contacts"
46 fields={fields}
47 onImportReady={handleImport}
48 />
49 </div>
50 );
51}

Next steps

Now that you have a working importer, explore advanced features:

Try it live

Experiment with a complete example in StackBlitz: Open in StackBlitz →

Trial limitations

The free trial includes:

  • ✅ Full UI and mapping features
  • ✅ Built-in validators and transformers
  • ⚠️ 20 records per import (unlimited on paid plans)
  • ⚠️ Up to 2 custom validators (unlimited on paid plans)
  • ⚠️ Up to 2 custom transformers (unlimited on paid plans)
  • ⚠️ Up to 2 data providers (unlimited on paid plans)

When you're ready, upgrade to unlock full features with access to our private packages.

Start typing to search documentation and articles...

⌘K or Ctrl+K to open search

No results found for ""

Try different keywords or check your spelling.

Use ↑ ↓ arrow keys to navigate and Enter to select