Script tag

One script tag. Any page, any framework.

No bundler, no build step, no package to install. Add the CSVbox script, construct an importer with your license key, and call openModal() from any element — in Svelte, Ember, Rails views, Laravel Blade, or plain server-rendered HTML.

  • Under 10 lines to first import
  • Validated rows only
  • SOC 2 Type II + GDPR
Include<script src="https://js.csvbox.io/script.js"></script>
index.html
<button data-csvbox disabled onclick="importer.openModal();">
  Import
</button>

<script src="https://js.csvbox.io/script.js"></script>
<script>
  function callback(result, data) {
    if (result) {
      console.log("success");
      console.log(data.row_success + " rows uploaded");
    } else {
      console.log("fail");
    }
  }

  let importer = new CSVBoxImporter("YOUR_LICENSE_KEY_HERE", {}, callback);

  importer.setUser({
    user_id: "default123"
  });
</script>

Not every app has a bundler, and not every framework has an official SDK. The plain JavaScript integration is the escape hatch that covers both: it is a single script tag and a constructor, so it works anywhere a browser executes a script.

It is also the most complete surface. The React, Angular, and Vue packages are wrappers around this same importer, so every option and every event documented here is available in the framework SDKs too — just spelled as props instead of method calls.

Because there is no build step, this is usually the fastest way to prove the importer out. Paste the snippet into a page, swap in your license key, and you have a working import flow before you have decided where it belongs in your app.

  • No npm install, no bundler, no build step — one script tag
  • Works in Svelte, Ember, Rails views, Laravel Blade, and static HTML
  • The full option and event surface the framework SDKs wrap
  • Imperative API — construct once, then openModal() from anything

How it works

  1. 1
    Add the script

    Drop the js.csvbox.io script tag into your page. Nothing else needs to change in your build, because there is no build.

  2. 2
    Construct the importer

    Call new CSVBoxImporter(licenseKey, options, callback). The options object is where row limits, language, theme, and custom headers go.

  3. 3
    Identify the user

    Call importer.setUser({ user_id: "..." }). user_id is mandatory; add any other attributes you want echoed back to your destination.

  4. 4
    Open it from any element

    Call importer.openModal() from a click handler on whatever element you like. Your callback fires with (result, data) when the import completes.

Time to first import: ~5 minutes — there is no install step to wait on.

No build step, no bundler. Drop the script tag in and call openModal() from any element.

Importer methods

MethodSignatureWhat it does
CSVBoxImporternew CSVBoxImporter(licenseKey, options, callback, settings)Constructs the importer. The callback receives (result, data) when an import finishes.
setUsersetUser(userObject)Attaches user attributes to the import. user_id is mandatory.
setOptionssetOptions(optionsObject)Updates options after construction — useful when they depend on state you do not have yet.
openModalopenModal()Opens the importer. Call it from any click handler.
listenlisten(eventName, callback)Subscribes to a lifecycle event: onReady, onLoadStart, onSubmit, onClose, or onImport.
Full JavaScript install docs

Options, events, and a custom trigger

import.html
<button id="import-btn">Import customers</button>

<script src="https://js.csvbox.io/script.js"></script>
<script>
  var importer = new CSVBoxImporter(
    "YOUR_LICENSE_KEY_HERE",
    {
      max_rows: 50000,
      language: "en",
      allow_invalid: false,
      theme: "light",
      lazy: true
    },
    function (result, data) {
      if (result) {
        console.log(data.row_success + " rows uploaded");
      } else {
        console.log("import failed");
      }
    }
  );

  importer.setUser({
    user_id: "default123",
    workspace_id: "ws_42"
  });

  importer.listen("onReady", function () {
    document.getElementById("import-btn").disabled = false;
  });

  importer.listen("onClose", function () {
    console.log("user closed the importer");
  });

  document
    .getElementById("import-btn")
    .addEventListener("click", function () {
      importer.openModal();
    });
</script>

Any element can be the trigger — there is no CSVbox button to style around. Construct the importer once, then call openModal() from as many handlers as you need.

Commonly used options

OptionWhat it controls
max_rows / min_rowsRow-count bounds enforced before the user can submit.
max_rows_allow_submitWhether an over-limit file may still be submitted.
max_rows_custom_message / min_rows_custom_messageThe message shown when a row-count bound is breached.
languageInterface language for the importer.
allow_invalidWhether rows that fail validation may still be submitted.
request_headersExtra HTTP headers sent with the import request.
dynamic_list_request_headersHeaders used when fetching dynamic dropdown values.
sample_template_url / sample_template_button_textLink and label for a downloadable sample file.
target_file_nameName recorded for the uploaded file.
upload_file_url / upload_file_worksheet_namePre-load a file, and the worksheet within it, instead of asking the user to pick one.
themeColour theme applied to the importer UI.
default_header_rowWhich row to treat as the header by default.
lazyDefer loading the importer until it is opened.

Frameworks without an official SDK

If we do not ship a package for your framework, this is the integration. It is the same importer the SDKs wrap, so nothing is missing.

Svelte / SvelteKit

Add the script to app.html and construct the importer inside onMount so it only runs in the browser.

Ember

Load the script in index.html and construct the importer from a component’s didInsertElement hook.

Rails / Laravel Blade

Add the script tag to your layout and construct the importer in the view that needs it — no JavaScript build required.

Static and server-rendered HTML

Paste the snippet into the page. There is nothing else to configure.

Common use cases

Proving it out fast

Drop the snippet into any page to see the full import flow against your real schema before you commit to where it lives.

Legacy applications

Add a modern import experience to an app with no bundler and no front-end framework, without touching its build.

Server-rendered admin tools

Rails, Laravel, and Django admin screens get the same importer as your main product, with one script tag.

Frameworks off the SDK list

Svelte, Ember, Alpine, htmx, or anything else — if it renders HTML, the snippet works.

JavaScript import questions, answered

Do I need npm or a bundler?

No. The plain JavaScript integration is a script tag and a constructor. Nothing is installed, nothing is compiled, and your existing build — if you have one — does not change.

Is the plain snippet less capable than the SDKs?

No, it is the other way round. The React, Angular, and Vue packages are wrappers around this same importer, so every option and event available here is available through them too.

How do I open the importer from a custom element?

Construct the importer once, then call importer.openModal() from any click handler. There is no CSVbox-rendered button to work around, so the trigger is entirely yours.

Can I change options after construction?

Yes. Call importer.setOptions() with a new options object. That is useful when a value — a row limit or a request header — depends on state you do not have at page load.

Which lifecycle events can I subscribe to?

Use importer.listen() with onReady, onLoadStart, onSubmit, onClose, or onImport to drive your own loading states, analytics, and post-import refreshes.

Which frameworks does this cover?

Any framework without an official SDK — Svelte, Ember, Alpine, htmx — plus server-rendered templates like Rails views and Laravel Blade, and plain static HTML.

JavaScript picks the SDK. Your back end picks the destination.

The SDK you install has nothing to do with where the data lands. Whatever you run server-side — Node, Rails, Django, Laravel, Go, .NET, or no server at all — CSVbox delivers validated rows to your webhook, database, or no-code tool.

Browse 20+ destinations

Stop building CSV importers.

Ship ours in 15 minutes. Free forever on the Sandbox plan.

No credit cardEmbed in minutesSecure by default