Complete reference of all TypeScript types, client methods, and React hooks. Types and client are exported from @vlozi/blog. React hooks are exported from @vlozi/blog/react.
Types
Post
interface Post {
title: string;
slug: string; // canonical React key — use post.slug, NOT post.id
excerpt: string;
content?: string; // HTML (only on single post)
publishedAt: string; // ISO-8601
seoTitle?: string;
seoDescription?: string;
featuredImageUrl?: string | null;
category?: Category | null;
tags?: Tag[];
author?: Author | null;
readingTime?: number; // Estimated minutes; computed client-side if missing
}IMPORTANT
The Post type has no id field. The public API never returns one. Always use post.slug as your React key — it's URL-safe, unique across published posts, and stable.
Category
interface Category {
name: string;
slug: string;
postCount?: number; // Number of published posts
}Tag
interface Tag {
name: string;
slug: string;
postCount?: number; // Number of published posts
}Author
interface Author {
name: string; // Display name
slug?: string; // URL-safe identifier (for /authors/:slug pages)
avatarUrl?: string; // Absolute URL to a 1:1 avatar
bio?: string; // Short plain-text bio
url?: string; // Website or profile URL
}ListParams
interface ListParams {
page?: number; // default: 1
limit?: number; // default: 10, max: 100
category?: string | string[]; // slug, or array for OR-match
tag?: string | string[]; // slug, or array for OR-match
search?: string; // search title & excerpt
sort?: "publishedAt" | "title" | "createdAt"; // default: "publishedAt"
order?: "asc" | "desc"; // default: "desc"
}ArchiveGroup
interface ArchiveGroup {
year: number;
month: number; // 1–12
monthName: string; // "January", "February", ...
posts: Post[];
count: number;
}ArchiveResult
interface ArchiveResult {
groups: ArchiveGroup[]; // Sorted newest first
totalPosts: number; // Across all groups
}NeighborsResult
interface NeighborsResult {
previous: Post | null; // Older adjacent post
next: Post | null; // Newer adjacent post
}PaginatedResponse<T>
interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
limit: number;
total: number;
totalPages: number;
};
}VloziConfig
interface VloziConfig {
apiKey: string; // Your public API key
baseUrl: string; // Your gateway URL
}Client methods
| Method | Returns | Description |
|---|---|---|
client.blog.list(params?) |
PaginatedResponse<Post> |
List published posts with filtering, search, and sort. |
client.blog.get(slug) |
Post |
Get a single published post by slug (includes HTML content). |
client.blog.categories.list() |
{ data: Category[] } |
List all categories with post counts. |
client.blog.tags.list() |
{ data: Tag[] } |
List all tags with post counts. |
client.blog.archive(options?) |
ArchiveResult |
All posts grouped by year/month. options.maxPosts caps the total. Client-side paginates internally. |
client.blog.related(slug, options?) |
Post[] |
Posts related to slug by category/tag overlap scoring. Options: limit (default 3), pool (default 100). |
client.blog.neighbors(slug, options?) |
NeighborsResult |
Previous/next posts in publication order. Options: pool (default 500). |
React hooks
| Hook | Input | Key returns |
|---|---|---|
usePosts(params?) |
ListParams | data, loading, error, refetch, page, totalPages, hasNextPage, hasPrevPage |
usePost(slug) |
string | data, loading, error |
useCategories() |
— | data (Category[]), loading, error, refetch |
useTags() |
— | data (Tag[]), loading, error, refetch |
useArchive(options?) |
{ maxPosts? } |
data (ArchiveResult), loading, error, refetch |
useRelatedPosts(slug, options?) |
string, { limit?, pool? } |
data (Post[]), loading, error |
useNeighbors(slug, options?) |
string, { pool? } |
data (NeighborsResult), loading, error |
useVlozi() |
— | VloziClient from context. Advanced: call client methods imperatively, prefetch on hover, wire into your own data layer. |