2. Install Code
Add a snippet of code to your app to start accepting spreadsheets from your users.
Go to the 'Code' tab of the sheet and find the integration code. Place the code in your application at the location you want to display the import button.
Sample code with basic usage:
<button class="btn btn-primary" data-csvbox disabled onclick="importer.openModal();">Import</button>
<script type="text/javascript" src="https://js.csvbox.io/script.js"></script>
<script type="text/javascript">
function callback(result, data) {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}
let importer = new CSVBoxImporter("YOUR_LICENSE_KEY_HERE",{
}, callback);
importer.setUser({
user_id: "default123"
})
</script>Install using npm:
npm install @csvbox/react This will give you access to the CSVBoxButton component having the basic functionality of our importer. Import the CSVBoxButton component to your project.
import { CSVBoxButton } from '@csvbox/react'Basic usage:
<CSVBoxButton
licenseKey="YOUR_LICENSE_KEY_HERE"
user={{
user_id: "default123"
}}
onImport={(result, data) => {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}}
render={(launch, isLoading)=>{
return <button disabled={isLoading} onClick={launch}>Upload file</button>;
}}
>
Import
</CSVBoxButton>Install using npm:
npm install @csvbox/angularImport:
Add CSVBoxAngularModule to your module imports.
import { CSVBoxAngularModule } from "@csvbox/angular";
@NgModule({
...
imports: [
...
CSVBoxAngularModule
]
})Once you have this setup, in your app component file, you will be able to import and access theCSVBoxMethods module for use.
It will bring the csvbox-button component into your project. Example:
<csvbox-button [licenseKey]="licenseKey" [imported]="imported.bind(this)" [user]="user">Import</csvbox-button>Basic usage:
@Component({
selector: 'app-root',
template: `
<csvbox-button
[licenseKey]="licenseKey"
[user]="user"
[imported]="imported.bind(this)">
Import
</csvbox-button>
`
})
export class AppComponent {
title = 'example';
licenseKey = 'YOUR_LICENSE_KEY_HERE';
user = { user_id: 'default123' };
imported(result: boolean, data: any) {
if(result) {
console.log("Sheet uploaded successfully");
console.log(data.row_success + " rows uploaded");
}else{
console.log("There was some problem uploading the sheet");
}
}
}Styling the button:
In order to style the <csvbox-button> from within your parent component, ensure that your parent component has ViewEncapsulation.None, pass down a class to <csvbox-button>, and now you will be able to style the button one-level down.
import { Component, ViewEncapsulation } from '@angular/core';@Component({
selector: 'app-root',
template: `
<csvbox-button
[licenseKey]="licenseKey"
[user]="user"
[dynamicColumns]="dynamicColumns"
[imported]="Imported.bind(this)"
class=“csvbox-btn”
>
Import
</csvbox-button>
`,
encapsulation: ViewEncapsulation.None,
styles: [`
.csvbox-btn button {
background: #007bff;
border-radius: 3px;
}
`],
export class AppComponent {
//...
}Install using npm:
npm install @csvbox/vuejs This will give you access to the CSVBoxButton component. Import the CSVBoxButton component to your project.
import { CSVBoxButton } from '@csvbox/vuejs' Now just import the CSVBoxButton and include it in your Vue components, and you're ready to get started.
Basic usage:
<template>
<div id="app">
<CSVBoxButton
:licenseKey="licenseKey"
:user="user"
:onImport="onImport">
Upload File
</CSVBoxButton>
</div>
</template>
<script>
import { CSVBoxButton } from '@csvbox/vuejs';
export default {
name: 'App',
components: {
CSVBoxButton,
},
data: () => ({
licenseKey: 'YOUR_LICENSE_KEY_HERE',
user: {
user_id: 'default123',
},
}),
methods: {
onImport: function (result, data) {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}
},
}
</script>
Implementation Demo
If your app/database is restricted to IP addresses on an allowlist, you will need to manually add CSVbox's addresses in order to use the importer.
You will have to whitelist the following IP addresses:
18.233.84.18318.213.249.533.73.26.144
Note that at any time, you will only see one of these addresses in use. However, the active IP address can change at any time, so you should add them all to your IP whitelist to ensure no interruptions in service.
Referencing the user
You can configure custom user attributes in the installation code to identify the users in your platform and match them with their respective imports.
Pass custom user attributes as input parameters to the setUsermethod. The custom user attributes will be pushed to your destination along with the uploaded data.
user_id is the only custom attribute that is mandatory. Apart from user_id, you can add up to 4 custom attributes in the<key>: <value>format. Example:
importer.setUser({
user_id: "1a2b3c4d5e6f",
team_id: "sales2",
isAuthenticated: "true",
permissionLevel: "admin",
email: "[email protected]"
})Pass custom user attributes as an object to the userproperty of the CSVBoxButton component. The custom user attributes will be pushed to your destination along with the uploaded data.
user_id is the only custom attribute that is mandatory. Apart from user_id, you can add up to 4 custom attributes in the <key>: <value>format. Example:
user={{
user_id: "1a2b3c4d5e6f",
team_id: "sales2",
isAuthenticated: "true",
permissionLevel: "admin",
email: "[email protected]"
}}Pass custom user attributes as an object to the userproperty of the AppComponent. The custom user attributes will be pushed to your destination along with the uploaded data.
user_id is the only custom attribute that is mandatory. Apart from user_id, you can add up to 4 custom attributes in the <key>: <value>format. Example:
user={
user_id: "1a2b3c4d5e6f",
team_id: "sales2",
isAuthenticated: "true",
permissionLevel: "admin",
email: "[email protected]"
}Pass custom user attributes as an object to the userproperty of the CSVBoxButton component. The custom user attributes will be pushed to your destination along with the uploaded data.
user_id is the only custom attribute that is mandatory. Apart from user_id, you can add up to 4 custom attributes in the <key>: <value>format. Example:
user: {
user_id: "1a2b3c4d5e6f",
team_id: "sales2",
isAuthenticated: "true",
permissionLevel: "admin",
email: "[email protected]"
},Callback function
Once the user uploads a file the importer will return the status of the import along with metadata describing the completed import. Data is returned via two variables: result and data.
result- It is of type boolean with the value true if the import is successful and false if the import fails.data- It returns JSON data as shown below:
{
"import_id": 79418895,
"sheet_id": 575,
"sheet_name": "Products Import",
"destination_type": "webhook"
"row_count": 100,
"row_success": 98,
"row_fail": 2,
"import_status": "Partial",
"import_starttime": 87987897897,
"import_endtime": 90890890809,
"original_filename": "example-1.csv",
"raw_file": "https://file-download-link",
"custom_fields": {
"user_id": "Z1001"
},
"column_mappings": [
{ "Name": "Name" },
{ "SKU": "Product SKU" },
{ "Price": "Sale Price" },
{ "Quantity": "Inventory"},
{ "Image URL": "Img"}
]
}You can write custom code to handle the success or failure conditions client side.
The result and datavariables will be available in the callbackfunction that is triggered when the import is completed.
function callback(result, data) {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}Pass additional options as an object to the userproperty of the CSVBoxButton component. The custom user attributes will be pushed to your destination along with the uploaded data.
user_id is the only custom attribute that is mandatory. Apart from user_id, you can add up to 4 custom attributes in the <key>: <value>format. Example:
user={{
user_id: "1a2b3c4d5e6f",
team_id: "sales2",
isAuthenticated: "true",
permissionLevel: "admin",
email: "[email protected]"
}}The imported property provides access to the result and datavariables via the specified callback function.
imported(result: boolean, data: any) {
if(result) {
console.log("Sheet uploaded successfully");
console.log(data.row_success + " rows uploaded");
}else{
console.log("There was some problem uploading the sheet");
}
}The onImport property provides access to the result and datavariables.
onImport: function (result, data) {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}Options
Here is the list of additional configuration options available with the CSVbox importer.
max_rows
Type: number
Default: null
Description:
Specify the maximum number of rows that a single file can import. This value excludes the headers of the file. So if the number of rows in a sheet is 101, but the first row is the header, then this file would be considered to have 100 data rows in it.

max_rows_allow_submit
Type: boolean
Default: true
Description:
Allow or disallow submission of the permissible number of rows when the overall row count exceeds the limit. Consider row limit (max_rows) is set to 5. If max_rows_allow_submit is set to true then the user can upload the top 5 rows of his file. If max_rows_allow_submit is set to false then the user will not be able to submit even 1 row if the overall row count exceeds max_rows.
max_rows_custom_message
Type: string
Default: null
Description:
Display a custom message to the user when the file row count is greater than max_rows. This message will show only when max_rows_allow_submit is set to false.

min_rows
Type: number
Default: null
Description:
The minimum number of rows that is required for a single upload.
min_rows_custom_message
Type: string
Default: null
Description:
Display a custom message when the file row count is less than min_rows.
language
Type: string
Default: null
Description:
Specify the importer frontend language. This value will override the default language option configured via the csvbox dashboard. Acceptable values are:
en
English
de
German
fr
French
es
Spanish
nl
Dutch
pt
Portuguese
th
Thai
pl
Polish
ro
Romanian
he
Hebrew
jp
Japenese
da
Danish
tr
Turkish
sk
Slovak
hi
Hindi
ms
Bahasa Malaysia (Malay)
ru
Russian
vi
Vietnamese
ko
Korean
id
Bahasa Indonesia
ar-EG
Egyptian Arabic
ur
Urdu
allow_invalid
Type: boolean
Default: 0
Description:
It specifies if the users can continue to submit the file even if there are validation errors.
request_headers
Type: { key: value, key: value, ... }
Default: null
Description:
This is where you define additional headers that get passed with each HTTP request.
dynamic_list_request_headers
Type: { key: value, key: value, ... }
Default: null
Description:
This is where you define additional headers that get passed with each HTTP request for the dynamic list API.
sample_template_url
Type: String
Default: null
Description:
It is the URL to download the sample CSV file for the end users.
sample_template_button_text
Type: String
Default: null
Description:
It specifies the text on the button for downloading the sample CSV file.
Examples:
Pass additional options as input parameters to the setOptionsmethod.
importer.setOptions({
max_rows: 50,
language: 'de',
request_headers: {
"Content-Type": "application/json",
"X-Access-Token": "71ab1d73a4d1319b260e9a0sdbdbc1c"
},
sample_template_url: 'https://files.myapp.com/user-18768',
sample_template_button_text: 'Starter Template'
})Pass the additional options as an object to the optionsproperty of the CSVBoxButton component.
options={{
max_rows: 50,
language: 'de',
request_headers: {
"Content-Type": "application/json",
"X-Access-Token": "71ab1d73a4d1319b260e9a0sdbdbc1c"
},
sample_template_url: 'https://files.myapp.com/user-18768',
sample_template_button_text: 'Starter Template'
}}Pass the additional options as an object to the optionsproperty of the AppComponent.
options={
max_rows: 50,
language: 'de',
request_headers: {
"Content-Type": "application/json",
"X-Access-Token": "71ab1d73a4d1319b260e9a0sdbdbc1c"
},
sample_template_url: 'https://files.myapp.com/user-18768',
sample_template_button_text: 'Starter Template'
}Pass the additional options as an object to the optionsproperty of the CSVBoxButton component.
options: {
max_rows: 50,
language: 'de',
request_headers: {
"Content-Type": "application/json",
"X-Access-Token": "71ab1d73a4d1319b260e9a0sdbdbc1c"
},
sample_template_url: 'https://files.myapp.com/user-18768',
sample_template_button_text: 'Starter Template'
},target_file_name
Type: String
Default: null
Description:
It specifies the name of the file that gets pushed to your destination. This is applicable for the following destinations only:
s3
FTP Server
Google Sheets
upload_file_url
Type: String
Default: null
Description:
The URL of the file to be imported. This is useful in cases where you want the data to be pre-loaded into the importer without asking the users to upload the file. Simply provide the file location and the importer will load the data when the user clicks the Import button.
upload_file_worksheet_name
Type: String
Default: null
Description:
The name of the worksheet that should be uploaded if you are uploading a file with multiple tabs via upload_file_url option.
theme
Type: String
Default: null
Description:
Initializes the importer with the specified theme. Supported values:
light,light-custom,dark,dark-custom. If not specified, the theme set in the sheet dashboard will be used by default.
default_header_row
Type: number
Default: 1
Description: Row to auto-select as the header on the Header Selection page (rows are 1-indexed).
Events
Here is the list of additional importer events/properties:
onReady
Triggers when the importer is initialized and ready for use by the users. The users can then click the Import button to open the Importer modal dialog.
onLoadStart
Triggers when the importer iFrame starts loading.
onClose
Triggers when the importer is closed.
onSubmit
Triggers when the user hits the 'Submit' button to upload the validated file. data object is available in this event. It contains metadata related to the import.
onImport
Triggers when all the data is pushed to the destination. Two objects are available in this event:
result(boolean): It is true when the import is successful and false when the import fails.data(object): Contains metadata related to the import.
Examples:
<button class="btn btn-primary" data-csvbox disabled onclick="importer.openModal();">Import</button>
<script type="text/javascript" src="https://js.csvbox.io/script.js"></script>
<script type="text/javascript">
function callback(result, data) {
if(result){
console.log("Sheet uploaded successfully");
console.log(data.row_success + " rows uploaded");
}else{
console.log("There was some problem uploading the sheet");
}
}
let importer = new CSVBoxImporter("YOUR_LICENSE_KEY_HERE",{}, callback);
importer.setUser({
user_id: 'default123'
});
importer.listen("onReady", function(){
console.log("onReady");
});
importer.listen("onClose", function(){
console.log("onClose");
});
importer.listen("onSubmit", function(data){
console.log("onSubmit");
console.log(data.import_id);
});
</script> import React from "react";
import { CSVBoxButton } from "@csvbox/react";
const App = () => {
return (
<CSVBoxButton
licenseKey="YOUR_LICENSE_KEY_HERE"
lazy={true}
user={{
user_id: "default123"
}}
onImport={(result, data) => {
if (result) {
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
} else {
console.log("fail");
//custom code
}
}}
loadStarted={() => {
console.log("loadStarted");
}}
onReady={() => {
console.log("onReady");
}}
onClose={() => {
console.log("onclosed");
}}
onSubmit={(data) => {
console.log("onSubmit");
console.log(data.import_id);
}}
>
Import
</CSVBoxButton>
);
};
export default App;onReady
importerReady
onLoadStart
loadStarted
onClose
closed
onSubmit
submitted
onImport
imported
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<csvbox-button
[licenseKey]="licenseKey"
[user]="user"
[dynamicColumns]="dynamicColumns"
[imported]="imported.bind(this)"
[closed]="closed.bind(this)"
[submitted]="submitted.bind(this)"
[importerReady]="importerReady.bind(this)">
Import
</csvbox-button>
`
})
export class AppComponent {
title = 'example';
licenseKey = 'YOUR_LICENSE_KEY_HERE';
user = { user_id: 'default123' };
dynamicColumns = [
{
column_name: 'col2',
type: 'text'
}
];
imported(result: boolean, data: any) {
console.log("result", result, "data", data)
if(result) {
console.log("Sheet uploaded successfully");
console.log(data.row_success + " rows uploaded");
}else{
console.log("There was some problem uploading the sheet");
}
}
loadStarted() {
console.log("loadStarted");
}
closed(){
console.log("onClose");
}
importerReady(){
console.log("onReady");
}
submitted(data: any){
console.log("onSubmit");
console.log(data.import_id);
}
}<template>
<div>
<CSVBoxButton
licenseKey="YOUR_LICENSE_KEY_HERE"
:user="{ user_id: 'default123' }"
:onImport="onImport"
:onReady="onReady"
:onClose="onClose"
:onSubmit="onSubmit"
>Import</CSVBoxButton>
</div>
</template>
<script>
import CSVBoxButton from './components/CSVBoxButton'
export default {
name: 'App',
components: {
CSVBoxButton
},
methods: {
onImport(result, data){
console.log("onImport", result, data);
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
},
onReady(){
console.log("onReady");
},
onClose(){
console.log("onClose");
},
onSubmit(data){
console.log("onSubmit");
console.log(data.import_id);
}
},
mounted() {
},
}
</script>Other Settings
Lazy Load
The importer assets are loaded on the webpage load. This can sometimes slow the app if you initialize multiple importers on the same page. As a workaround, you can defer the loading of the importer assets to the Import button click. This can be done by adding the lazy: true parameter to the initialization code.
let importer = new CSVBoxImporter("YOUR_LICENSE_KEY_HERE",{
}, callback, { lazy: true });
import { CSVBoxButton } from '@csvbox/react'
import './App.css';
function App() {
return (
<div className="App">
<CSVBoxButton
licenseKey="YOUR_LICENSE_KEY_HERE"
user={{
user_id: "default123"
}}
onImport={(result, data) => {
if(result){
console.log("success");
console.log(data.row_success + " rows uploaded");
//custom code
}else{
console.log("fail");
//custom code
}
}}
lazy={true}
>
Import
</CSVBoxButton>
</div>
);
}
export default App;@Component({
selector: 'app-root',
template: `
<csvbox-button
[licenseKey]="licenseKey"
[user]="user"
[imported]="imported.bind(this)"
[lazy]="lazy">
Import
</csvbox-button>
`
})
export class AppComponent {
title = 'csvbox-test';
licenseKey = 'YOUR_LICENSE_KEY_HERE';
user = { user_id: 'default123' };
lazy = true;
imported(result: boolean, data: any) {
if(result) {
console.log("Sheet uploaded successfully");
console.log(data.row_success + " rows uploaded");
}else{
console.log("There was some problem uploading the sheet");
}
}
}<CSVBoxButton
:licenseKey="licenseKey"
:user="user"
:onImport="onImport"
:lazy="true">
Upload File
</CSVBoxButton>Last updated
Was this helpful?
