Zenex CMSDocs

GET Single Post

Fetch a single post by slug, including full content.

Endpoint

Endpoint
GET /api/blogs/{blogId}/posts/{slug}

Response

Response
{
"data": {
"id": "clx1234567890",
"title": "My First Post",
"slug": "my-first-post",
"content": {
"time": 1672531200000,
"blocks": [
{
"type": "paragraph",
"data": {
"text": "This is the post content in Editor.js format."
}
}
],
"version": "2.28.0"
},
"excerpt": "A short description",
"coverImage": "https://example.com/image.jpg",
"language": "en",
"html": "<p class=\"zenex-cms__paragraph\">This is the post content in Editor.js format.</p>",
"publishedAt": "2024-01-01T00:00:00.000Z",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"categories": [...],
"tags": [...],
"metaTitle": "SEO Title",
"metaDescription": "SEO Description",
"ogImage": "https://example.com/og-image.jpg",
"ogTitle": "Social Title",
"ogDescription": "Social Description",
"canonicalUrl": "https://example.com/blog/my-first-post",
"keywords": "javascript, web"
}
}

Example

example.ts
const blogId = "your-blog-id";
const slug = "my-first-post";
const res = await fetch(
`https://yourdomain.com/api/blogs/${blogId}/posts/${slug}`
);
const { data: post } = await res.json();
console.log(post.title);
console.log(post.content); // Editor.js format

Content Format

The content is available in two formats:

  • content - Raw Editor.js JSON blocks structure.
  • html - Server-side rendered HTML with zenex-cms__* classes.

Rendering & Styling

The easiest way to render post content is to use the html field and include our default stylesheet.

1. Render HTML

In React / Next.js:

Post.tsx
<div
className="zenex-cms-content"
dangerouslySetInnerHTML={{ __html: post.html }}
/>

In Astro:

Post.astro
<div class="zenex-cms-content" set:html={post.html} />

2. Add Styles

Copy the following CSS to your project (e.g., zenex-cms.css) and import it.

zenex-cms.css
/* Zenex CMS Default Styles */
.zenex-cms__header {
font-weight: 700;
line-height: 1.2;
margin: 1.5rem 0 1rem;
color: inherit;
}
.zenex-cms__h1 { font-size: 2.25rem; font-weight: 800; }
.zenex-cms__h2 { font-size: 1.875rem; font-weight: 700; }
.zenex-cms__h3 { font-size: 1.5rem; font-weight: 600; }
.zenex-cms__h4 { font-size: 1.25rem; font-weight: 600; }
.zenex-cms__paragraph {
font-size: 1rem;
line-height: 1.75;
margin: 0.75rem 0;
color: inherit;
}
.zenex-cms__list {
margin: 0.75rem 0;
padding-left: 1.5rem;
}
.zenex-cms__list-item {
margin: 0.25rem 0;
line-height: 1.75;
}
.zenex-cms__list--unordered { list-style-type: disc; }
.zenex-cms__list--ordered { list-style-type: decimal; }
.zenex-cms__quote {
border-left: 4px solid currentColor;
padding-left: 1rem;
margin: 1rem 0;
font-style: italic;
opacity: 0.9;
}
.zenex-cms__code-block {
background-color: #111827;
color: #e5e7eb;
border-radius: 0.5rem;
padding: 1.25rem;
margin: 1.5rem 0;
overflow-x: auto;
border: 1px solid #374151;
}
.zenex-cms__code {
font-family: monospace;
font-size: 0.9rem;
line-height: 1.6;
color: inherit;
}
.zenex-cms__image-figure { margin: 1.5rem 0; }
.zenex-cms__image {
max-width: 100%;
height: auto;
border-radius: 0.5rem;
}
.zenex-cms__image-caption {
font-size: 0.875rem;
text-align: center;
margin-top: 0.5rem;
opacity: 0.8;
}
.zenex-cms__link-tool {
border: 1px solid currentColor;
opacity: 0.8;
border-radius: 0.5rem;
margin: 1rem 0;
padding: 1rem;
display: block;
text-decoration: none;
}