Dokumentasi Resmi
|tulis.orgArsitektur Dokumentasi
Peta jalan panduan, SDK integration, dan API reference lengkap yang disiapkan secara terstruktur.
TULIS CMS/DEVELOPER HUB
/sdks-javascript-fetch
API Publik Tulis — Contoh JavaScript (fetch)
Klien kecil yang dapat digunakan kembali yang dibangun di atas API fetch native untuk API publik Tulis headless CMS.
Peringatan keamanan: Simpan kunci API di sisi server. Jangan pernah mengirim
apiKeyke browser. HeaderAuthorization: Bearerhanya boleh dilampirkan di lingkungan server tepercaya (Node.js, fungsi serverless, dll.).
Pembantu klien
type TulisClientOptions = {
apiKey: ***
workspaceId: string;
host: string;
};
function createTulisClient({ apiKey, workspaceId, host }: TulisClientOptions) {
const base = `${host.replace(/\/$/, "")}/v1`;
async function request<T>(path: string, init: RequestInit = {}): Promise<T> {
const res = await fetch(`${base}${path}`, {
...init,
headers: {
"Authorization": `Bearer ${apiKey}`,
"X-Workspace-ID": workspaceId,
...(init.headers ?? {}),
},
});
if (!res.ok) {
throw new Error(`Tulis API error ${res.status}: ${res.statusText}`);
}
return (await res.json()) as T;
}
return {
listPosts(opts: { page?: number; perPage?: number } = {}) {
const params = new URLSearchParams();
if (opts.page) params.set("page", String(opts.page));
if (opts.perPage) params.set("per_page", String(opts.perPage));
const qs = params.toString();
return request<{
status: string;
message: string;
data: any[];
meta: { Page: number; PerPage: number; Total: number; TotalPages: number; HasNext: boolean; HasPrev: boolean };
}>(`/posts${qs ? `?${qs}` : ""}`);
},
getPost(slugOrId: string) {
return request<{ status: string; message: string; data: any; json_ld: object }>(
`/posts/${encodeURIComponent(slugOrId)}`
);
},
listTaxonomies(type: "category" | "tag") {
return request<{ status: string; message: string; data: any[] }>(
`/taxonomies?type=${encodeURIComponent(type)}`
);
},
listComments(postId: string) {
return request<{ status: string; message: string; data: any[] }>(
`/posts/${encodeURIComponent(postId)}/comments`
);
},
createComment(payload: { name: string; email: string; post_id: string; content: string }) {
return request<{ status: string; message: string; data: any }>(`/comments`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
},
};
}
export { createTulisClient };
export type { TulisClientOptions };Contoh penggunaan — render daftar posting
import { createTulisClient } from "./tulis-client.js";
// PENTING: jalankan ini hanya di server di mana kunci tidak terekspos ke browser.
const tulis = createTulisClient({
apiKey: process.env.TULIS_API_KEY,
workspaceId: process.env.TULIS_WORKSPACE_ID,
host: process.env.TULIS_HOST,
});
async function renderPostList() {
const { data: posts, meta } = await tulis.listPosts({ page: 1, perPage: 10 });
for (const post of posts) {
console.log(`- ${post.title} (${post.slug})`);
}
console.log(`Halaman ${meta.Page}/${meta.TotalPages}, total: ${meta.Total}`);
}
renderPostList().catch((err) => console.error(err));Lini Masa Peluncuran Fitur
Fase 1: Setup Awal & KonfigurasiSELESAI
Docker Compose, pengaturan file environment, dan panduan setup lokal telah lengkap dibuat.
Fase 2: Referensi RESTful APISELESAI
Dokumentasi route endpoint publik, otentikasi JWT, dan kontrol hak akses telah selesai disusun.
Fase 3: Integrasi Frontend & Fitur LanjutSEDANG BERJALAN
Mempersiapkan boilerplate untuk Next.js client, manajemen revisi konten, dan optimasi query.