2.2.0 • Published 5 months ago
pmkin v2.2.0
PMKIN JavaScript SDK
PMKIN is a lightweight headless CMS designed for developers who want to focus on building rather than managing complex content infrastructure. It provides a simple GraphQL API to manage and deliver your content, making it perfect for blogs, documentation sites, and other content-driven applications.
Installation
bun add pmkin
# or
npm install pmkin
# or
yarn add pmkin
# or
pnpm add pmkin
Getting Started (Next.js)
Setup Client
First, create a PMKIN client instance. Create a new file lib/pmkin.ts
:
import { PmkinClient } from 'pmkin'
if (!process.env.PMKIN_TOKEN) {
throw new Error('PMKIN_TOKEN is not set')
}
export const pmkin = new PmkinClient({
token: process.env.PMKIN_TOKEN
})
Add your PMKIN token to your .env.local
file:
PMKIN_TOKEN=your_token_here
List Blog Posts
Create a blog posts listing page at app/blog/page.tsx
:
import Link from 'next/link'
import { pmkin } from '@/lib/pmkin'
// Revalidate every hour
export const revalidate = 3600
export default async function BlogPage() {
const posts = await pmkin.listDocuments()
return (
<div className="prose lg:prose-xl">
{posts.map((post) => (
<article key={post.id}>
<h2>{post.title}</h2>
{post.subtitle && <p>{post.subtitle}</p>}
<Link href={`/blog/${post.slug}`}>Read more</Link>
</article>
))}
</div>
)
}
Show a Single Blog Post
Create a dynamic route for individual blog posts at app/blog/[slug]/page.tsx
:
import { notFound } from 'next/navigation'
import Markdown from 'react-markdown'
import { pmkin } from '@/lib/pmkin'
interface PageProps {
params: {
slug: string
}
}
// Revalidate every hour
export const revalidate = 3600
export default async function BlogPostPage({ params }: PageProps) {
const post = await pmkin.findDocumentBySlug(params.slug)
if (!post) {
notFound()
}
return (
<article className="prose lg:prose-xl">
<h1>{post.title}</h1>
{post.subtitle && <p>{post.subtitle}</p>}
<Markdown>
{post.markdown}
</Markdown>
</article>
)
}
Error Handling
The client methods can throw different types of errors depending on the API response:
try {
const posts = await pmkin.listDocuments()
} catch (error) {
if (error instanceof GraphQLError) {
// GraphQL validation or execution errors
console.error('GraphQL Error:', error.message)
} else if (error instanceof UnauthorizedError) {
// Invalid or expired token
console.error('Authentication failed')
} else if (error instanceof RateLimitError) {
// Too many requests
console.error('Rate limit exceeded')
} else if (error instanceof InvalidResponseError) {
// Invalid response format
console.error('Invalid API response:', error.response)
} else if (error instanceof RequestError) {
// Other HTTP errors
console.error('Request failed:', error.message)
}
}
Error Types
GraphQLError
: Thrown when the GraphQL query is invalid or fails to executeUnauthorizedError
: Thrown when the API token is invalid or expired (HTTP 401)RateLimitError
: Thrown when you've exceeded the rate limit (HTTP 429)InvalidResponseError
: Thrown when the API response format is invalidRequestError
: Thrown for other HTTP errors (like 503 Service Unavailable)
Not Found Cases
Methods that fetch single items return undefined
when the item is not found:
const post = await pmkin.findDocumentBySlug('non-existent')
if (!post) {
// Handle not found case
}
API Reference
PmkinClient
const client = new PmkinClient({
token: string // Your PMKIN API token
})
Documents
// List all documents
const posts = await client.listDocuments()
// Returns: DocumentListing[]
// Find document by ID
const post = await client.findDocument('123')
// Returns: Document | undefined
// Find document by slug
const post = await client.findDocumentBySlug('my-post')
// Returns: Document | undefined
Categories
// List all categories
const categories = await client.listCategories()
// Returns: CategoryListing[]
// Find category by ID
const category = await client.findCategory('123')
// Returns: Category | undefined