Serve articles on your Next.js site.
With Next.js, Citapult doesn't push anything to your site; your site fetches the articles instead, through a small API with its own key. Citapult gives you the code for it: four files to copy.
Updated
What you need
- A Next.js site on version 15 or later with the App Router. For other setups the API alone does the job, see below.
- Access to your host's environment variables, the project settings on Vercel for example.
- Free paths for
/blogand/<slug>, or you adapt the two pages from the starter files to your structure.
Set it up
1. Add the integration
In Citapult, open Settings → Integrations, pick Next.js under “Type” and click “Add”. Citapult creates a key starting with
rq_. The key only reads articles this integration has received.2. Copy the starter files
Under “Setup” next to the integration you'll find four files with your key in them:
.env.local,lib/citapult.ts,app/blog/page.tsxandapp/[slug]/page.tsx. Copy them into your project. Since.env.localisn't deployed, add both variables at your host too, then deploy..env.local CITAPULT_API_URL=https://…/api/v1 CITAPULT_API_KEY=rq_…
3. Publish an article
Open a finished article and click “Publish”. From then on it lives on your site at
/<slug>, the same URL as in Citapult, and in the overview at/blog. Your pages refetch at most every five minutes, and only on a visit: the first visit after that still gets the old version. Articles you published before adding the integration only show up in the API once you send them again.4. Optional: publish automatically
Turn on “Publish automatically” under Integrations. Articles marked “Needs review” then go out to all integrations on their scheduled day without a click. You set the time in the calendar under “Schedule”.
The endpoints
The starter files use two endpoints under CITAPULT_API_URL. Both need the key in the header Authorization: Bearer rq_…. A wrong key gets 401 with {"error":"Invalid API key"}, an unknown slug 404 with {"error":"Not found"}.
GET /articles:{ "articles": [...] }with every article this integration received, newest first.GET /articles/<slug>: one article with all fields, as it was last sent.
curl "$CITAPULT_API_URL/articles" \ -H "Authorization: Bearer $CITAPULT_API_KEY"
What the API returns
The list at /articles leaves out the large fields: content_html, content_markdown, json_ld and sources only come with a single article.
| Field | Contents |
|---|---|
id | The article's ID in Citapult |
title | The title, the H1 on the article page |
slug | The last part of the URL the article lives at |
content_html | The article text as HTML, without the H1. Raw HTML in the text arrives as text, only YouTube embeds stay, so you can insert it as is. |
content_markdown | The same text as Markdown |
meta_title, meta_description | Meta title and meta description, or null |
image_url, image_alt | The featured image and its alt text, or null |
language | The article's language and country, like en-US |
tags | A list with the article's main keyword |
json_ld | The structured data as a list, one application/ld+json script each |
sources | The sources, with url and title |
author | Name, role and short bio from the settings, or null |
created_at, published_at, updated_at | Timestamps in ISO format |
When you change an article
Edit a published article and its status goes back to “Needs review”, while the API keeps returning the old version. The new one goes out with “Update”, or on its own with “Publish automatically” if the article was scheduled for today or yesterday. Citapult locks the slug after the first publish, so the URL stays.
Removing the integration
The key stops working right away, and your site gets no more articles. A new integration has a new key and only serves what you send again after that.
Errors and questions
I use the Pages Router or another framework
The starter files are built for the App Router. The API itself is a plain GET with a bearer token and works with any framework: fetch the list from /articles and a single article from /articles/<slug>.
A new article doesn't show up
Your pages refetch at most every five minutes, and only on a visit: the first visit after that still gets the old version. Load the page twice after a few minutes. If the list below the button shows an error at the Next.js integration, it didn't get the article. An error at another integration doesn't hold it back.
Citapult API: HTTP 401 on your site
Citapult API: HTTP 401 on your siteThe key is missing from your host's environment variables, was copied wrong or belongs to a removed integration. Copy it again from “Setup” and redeploy.
“"…" already has the slug … there”
Another article from Citapult already lives at this slug on your site. The new article then goes out to no integration, not even the others. Give it a different slug and send it again. That works as long as no integration has the article or is creating it. After that its slug is fixed, and the Next.js integration can't serve it next to the other article.
Can the key go into the browser?
No, it belongs on the server. The starter files only use it in Server Components. Never put it in a variable starting with NEXT_PUBLIC_.