Integration·Eleventy·beginner
Scheduled blog posts for Eleventy
Scheduled blog posts for Eleventy: write Crontent posts as markdown drafts via webhook and rebuild your static site.
How-to: Integrate Crontent with Eleventy. Official docs: Eleventy. Shared API contract: Publishing API and SDK.
Verify the Crontent webhook, write a markdown draft into your Eleventy input directory, and rebuild after review.
Field mapping
| Crontent field | Eleventy frontmatter |
|---|---|
title | title |
seo_title | seoTitle (custom layout partial) |
slug | Permalink via permalink: /blog/{{ slug }}/ |
excerpt | description |
body_mdx | Markdown body |
body_html | Use with a .html template if preferred |
tags | tags |
hero_image_url | image |
canonical_url | canonical |
sources[] | sources (array in frontmatter) |
Webhook endpoint
Run alongside Eleventy or as a separate serverless function:
ts
import { Crontent } from "@crontent/sdk";
import { writeFile, mkdir } from "node:fs/promises";
import { join } from "node:path";
const crontent = new Crontent({ apiKey: process.env.CRONTENT_API_KEY! });
export async function handler(req: Request) {
const rawBody = await req.text();
const valid = await crontent.webhooks.verify({
rawBody,
signature: req.headers.get("x-crontent-signature"),
timestamp: req.headers.get("x-crontent-timestamp"),
secret: process.env.CRONTENT_WEBHOOK_SECRET!,
});
if (!valid) return new Response("unauthorized", { status: 401 });
const { post_id } = JSON.parse(rawBody);
const post = await crontent.posts.get(post_id);
const inputDir = join(process.cwd(), "src/posts");
await mkdir(inputDir, { recursive: true });
const content = `---
title: ${JSON.stringify(post.title)}
description: ${JSON.stringify(post.excerpt ?? "")}
date: ${JSON.stringify(post.ready_at ?? post.created_at)}
draft: true
tags: ${JSON.stringify(post.tags)}
permalink: "/blog/${post.slug}/"
layout: post.njk
---
${post.body_mdx}
`;
await writeFile(join(inputDir, `${post.slug}.md`), content);
return new Response("ok");
}In .eleventy.js, exclude drafts from collections in production:
js
eleventyConfig.addGlobalData("eleventyExcludeFromCollections", (data) => data.draft);Remove draft: true after editorial review and rebuild.
Backfill
Import historical posts with a script calling posts.list. Write files with the same frontmatter shape.