Next.js blog integration
Connect Spron to your Next.js blog by adding one route that receives ready articles and saves them in your site. The integration sends complete article content and images, while your code controls storage and whether each post becomes public or stays a draft.
How Next.js blog publishing works
Spron sends each ready article to a public HTTPS route in your Next.js project. The @spron/receiver package verifies the request, passes the article to your code, and returns the result to Spron.
Your saveArticle function decides where posts live, such as a database, CMS, or Markdown file. Save each post by its article ID so later deliveries update the same post instead of creating another one.
When you press Republish in the article editor, your blog receives the latest saved version. For Markdown files, save the article as a file, then rebuild and deploy your blog. Spron does not write to your Git repository.
- Press Publish in an article to send it.
- Use Send pending to send ready articles waiting for delivery.
- Return
external_idso Spron can keep the destination record. - Return
published_urlwhen the post is public.
Before you connect your Next.js blog
You need access to your blog’s code, a server that runs Node.js, and a public HTTPS address that can receive articles. You must also decide how your route will save posts and images.
A Spron workspace owner or admin can create the connection. Other members see the instruction to ask a workspace owner or admin to connect the blog.
- A Next.js project with the App Router
- A public route such as
https://example.com/api/spron - Storage for article records or files
- Storage for downloaded article images
- Server environment variables for
SPRON_ACCESS_TOKENandSPRON_WEBHOOK_SECRET
Connect Next.js to Spron
Install the receiver
Run the install command in your Next.js project. The receiver provides the route handler and image download helper used by the integration.
npm install @spron/receiverAdd the article route
Create
app/api/spron/route.tsand add the receiver code below. Keep the route on the Node.js runtime.Write
saveArticleandsaveImagefor your own storage. Save each article by its ID so an update changes the existing post.- Download images before saving the final article.
- Revalidate the blog index and the saved post path.
- Return only
external_idfor a non-public post. - Return both
external_idandpublished_urlfor a public post.
import { spronReceiver, downloadImages } from "@spron/receiver"; import { revalidatePath } from "next/cache"; import { saveArticle, saveImage } from "@/lib/spron-store"; export const runtime = "nodejs"; export const POST = spronReceiver({ secret: process.env.SPRON_WEBHOOK_SECRET!, token: process.env.SPRON_ACCESS_TOKEN!, onArticle: async (article, delivery) => { const media = await downloadImages(article, saveImage); const post = await saveArticle({ ...article, ...media }, delivery); revalidatePath("/blog"); revalidatePath(post.path); return post.isPublic ? { external_id: post.id, published_url: post.url } : { external_id: post.id }; }, });Connect your blog
In Spron, open the Next.js integration and press Connect blog. Enter the public address of your route, such as
https://example.com/api/spron.Copy the token Spron shows and add it to your server as both
SPRON_ACCESS_TOKENandSPRON_WEBHOOK_SECRET. The signing secret is shown once when you create the connection, so store it securely.SPRON_ACCESS_TOKEN=your-token SPRON_WEBHOOK_SECRET=your-tokenSend your first article
Deploy your blog so the public route uses the environment variables and storage code. Then press Publish in an article, or use Send pending from the connection.
- Open Delivery history to see whether the article arrived.
- Check the saved post in your storage or CMS.
- If the post is public, open the returned URL and inspect the page.
What Spron sends to your blog
Spron sends the complete article data needed to save a post. This includes the title, formatted content, search description, images, alt text, and captions.
Use downloadImages before saving the article. Image downloads from Spron expire after one hour, so your route must copy them into storage controlled by your site.
The receiver checks the bearer token, request signature, timestamp, delivery ID, and request body before it calls onArticle. Its default delivery-age tolerance is 300 seconds, and its default streamed body limit is 2 MiB.
- Use
article.idas the stable key for an update. - Use the downloaded
content_htmlwhen saving formatted content. - Return
external_idwith the saved post ID. - Add
published_urlonly when the post has a public URL.
Check your first Next.js post
Open Delivery history in Spron after sending your first article. The table shows the article, connected site, result, and sent date.
A result can appear as Waiting, Sending, Saved as draft, Published, or Needs attention. If the route returns a public URL, open that URL and check the title, content, links, and locally saved images.
When a delivery needs attention, review the displayed delivery error. An owner or admin can retry accepted, published, or failed deliveries while the connection remains active.
- Confirm that the article uses the expected destination path.
- Check that article images load from your site’s storage.
- Send an update with Republish and confirm that it changes the same post.
Fix common Next.js connection issues
The delivery shows Needs attention
Open the delivery error in Delivery history. Errors from saveArticle, saveImage, or another onArticle callback operation cause the route to fail so Spron can retry. Fix the storage or callback error, then use the retry action.
The route returns 401, 400, or 413
The receiver returns 401 for an invalid authorization or signature request, 400 for an invalid request, and 413 when the streamed body exceeds its configured limit. Check that both server variables contain the token shown by Spron and that no proxy changes the raw request body or signature headers.
Article images are missing after delivery
Make sure your route calls downloadImages and that saveImage stores each file on your site. Spron image downloads expire after one hour, and the downloader rejects redirects and times out after 10 seconds.
Two servers create duplicate posts
Upsert each post by article.id and use an atomic database claim or shared lock across processes. The receiver shares one write within a single receiver instance, but its in-memory replay check is not a distributed lock.
Need help connecting? Contact support, visit the Help Center, or see our other publishing integrations.