Skip to content

Getting Started

After creating your project in Skapi, connect it to your frontend.

Your frontend is the part users see, such as pages, buttons, and forms. It can be plain HTML or a JavaScript framework like Vue or React.

Skapi works with vanilla HTML and modern JavaScript frameworks (for example Vue, React, and Angular).

To use Skapi, import the library and initialize it with your project ID.

For HTML Projects

For vanilla HTML projects, import Skapi using a script tag and initialize the library as shown below. Initialize the Skapi class in the HTML <head> of each page that uses Skapi. When you initialize the class, use the exact project ID from your Skapi dashboard.

html
<!-- index.html -->
<!DOCTYPE html>
<script src="https://cdn.jsdelivr.net/npm/skapi-js@latest/dist/skapi.js"></script>
<script>
    // Replace "<Project ID>" with your actual project ID
    const skapi = new Skapi("<Project ID>");
</script>

Replace the placeholder

"<Project ID>" is a placeholder, including the angle brackets. Replace the whole string with your actual project ID from your Skapi dashboard after you create a project, so the line reads like this:

js
const skapi = new Skapi("abc123defg456hij78-9klmnop012qrstu345vwxyz");

Every example in these docs uses the same "<Project ID>" placeholder, so replace it wherever you copy one.

The project ID is a single token that identifies your project and its owner.

Example format: "xxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxx"

For BunnyQuery users

A BunnyQuery project ID is a Skapi project ID; use it as-is.

For SPA Projects

To use Skapi in a Single Page Application (SPA) such as Vue, React, or Angular, install skapi-js with npm.

sh
$ npm i skapi-js

Then import the library in your main JavaScript file:

javascript
// main.js
import { Skapi } from "skapi-js";
const skapi = new Skapi("<Project ID>");

export { skapi }

// You can now import skapi from anywhere in your project.

For TypeScript Projects

Skapi includes TypeScript support, so you can import both the class and related types.

typescript
import { Skapi } from 'skapi-js';
import type { RecordData, DatabaseResponse } from 'skapi-js';

const skapi = new Skapi("<Project ID>");
let databaseRecords: DatabaseResponse<RecordData>;

Node.js (CommonJS)

To use Skapi in Node.js (CommonJS), import the library as shown below:

javascript
const { Skapi } = require('skapi-js');
const skapi = new Skapi("<Project ID>");

Node.js (ESM)

javascript
import { Skapi } from 'skapi-js';
const skapi = new Skapi("<Project ID>");

Note: When running Skapi in Node.js, browser-specific features such as WebSocket, WebRTC, and Notifications are not available.

Get Connection Information

After your client connects to Skapi, call getConnectionInfo() to retrieve connection details.

html
<!-- index.html -->
<!DOCTYPE html>
<script src="https://cdn.jsdelivr.net/npm/skapi-js@latest/dist/skapi.js"></script>
<script>
    const skapi = new Skapi("<Project ID>");
</script>
<script>
skapi.getConnectionInfo().then(info => {
    console.log(info);
    /*
    Returns:
    {
        project_id: "Public project ID of the connected project",
        user_ip: "Connected user's IP address",
        user_agent: "Connected user agent",
        user_location: "Connected user's country code",
        service_name: "Your Project Name",
        service_description: "Your project description",
        version: 'x.x.x', // Skapi library version
        ai_agent: "AI agent instructions set for the project",
        conf: {
            freeze_database: boolean, // Database is read only
            prevent_signup: boolean, // Signup is blocked
            prevent_inquiry: boolean, // Inquiry is blocked
            prevent_anonymous: boolean // Anonymous users cannot write to the database
        }
    }
    */
   window.alert(`Connected to ${info.service_name}`);
});
</script>
javascript
import { skapi } from '../location/of/your/main.js';
skapi.getConnectionInfo().then(info => {
    console.log(info);
    /*
    Returns:
    {
        project_id: "Public project ID of the connected project",
        user_ip: "Connected user's IP address",
        user_agent: "Connected user agent",
        user_location: "Connected user's country code",
        service_name: "Your Project Name",
        service_description: "Your project description",
        version: 'x.x.x', // Skapi library version
        ai_agent: "AI agent instructions set for the project",
        conf: {
            freeze_database: boolean, // Database is read only
            prevent_signup: boolean, // Signup is blocked
            prevent_inquiry: boolean, // Inquiry is blocked
            prevent_anonymous: boolean // Anonymous users cannot write to the database
        }
    }
    */
   window.alert(`Connected to ${info.service_name}`);
});

Advanced Settings

You can pass additional options when initializing the Skapi class.

new Skapi(...)

ts
class Skapi {
  constructor(
    project_id: string, // Skapi project ID. The legacy service ID + owner ID pair is still accepted.
    options?: {
        autoLogin?: boolean;        // Default: true
        refetchServiceInfo?: boolean;// Default: false. Bypasses cached project info and always fetch new project info on load.
        requestBatchSize?: number;  // Default: 30. Maximum number of requests processed per batch.
        encryption?: boolean | { // Default: false. Encrypts the data of private records in the browser. Can only be set here, on initialization.
            iterations?: number;             // Default: 600000. PBKDF2 cost. Minimum 100000.
            minPasswordLength?: number;      // Default: 0 (off). Refuses to set up encryption for a shorter password.
            persistDevice?: boolean;         // Default: true. Stays unlocked across page reloads on that device.
            recovery?: 'code' | 'none';      // Default: 'code'. Issues a one-time recovery code.
            trustPolicy?: 'tofu' | 'strict'; // Default: 'tofu'. How a recipient's public key is trusted when sharing.
            withheld?: 'null' | 'sentinel';  // Default: 'null'. What data is set to when a record cannot be decrypted.
            table?: string;                  // Default: 'skapi__keyring'. Reserved table that stores the user's keyring.
        };
        eventListener?: {
            onLogin?: (user: UserProfile | null) => void; // Fires on initial page load (after Skapi initializes), on login/logout, and when a session expires. The callback receives a UserProfile object if the user is logged in; otherwise, it receives null.
            onUserUpdate?: (user: UserProfile | null) => void; // Fires on initial page load (after Skapi initializes), on login/logout, when a session expires, and when the user's profile is updated. The callback receives a UserProfile object if the user is logged in; otherwise, it receives null.
            onBatchProcess?: (process: {
                batchToProcess: number; // Number of batches left to process
                itemsToProcess: number; // Number of items left to process
                completed: any[]; // Results completed in this batch
            }) => void;
        }
    }) {
    ...
  }
  ...
}

Options overview:

  • autoLogin (boolean, default: true)

    • Automatically restores the user's session on page load.
    • See: Auto Login
  • requestBatchSize (number, default: 30)

    • Maximum number of requests processed per batch.
  • encryption (boolean | object, default: false)

    • Encrypts the data of the records saved to access_group: 'private', in the browser, before it reaches the database. The contents of the files attached to those records are encrypted as well.
    • This only takes effect when it is set here, when the Skapi class is initialized. There is no method that turns encryption on afterwards, so when this option is left out, the instance saves the data of every record as plain text for its entire lifetime.
    • Enabling it later does not go back and encrypt the records that were already saved as plain text.
    • Setting it to true uses the default settings. Pass an object to change them:
      • iterations (number, default: 600000): PBKDF2 cost of deriving the key from the user's password. Minimum 100000.
      • minPasswordLength (number, default: 0, off): refuses to set up encryption for a password shorter than this. The strength of the encryption is capped by the user's password, so it is worth setting.
      • persistDevice (boolean, default: true): keeps encryption unlocked across page reloads on that device.
      • recovery ('code' | 'none', default: 'code'): issues a one-time recovery code, which is the only way for the user to reach their data again after a password reset.
      • trustPolicy ('tofu' | 'strict', default: 'tofu'): how a recipient's public key is trusted when a record is shared. 'strict' requires the key to be pinned before the first share.
      • withheld ('null' | 'sentinel', default: 'null'): what data is set to when a record cannot be decrypted. 'sentinel' returns a placeholder object carrying the reason instead of null.
      • table (string, default: 'skapi__keyring'): the reserved table that stores the user's keyring.
    • See: Encrypting Private Record Data
  • eventListener (callbacks for key events)

    • onLogin(user: UserProfile | null)

      • Fires on initial page load (after Skapi initializes), on login/logout, and when a session expires. The callback receives a UserProfile object if the user is logged in; otherwise, it receives null.
      • See: Listening to Login/Logout Status
    • onUserUpdate(user: UserProfile | null)

      • Fires on initial page load (after Skapi initializes), on login/logout, when a session expires, and when the user's profile is updated. The callback receives a UserProfile object if the user is logged in; otherwise, it receives null.
      • See: Listening to User Profile Updates
    • onBatchProcess(process)

      • Fires each time Skapi completes processing a request batch.

Type reference: See UserProfile.