JSPM

@spaceinvoices/embed-sdk

1.0.5
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 33
  • Score
    100M100P100Q59014F
  • License MIT

Embed Space Invoices UI in your application via iframes

Package Exports

  • @spaceinvoices/embed-sdk

Readme

@spaceinvoices/embed-sdk

Embed Space Invoices UI in your application via iframes with customizable themes.

Installation

npm install @spaceinvoices/embed-sdk
# or
yarn add @spaceinvoices/embed-sdk
# or
pnpm add @spaceinvoices/embed-sdk

Quick Start

import { SpaceInvoices } from '@spaceinvoices/embed-sdk';

const si = new SpaceInvoices({
  apiKey: 'ek_live_your_entity_api_key',
  entityId: 'ent_123',
  baseUrl: 'https://invoicing.example.com',
  theme: {
    primary: '#6366f1',
    radius: 8,
  },
  onAction: (action) => {
    console.log('Action:', action);
  },
});

// Open invoice list
si.open('invoices', { container: '#invoice-container' });

// Open invoice list sorted by newest invoice date first
si.open('invoices', {
  container: '#invoice-container',
  searchParams: { order_by: '-date' },
});

Usage via Script Tag

<div id="space-invoices-embed" style="height: 600px;"></div>

<script src="https://unpkg.com/@spaceinvoices/embed-sdk"></script>
<script>
  const si = new SpaceInvoices.SpaceInvoices({
    apiKey: 'ek_live_your_entity_api_key',
    entityId: 'ent_123',
    baseUrl: 'https://invoicing.example.com',
  });

  si.open('invoices');
</script>

Configuration

interface SpaceInvoicesConfig {
  // Required
  apiKey: string;      // Entity API key (ek_live_* or ek_test_*). Authenticates entity access only.
  entityId: string;    // Entity ID

  // Optional
  baseUrl?: string;    // White-label app origin. If omitted, loads https://app.spaceinvoices.com.
  locale?: EmbedLocale; // UI language ("en", "sl", "de", "it", "fr", "es", "pt", "nl", "pl", "hr")
  theme?: ThemeConfig; // Theme customization

  // Callbacks
  onAction?: (action: EmbedAction) => void;
  onReady?: () => void;
  onError?: (error: EmbedError) => void;
  onClose?: () => void;
}

White-label behavior is selected by the embed host, not by the entity API key. Use your managed or custom white-label domain as baseUrl if you want white-label branding, feature gating, billing UI, support contact, and default theme to apply.

If you omit baseUrl, the SDK loads https://app.spaceinvoices.com, which means the embed will authenticate with your entity API key but will use the default Space Invoices white-label.

Available Views

View Description
invoices Invoice list
invoice/new Create new invoice
invoice View invoice (requires id)
estimates Estimate list
estimate/new Create new estimate
estimate View estimate (requires id)
credit-notes Credit note list
credit-note/new Create new credit note
credit-note View credit note (requires id)
advance-invoices Advance invoice list
advance-invoice/new Create new advance invoice
advance-invoice View advance invoice (requires id)
delivery-notes Delivery note list
delivery-note/new Create new delivery note
delivery-note View delivery note (requires id)
customers Customer list
customer/new Create new customer
customer View customer (requires id)
settings/company Company settings
settings/defaults Default settings
settings/numbering Numbering settings
settings/tax Tax settings
settings/furs FURS fiscalization settings
settings/fina FINA settings
settings/e-invoicing E-invoicing settings
settings/templates Document templates settings
export Document export

Theme Customization

const si = new SpaceInvoices({
  apiKey: 'ek_live_...',
  entityId: 'ent_123',
  baseUrl: 'https://invoicing.example.com',
  theme: {
    primary: '#6366f1',    // Primary brand color
    accent: '#8b5cf6',     // Accent color
    background: '#ffffff', // Background color
    foreground: '#1a1a1a', // Text color
    card: '#ffffff',       // Card background
    border: '#e5e5e5',     // Border color
    radius: 8,             // Border radius (px)
    darkMode: false,       // Enable dark mode
  },
});

You can update the theme dynamically:

si.updateTheme({
  primary: '#10b981',
  darkMode: true,
});

Locale

Set the UI language (defaults to browser language detection):

const si = new SpaceInvoices({
  apiKey: 'ek_live_...',
  entityId: 'ent_123',
  locale: 'sl', // Slovenian
});

Supported locales: en, sl, de, it, fr, es, pt, nl, pl, hr

You can update the locale dynamically:

si.setLocale('de'); // Switch to German

Navigate between views without recreating the embed:

// Open invoice list
si.open('invoices');

// Open invoice list with custom initial sorting
si.open('invoices', {
  searchParams: { order_by: '-date' },
});

// Navigate to create form
si.navigate('invoice/new');

// Navigate to view a specific invoice
si.navigate('invoice', { id: 'inv_123' });

Operator Prefill

For multi-user cashier/operator setups, pass operator identity through the existing prefill option. This override is request-scoped and is not persisted to user settings, entity defaults, or local storage.

The host should pass only operator identity. Premise, device, payment type, and skip/fiscalization controls stay inside the Space Invoices UI.

si.open('invoice/new', {
  prefill: {
    operator: {
      label: 'Cashier 2',
      tax_number: '12345678',
    },
  },
});

The embed maps this generic shape to the active fiscalization provider automatically:

  • FURS: tax_number -> operator_tax_number
  • FINA: tax_number -> operator_oib

Initial List State

Pass route search params through searchParams when you want to control the initial state of list views. This is useful for sorting, search, and filters.

si.open('invoices', {
  container: '#invoice-container',
  searchParams: {
    order_by: '-date',
    search: 'Acme',
  },
});

For multi-column sorting, pass an array:

si.open('invoices', {
  searchParams: {
    order_by: ['-date', 'number'],
  },
});

Troubleshooting

White-label branding is not showing up

If the embed authenticates successfully but still looks like Space Invoices, check the baseUrl you passed to the SDK.

  • apiKey selects the entity.
  • baseUrl selects the white-label host.

This combination will authenticate correctly but will not activate white-label behavior:

const si = new SpaceInvoices({
  apiKey: 'ek_live_...',
  entityId: 'ent_123',
  // baseUrl omitted -> defaults to https://app.spaceinvoices.com
});

To apply white-label branding, point the embed at your managed or custom white-label domain:

const si = new SpaceInvoices({
  apiKey: 'ek_live_...',
  entityId: 'ent_123',
  baseUrl: 'https://invoicing.example.com',
});

Actions

Listen for user actions within the embed:

const si = new SpaceInvoices({
  // ...config
  onAction: (action) => {
    switch (action.type) {
      case 'document_created':
        console.log('Created document:', action.data?.id);
        break;
      case 'navigation':
        console.log('Navigated to:', action.data?.path);
        break;
      case 'close_requested':
        // User requested to close the embed
        si.close();
        break;
    }
  },
});

Action Types

Type Description
page_loaded Page finished loading
document_created Document was created
document_updated Document was updated
document_deleted Document was deleted
customer_created Customer was created
customer_updated Customer was updated
customer_deleted Customer was deleted
navigation User navigated within embed
close_requested User requested to close
settings_updated Settings were updated
export_started Document export started
export_completed Document export completed

API Reference

SpaceInvoices

Main SDK class.

Methods

  • open(view, options?) - Open a view in a container
  • navigate(view, options?) - Navigate to a different view
  • updateTheme(theme) - Update theme colors dynamically
  • setLocale(locale) - Change UI language dynamically
  • close() - Close and unmount the embed
  • ready() - Returns a promise that resolves when embed is ready
  • getInstance() - Get current embed instance
  • destroy() - Destroy SDK and clean up resources

EmbedInstance

Returned by open().

interface EmbedInstance {
  id: string;
  container: HTMLElement;
  iframe: HTMLIFrameElement;
  view: EmbedView;
  unmount: () => void;
  navigate: (view, options?) => void;
  updateTheme: (theme) => void;
}

Framework Examples

React

import { useEffect, useRef } from 'react';
import { SpaceInvoices } from '@spaceinvoices/embed-sdk';

function InvoiceEmbed() {
  const containerRef = useRef<HTMLDivElement>(null);
  const sdkRef = useRef<SpaceInvoices | null>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    sdkRef.current = new SpaceInvoices({
      apiKey: 'ek_live_...',
      entityId: 'ent_123',
      onAction: (action) => console.log(action),
    });

    sdkRef.current.open('invoices', { container: containerRef.current });

    return () => sdkRef.current?.destroy();
  }, []);

  return <div ref={containerRef} style={{ height: '600px' }} />;
}

Vue

<template>
  <div ref="container" style="height: 600px" />
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { SpaceInvoices } from '@spaceinvoices/embed-sdk';

const container = ref(null);
let sdk = null;

onMounted(() => {
  sdk = new SpaceInvoices({
    apiKey: 'ek_live_...',
    entityId: 'ent_123',
  });
  sdk.open('invoices', { container: container.value });
});

onUnmounted(() => sdk?.destroy());
</script>

Security

  • The SDK uses entity API keys (ek_*), which are scoped to a single entity
  • All communication happens via postMessage with origin validation
  • Iframes provide complete style isolation and security boundaries
  • API keys should be kept secure and not exposed in client-side code for production use

Browser Support

  • Chrome/Edge 80+
  • Firefox 75+
  • Safari 13.1+

License

MIT