kantan-cms
v0.5.0
Published
Official Node.js TypeScript library for the Kantan CMS API
Maintainers
Readme
Kantan CMS Library
Official TypeScript library for the Kantan CMS API. Supports both browser and Node.js environments.
Installation
npm install kantan-cmsImport Options
This library provides separate entry points for different environments:
Browser/Client-Side
The client export provides browser-safe form utilities without Node.js dependencies:
import { getFormToken, submitForm } from "kantan-cms/client";
// Get form token
const { token } = await getFormToken("collection-id");
// Submit form data
await submitForm("collection-id", {
token,
data: {
name: "John Doe",
email: "[email protected]"
}
});Note: For full API access (collections, records, schemas, etc.) in the browser, use your server as a proxy or use the server version in a Node.js environment.
Server-Side (Node.js with Caching)
Use the full-featured client with file system caching support:
import { KantanCms } from "kantan-cms/server";
const kantan = new KantanCms({
apiKey: "your-api-key",
projectId: "your-project-id",
baseUrl: "https://api.kantan-cms.com", // optional
useCache: true, // Enable caching (Node.js only)
cachePath: "/tmp/my-cache", // Optional cache directory
clearCacheAtInit: true // Optional: clear cache on initialization
});Default Import (Node.js with Caching)
The default import uses the server version:
import { KantanCms } from "kantan-cms";
const kantan = new KantanCms({
apiKey: "your-api-key",
projectId: "your-project-id"
});
// List all collections
const { collections } = await kantan.getCollections({
pageSize: 10,
pageNum: 1
});
console.log(collections);Authentication
You need two credentials to use the Kantan CMS API:
- API Key - Your authentication key
- Project ID - Your project identifier
Both are passed via HTTP headers (X-API-Key and X-Project-Id) and are automatically added by the library.
API Reference
Collections
List Collections
Get a paginated list of collections in your project.
const response = await kantan.listCollections({
pageSize: 10, // optional, default: 10
pageNum: 1, // optional, default: 1
resp: "minimal" // optional
});
// Or use the alias
const response = await kantan.getCollections({ pageSize: 20 });Count Collections
Get the total number of collections.
const { count } = await kantan.countCollections();
console.log(`Total collections: ${count}`);Get Collection
Get a specific collection by ID.
const { collection } = await kantan.getCollection("collection-uuid");
console.log(collection.name, collection.type);Records
List Records
Get all records in a collection with pagination.
const { records } = await kantan.listRecords("collection-uuid", {
pageSize: 20,
pageNum: 1
});
records.forEach(record => {
console.log(record.id, record);
});Get Record
Get a specific record by ID.
const { records } = await kantan.getRecord(
"collection-uuid",
"record-uuid"
);
console.log(records[0]);Count Records
Get the total number of records in a collection.
const { count } = await kantan.countRecords("collection-uuid");
console.log(`Total records: ${count}`);Schemas
Get Schema Type
Get the schema type structure for a collection. Returns a mapping of custom field keys to their respective types.
const { schema_item } = await kantan.getSchemaType("collection-uuid");
// Example output: { "title": "string", "price": "number", "published": "boolean" }
console.log(schema_item);Forms
Get Form Token
Get a form submission token for a specific collection.
const { token } = await kantan.getFormToken("collection-uuid");
console.log(`Form token: ${token}`);Submit Form
Submit data to a form-type collection.
const result = await kantan.submitForm("collection-uuid", {
data: {
name: "John Doe",
email: "[email protected]",
message: "Hello from the API!"
},
token: "your-form-token" // obtained from getFormToken()
});API Key Validation
Validate API Key
Check if your API key is valid.
const { status } = await kantan.validateApiKey();
if (status === 200) {
console.log("API key is valid!");
}Hosting
Generate Presigned URL
Generate a presigned URL for uploading a zip file for hosting.
const { presigned_zip } = await kantan.generatePresignedUrl();
console.log(`Upload URL: ${presigned_zip.url}`);Update Hosting Status
Update the hosting status for your project.
await kantan.updateHostingStatus({
hosting: {
status: "host_complete",
status_message: "Deployment successful"
}
});Available hosting statuses:
host_errorpreview_errorhost_completepreview_completewaitingrunningerror
TypeScript Support
This library is written in TypeScript and includes full type definitions. All API responses are fully typed.
import {
KantanCms,
Collection,
Record,
CollectionType,
HostingStatus
} from "kantan-cms";
const kantan = new KantanCms({
apiKey: process.env.KANTAN_API_KEY!,
projectId: process.env.KANTAN_PROJECT_ID!
});
// Full type inference
const { collections } = await kantan.getCollections();
collections.forEach((collection: Collection) => {
console.log(collection.name);
});Error Handling
The library throws KantanCmsError for API errors.
import { KantanCms, KantanCmsError } from "kantan-cms";
try {
const { collection } = await kantan.getCollection("invalid-uuid");
} catch (error) {
if (error instanceof KantanCmsError) {
console.error(`API Error (${error.statusCode}): ${error.message}`);
console.error("Response:", error.response);
} else {
console.error("Unexpected error:", error);
}
}Advanced Usage
Custom Base URL
If you're using a custom deployment or proxy:
const kantan = new KantanCms({
apiKey: "your-api-key",
projectId: "your-project-id",
baseUrl: "https://custom-api.example.com"
});Environment Support
Browser Usage
The /client export provides form utilities that work in browsers without Node.js dependencies:
// ✅ Browser-safe form functions
import { getFormToken, submitForm } from "kantan-cms/client";The client version:
- ✅ No Node.js dependencies (no
fs,path, etc.) - ✅ Smaller bundle size
- ✅ Works in all modern browsers
- ✅ Perfect for form submissions
- ❌ No full API access (use server as proxy for collections, records, etc.)
Node.js Usage
For full API access, use the server version:
// ✅ Full API with caching
import { KantanCms } from "kantan-cms/server";
// ✅ Or the default import (same as server)
import { KantanCms } from "kantan-cms";The server version includes:
- ✅ Full API access (collections, records, schemas, hosting, etc.)
- ✅ File system caching support
- ✅ Cache management methods
- ✅ Form functions
Framework-Specific Examples
Next.js
Server-side API Route:
// app/api/collections/route.ts
import { KantanCms } from "kantan-cms/server";
export async function GET() {
const kantan = new KantanCms({
apiKey: process.env.KANTAN_API_KEY!,
projectId: process.env.KANTAN_PROJECT_ID!,
useCache: true
});
const { collections } = await kantan.getCollections();
return Response.json({ collections });
}Client-side Form:
// app/contact/page.tsx
"use client"
import { getFormToken, submitForm } from "kantan-cms/client";
import { useState } from "react";
export default function ContactPage() {
const [submitted, setSubmitted] = useState(false);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const { token } = await getFormToken("form-collection-id");
await submitForm("form-collection-id", {
token,
data: {
name: formData.get("name"),
email: formData.get("email"),
message: formData.get("message")
}
});
setSubmitted(true);
}
return (
<form onSubmit={handleSubmit}>
{/* form fields */}
</form>
);
}React (Vite/CRA)
// src/components/ContactForm.tsx
import { getFormToken, submitForm } from "kantan-cms/client";
export function ContactForm() {
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
const { token } = await getFormToken("form-collection-id");
await submitForm("form-collection-id", {
token,
data: { /* form data */ }
});
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}Pagination Helper
Example of paginating through all records:
async function getAllRecords(collectionId: string) {
const allRecords = [];
let pageNum = 1;
const pageSize = 100;
while (true) {
const { records } = await kantan.listRecords(collectionId, {
pageSize,
pageNum
});
if (records.length === 0) break;
allRecords.push(...records);
pageNum++;
if (records.length < pageSize) break; // Last page
}
return allRecords;
}Collection Types
Collections in Kantan CMS can be one of the following types:
custom- Custom content collectionsblog- Blog post collectionsmedia- Media asset collectionsform- Form submission collectionsdict- Dictionary/key-value collections
Requirements
- Node.js >= 18.0.0
- Modern browsers with fetch API support
CommonJS vs ESM
This library supports both CommonJS and ES Modules:
// ESM
import { KantanCms } from "kantan-cms";
// CommonJS
const { KantanCms } = require("kantan-cms");Examples
Blog Integration
// Get all blog posts
const { records: posts } = await kantan.listRecords("blog-collection-id", {
pageSize: 50
});
posts.forEach(post => {
console.log(`${post.title} - ${post.created_at}`);
});Form Submission Flow
// 1. Get form token
const { token } = await kantan.getFormToken("form-collection-id");
// 2. Submit form data
await kantan.submitForm("form-collection-id", {
token,
data: {
fullName: "Jane Smith",
email: "[email protected]",
inquiry: "Product question"
}
});Media Gallery
// Get media collection
const { records: mediaItems } = await kantan.listRecords("media-collection-id");
mediaItems.forEach(item => {
console.log(`${item.filename}: ${item.url}`);
});License
MIT
Support
For issues and questions:
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
