{"id":25554008,"url":"https://github.com/pmkin-cms/pmkin-js","last_synced_at":"2026-02-17T01:34:11.506Z","repository":{"id":276543901,"uuid":"929582473","full_name":"pmkin-cms/pmkin-js","owner":"pmkin-cms","description":"PMKIN lets you create and publish content on your terms. You don’t need to wait for your developers to deploy the changes, and it integrates seamlessly with your Next.js website. Get started for free today and leave Git and Markdown behind.","archived":false,"fork":false,"pushed_at":"2025-04-08T13:07:02.000Z","size":42,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-08T06:44:54.442Z","etag":null,"topics":["cms","graphql","headless","headless-cms","typescript"],"latest_commit_sha":null,"homepage":"https://pmkin.io/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmkin-cms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-08T22:02:00.000Z","updated_at":"2025-04-08T13:01:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"c4b84185-a029-42f0-bdcd-92042d10c5fe","html_url":"https://github.com/pmkin-cms/pmkin-js","commit_stats":null,"previous_names":["pmkin-cms/pmkin-js"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/pmkin-cms/pmkin-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmkin-cms%2Fpmkin-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmkin-cms%2Fpmkin-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmkin-cms%2Fpmkin-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmkin-cms%2Fpmkin-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmkin-cms","download_url":"https://codeload.github.com/pmkin-cms/pmkin-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmkin-cms%2Fpmkin-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29529513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T00:57:22.232Z","status":"ssl_error","status_checked_at":"2026-02-17T00:54:25.811Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","graphql","headless","headless-cms","typescript"],"created_at":"2025-02-20T12:49:00.690Z","updated_at":"2026-02-17T01:34:11.474Z","avatar_url":"https://github.com/pmkin-cms.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PMKIN JavaScript SDK\n\n[PMKIN](https://pmkin.io) is a lightweight headless CMS designed for developers\nwho want to focus on building rather than managing complex content\ninfrastructure. It provides a simple GraphQL API to manage and deliver your\ncontent, making it perfect for blogs, documentation sites, and other\ncontent-driven applications.\n\n## Installation\n\n```bash\nbun add pmkin\n# or\nnpm install pmkin\n# or\nyarn add pmkin\n# or\npnpm add pmkin\n```\n\n## Getting Started (Next.js)\n\n### Setup Client\n\nFirst, create a PMKIN client instance. Create a new file `lib/pmkin.ts`:\n\n```typescript\nimport { PmkinClient } from 'pmkin'\n\nif (!process.env.PMKIN_TOKEN) {\n  throw new Error('PMKIN_TOKEN is not set')\n}\n\nexport const pmkin = new PmkinClient({\n  token: process.env.PMKIN_TOKEN\n})\n```\n\nAdd your PMKIN token to your `.env.local` file:\n\n```\nPMKIN_TOKEN=your_token_here\n```\n\n### List Blog Posts\n\nCreate a blog posts listing page at `app/blog/page.tsx`:\n\n```typescript\nimport Link from 'next/link'\nimport { pmkin } from '@/lib/pmkin'\n\n // Revalidate every hour\nexport const revalidate = 3600\n\nexport default async function BlogPage() {\n  const posts = await pmkin.listDocuments()\n\n  return (\n    \u003cdiv className=\"prose lg:prose-xl\"\u003e\n      {posts.map((post) =\u003e (\n        \u003carticle key={post.id}\u003e\n          \u003ch2\u003e{post.title}\u003c/h2\u003e\n\n          {post.subtitle \u0026\u0026 \u003cp\u003e{post.subtitle}\u003c/p\u003e}\n\n          \u003cLink href={`/blog/${post.slug}`}\u003eRead more\u003c/Link\u003e\n        \u003c/article\u003e\n      ))}\n    \u003c/div\u003e\n  )\n}\n```\n\n### Show a Single Blog Post\n\nCreate a dynamic route for individual blog posts at `app/blog/[slug]/page.tsx`:\n\n```typescript\nimport { notFound } from 'next/navigation'\nimport Markdown from 'react-markdown'\n\nimport { pmkin } from '@/lib/pmkin'\n\ninterface PageProps {\n  params: {\n    slug: string\n  }\n}\n\n// Revalidate every hour\nexport const revalidate = 3600\n\nexport default async function BlogPostPage({ params }: PageProps) {\n  const post = await pmkin.findDocumentBySlug(params.slug)\n\n  if (!post) {\n    notFound()\n  }\n\n  return (\n    \u003carticle className=\"prose lg:prose-xl\"\u003e\n      \u003ch1\u003e{post.title}\u003c/h1\u003e\n\n      {post.subtitle \u0026\u0026 \u003cp\u003e{post.subtitle}\u003c/p\u003e}\n\n      \u003cMarkdown\u003e\n        {post.markdown}\n      \u003c/Markdown\u003e\n    \u003c/article\u003e\n  )\n}\n```\n\n## Error Handling\n\nThe client methods can throw different types of errors depending on the API\nresponse:\n\n```typescript\ntry {\n  const posts = await pmkin.listDocuments()\n} catch (error) {\n  if (error instanceof GraphQLError) {\n    // GraphQL validation or execution errors\n    console.error('GraphQL Error:', error.message)\n  } else if (error instanceof UnauthorizedError) {\n    // Invalid or expired token\n    console.error('Authentication failed')\n  } else if (error instanceof RateLimitError) {\n    // Too many requests\n    console.error('Rate limit exceeded')\n  } else if (error instanceof InvalidResponseError) {\n    // Invalid response format\n    console.error('Invalid API response:', error.response)\n  } else if (error instanceof RequestError) {\n    // Other HTTP errors\n    console.error('Request failed:', error.message)\n  }\n}\n```\n\n### Error Types\n\n- `GraphQLError`: Thrown when the GraphQL query is invalid or fails to execute\n- `UnauthorizedError`: Thrown when the API token is invalid or expired\n  (HTTP 401)\n- `RateLimitError`: Thrown when you've exceeded the rate limit (HTTP 429)\n- `InvalidResponseError`: Thrown when the API response format is invalid\n- `RequestError`: Thrown for other HTTP errors (like 503 Service Unavailable)\n\n### Not Found Cases\n\nMethods that fetch single items return `undefined` when the item is not found:\n\n```typescript\nconst post = await pmkin.findDocumentBySlug('non-existent')\n\nif (!post) {\n  // Handle not found case\n}\n```\n\n## API Reference\n\n### PmkinClient\n\n```typescript\nconst client = new PmkinClient({\n  token: string // Your PMKIN API token\n})\n```\n\n#### Documents\n\n```typescript\n// List all documents\nconst posts = await client.listDocuments()\n// Returns: DocumentListing[]\n\n// List all documents in a specific category\nconst posts = await client.listDocumentsInCategory('c58b1646-94b7-4baf-b9cb-1c40d47284ac', true) // Second parameter is optional includeDrafts flag\n// Returns: DocumentListing[]\n\n// Find document by ID\nconst post = await client.findDocument('6733466740869c00233ad8dd')\n// Returns: Document | undefined\n\n// Find document by slug\nconst post = await client.findDocumentBySlug('my-post')\n// Returns: Document | undefined\n```\n\n#### Categories\n\n```typescript\n// List all categories\nconst categories = await client.listCategories()\n// Returns: CategoryListing[]\n\n// Find category by ID\nconst category = await client.findCategory('c58b1646-94b7-4baf-b9cb-1c40d47284ac')\n// Returns: Category | undefined\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmkin-cms%2Fpmkin-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmkin-cms%2Fpmkin-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmkin-cms%2Fpmkin-js/lists"}