Back to Docs

API Reference

Complete API documentation for BlogFlow SDK

import { BlogFlow } from '@blogflow/sdk';

const client = new BlogFlow({
  apiKey: 'your_api_key',
  baseUrl: 'https://blogflow-api-server.vercel.app/api/v2', // optional
  defaultLanguage: 'en' // optional, defaults to 'en' if not specified
});
// Get posts with language and limit
const posts = await client.getPosts({
  lang: 'zh',
  limit: 20,
  offset: 0
});

// Search posts
const searchResults = await client.getPosts({
  search: 'react',
  searchFields: ['title', 'excerpt']
});

// Sort posts
const sortedPosts = await client.getPosts({
  sort: 'created_at',
  order: 'desc',
  limit: 10
});

// Next.js ISR cache (revalidate every 60 seconds)
const cachedPosts = await client.getPosts({
  next: { revalidate: 60 }
});

// Next.js on-demand revalidation with tags
const taggedPosts = await client.getPosts({
  next: { tags: ['posts'] }
});

Parameters:

  • lang? - Language code: 'en' | 'zh' | 'es' | 'fr' | 'de' | 'ja' | 'ko'
  • limit? - Number of posts (default: 20, max: 100)
  • offset? - Pagination offset (default: 0)
  • sort? - Sort field: 'id' | 'created_at' | 'updated_at'
  • order? - Sort order: 'asc' | 'desc'
  • search? - Search keyword
  • searchFields? - Fields to search: ['title', 'excerpt', 'category', 'slug']
  • next? - Next.js cache options: { revalidate?: number, tags?: string[] }
  • cache? - Standard fetch cache option

Returns: Promise<V2PostListItem[]>

// Get a post by slug
const post = await client.getPost('my-article-slug', {
  lang: 'zh'
});

// With Next.js ISR cache (revalidate every hour)
const cachedPost = await client.getPost('my-article-slug', {
  lang: 'zh',
  next: { revalidate: 3600 }
});

// With cache tags for on-demand revalidation
const taggedPost = await client.getPost('my-article-slug', {
  next: { tags: ['posts', 'my-article-slug'] }
});

Parameters:

  • slug - Post slug (required)
  • options.lang? - Language code
  • options.next? - Next.js cache options
  • options.cache? - Standard fetch cache option

Returns: Promise<V2Post>

// Get paginated posts
const result = await client.getPaginatedPosts({
  page: 1,
  pageSize: 12,
  lang: 'zh'
});

// Access pagination metadata
console.log(result.items);        // Array of posts
console.log(result.page);          // Current page number
console.log(result.pageSize);      // Posts per page
console.log(result.totalCount);    // Total number of posts
console.log(result.totalPages);    // Total number of pages
console.log(result.hasNextPage);   // Boolean
console.log(result.hasPreviousPage); // Boolean

// With search
const searchResult = await client.getPaginatedPosts({
  page: 1,
  pageSize: 20,
  search: 'javascript',
  lang: 'en'
});

Parameters:

  • page? - 1-based page number (default: 1)
  • pageSize? - Posts per page (default: 12, max: 100)
  • All parameters from getPosts() are also supported

Returns: Promise<V2PaginatedPostsResponse>

Response includes: items, page, pageSize, totalCount, totalPages, hasNextPage, hasPreviousPage

Type Definitions

Complete TypeScript type definitions for all API methods and responses.

interface BlogFlowConfig {
  apiKey: string;                    // Required: Your API key
  baseUrl?: string;                  // Optional: API server URL
  defaultLanguage?: SupportedLanguage; // Optional: Default language
}
interface V2PostListItem {
  id: number;
  title: string;
  slug: string;
  category?: string | null;
  featured_image_url?: string | null;
  created_at: string;  // ISO 8601 format
  excerpt?: string | null;
}
interface V2Post {
  id: number;
  title: string;
  slug: string;
  content: string;                   // Full HTML content
  excerpt?: string | null;
  category?: string | null;
  featured_image_url?: string | null;
  featured_image_alt?: string | null;
  seo_title?: string | null;
  seo_description?: string | null;
  created_at: string;                // ISO 8601 format
}
interface V2PaginatedPostsResponse {
  items: V2PostListItem[];
  page: number;
  pageSize: number;
  totalCount: number;
  totalPages: number;
  hasNextPage: boolean;
  hasPreviousPage: boolean;
}
type SupportedLanguage = 
  | 'en'  // English
  | 'zh'  // Chinese
  | 'es'  // Spanish
  | 'fr'  // French
  | 'de'  // German
  | 'ja'  // Japanese
  | 'ko'; // Korean

Error Handling

Learn how to handle errors gracefully in your application.

// Base error class
class BlogFlowError extends Error {
  statusCode?: number;
  details?: string;
}

// Authentication error (401)
class BlogFlowAuthError extends BlogFlowError

// Not found error (404)
class BlogFlowNotFoundError extends BlogFlowError

// Server error (500)
class BlogFlowServerError extends BlogFlowError
import { 
  BlogFlow, 
  BlogFlowError,
  BlogFlowAuthError,
  BlogFlowNotFoundError,
  BlogFlowServerError
} from '@blogflow/sdk';

try {
  const post = await client.getPost('my-slug');
} catch (error) {
  if (error instanceof BlogFlowAuthError) {
    // Handle authentication error (401)
    console.error('Invalid API key:', error.message);
  } else if (error instanceof BlogFlowNotFoundError) {
    // Handle not found error (404)
    console.error('Post not found:', error.message);
  } else if (error instanceof BlogFlowServerError) {
    // Handle server error (500)
    console.error('Server error:', error.message, error.details);
  } else if (error instanceof BlogFlowError) {
    // Handle other errors
    console.error('Error:', error.message, error.statusCode);
  } else {
    // Handle unexpected errors
    console.error('Unexpected error:', error);
  }
}

Return Types

Detailed structure of all return types and response objects.

// Returns: Promise<V2PostListItem[]>
[
  {
    id: 1,
    title: "Getting Started with Next.js",
    slug: "getting-started-with-nextjs",
    category: "Tutorial",
    featured_image_url: "https://example.com/image.jpg",
    created_at: "2024-01-15T10:30:00Z",
    excerpt: "Learn how to build modern web apps..."
  },
  // ... more posts
]
// Returns: Promise<V2Post>
{
  id: 1,
  title: "Getting Started with Next.js",
  slug: "getting-started-with-nextjs",
  content: "<h1>Getting Started</h1><p>Full HTML content...</p>",
  excerpt: "Learn how to build modern web apps...",
  category: "Tutorial",
  featured_image_url: "https://example.com/image.jpg",
  featured_image_alt: "Next.js logo",
  seo_title: "Next.js Tutorial - Complete Guide",
  seo_description: "Learn Next.js from scratch...",
  created_at: "2024-01-15T10:30:00Z"
}
// Returns: Promise<V2PaginatedPostsResponse>
{
  items: [
    { id: 1, title: "Post 1", slug: "post-1", ... },
    { id: 2, title: "Post 2", slug: "post-2", ... },
    // ... 12 posts
  ],
  page: 1,
  pageSize: 12,
  totalCount: 150,
  totalPages: 13,
  hasNextPage: true,
  hasPreviousPage: false
}

Use Cases & Examples

Real-world examples and best practices for common scenarios.

// app/blog/page.tsx
import { BlogFlow } from '@blogflow/sdk';

const client = new BlogFlow({
  apiKey: process.env.BLOGFLOW_API_KEY!,
});

export default async function BlogPage() {
  // ISR: Revalidate every 60 seconds
  const posts = await client.getPosts({
    lang: 'en',
    limit: 20,
    next: { revalidate: 60 }
  });

  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  );
}
// app/blog/[slug]/page.tsx
import { BlogFlow } from '@blogflow/sdk';

const client = new BlogFlow({
  apiKey: process.env.BLOGFLOW_API_KEY!,
});

export async function generateStaticParams() {
  const posts = await client.getPosts({ limit: 100 });
  return posts.map(post => ({ slug: post.slug }));
}

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await client.getPost(params.slug, {
    lang: 'en',
    next: { revalidate: 3600 } // Cache for 1 hour
  });

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  );
}
// app/search/page.tsx
import { BlogFlow } from '@blogflow/sdk';

const client = new BlogFlow({
  apiKey: process.env.BLOGFLOW_API_KEY!,
});

export default async function SearchPage({ 
  searchParams 
}: { 
  searchParams: { q?: string } 
}) {
  const query = searchParams.q || '';
  
  const results = await client.getPosts({
    search: query,
    searchFields: ['title', 'excerpt', 'category'],
    limit: 20
  });

  return (
    <div>
      <h1>Search Results for "{query}"</h1>
      {results.map(post => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  );
}
// app/blog/page.tsx
import { BlogFlow } from '@blogflow/sdk';

const client = new BlogFlow({
  apiKey: process.env.BLOGFLOW_API_KEY!,
});

export default async function BlogPage({ 
  searchParams 
}: { 
  searchParams: { page?: string } 
}) {
  const currentPage = parseInt(searchParams.page || '1');

  const result = await client.getPaginatedPosts({
    page: currentPage,
    pageSize: 12,
    lang: 'en'
  });

  return (
    <div>
      <div>
        {result.items.map(post => (
          <article key={post.id}>{post.title}</article>
        ))}
      </div>
      
      <div>
        <p>Page {result.page} of {result.totalPages}</p>
        {result.hasPreviousPage && (
          <a href={"?page=" + (currentPage - 1)}>Previous</a>
        )}
        {result.hasNextPage && (
          <a href={"?page=" + (currentPage + 1)}>Next</a>
        )}
      </div>
    </div>
  );
}

Frequently Asked Questions

Common questions and solutions for using BlogFlow SDK.

Contact your administrator or visit your BlogFlow dashboard to obtain an API key. Keep your API key secure as it's used for authentication.

The SDK supports 7 languages: English (en), Chinese (zh), Spanish (es), French (fr), German (de), Japanese (ja), and Korean (ko).

Use the next parameter to configure ISR (Incremental Static Regeneration) caching. For example: next: { revalidate: 60 } will revalidate the cache every 60 seconds. Use tags for on-demand revalidation.

The SDK provides specific error classes: BlogFlowAuthError (401), BlogFlowNotFoundError (404), BlogFlowServerError (500). Use try-catch blocks to catch and handle these errors appropriately.

getPosts() returns a simple array of posts, suitable for list displays. getPaginatedPosts() returns a response object with pagination metadata (total pages, has next page, etc.), suitable for scenarios requiring pagination controls.

Use the search parameter to search the entire database on the server side, not just loaded posts. This is 10-100x faster than client-side search. You can specify searchFields to limit the search scope.