Publishing integrations
Next.js blog
For sites with no CMS at all. Instead of publishing into someone else’s database, your app reads the articles from ours at build time and revalidates on a schedule.
Install#
npm install rankli-nextjs-blogNext.js 14 or 15 with the App Router. React 18 or 19.
Create the integration and get a key#
- In Rankli, open Integrations → New integration → Next.js blog.
- Name it after the site it serves.
- Copy the API key from the confirmation. It is shown once.
- Put it in your environment:
RANKLI_BLOG_API_KEY=rk_blog_your_key_hereThis key is read on the server only — the package never exposes it to the browser, and it must not be prefixed NEXT_PUBLIC_. Add it to your hosting provider’s environment variables as well as your local .env.local.
Add the routes#
Four files, all of them thin wrappers around the package:
import { BlogIndex } from 'rankli-nextjs-blog';
export const revalidate = 86400; // once a day
export default function Page() {
return <BlogIndex title="Blog" />;
}import { BlogPost, generateBlogParams, blogMetadata } from 'rankli-nextjs-blog';
export const revalidate = 86400;
export const generateStaticParams = generateBlogParams;
export const generateMetadata = blogMetadata;
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
return <BlogPost slug={slug} />;
}Two more are optional: app/blog/tag/[slug]/page.tsx for tag archives and app/blog/sitemap.xml/route.ts for a blog-only sitemap. Both are one-liners over the same exports, and both are in the package’s starter folder.
Styling it#
The components render semantic HTML with no styles of their own and no CSS import, so they inherit your site. Every element carries a rk- class if you want to target them:
.rk-post h2 { font-size: 1.5rem; margin-top: 2.5rem; }
.rk-post img { border-radius: 12px; }
.rk-index-card { border: 1px solid #eee; }If you would rather build your own markup, getPosts() and getPost(slug) return the data and nothing else.
Caching and freshness#
With revalidate = 86400 your pages are static and refresh once a day, which means one request to us per page per day and a blog that survives us being down.
To publish faster than that, add a revalidation route and give Rankli its URL as a webhook target — the article then appears within seconds of being written:
import { revalidatePath } from 'next/cache';
export async function POST(req: Request) {
if (req.headers.get('authorization') !== `Bearer ${process.env.RANKLI_REVALIDATE_TOKEN}`) {
return new Response('no', { status: 401 });
}
revalidatePath('/blog');
revalidatePath('/blog/[slug]', 'page');
return Response.json({ revalidated: true });
}When it does not work#
The index is empty
No articles have been published to this integration yet. An article publishes to the connections attached to its product; check the product’s integrations list.
401 at build time
The environment variable is missing where the build runs. Vercel and Netlify need it set in the project settings as well as in your local file.
Changes do not appear
revalidate is doing its job. Either wait for the window, redeploy, or add the revalidation route above.