With Next.js (App Router)
Let's create a blog with Next.js. Here’s a brief folder structure:
/app
/blog
/[slug]
- page.ts
- page.ts
For reliability and better DX, generate client code with:
npx @writeflow/client@latest --key <YOUR_API_KEY> --outDir ./src/utils
In blog/page.ts
, a list of posts should be displayed to users. We'll use unstable_cache
to save the result from fetching.
import { unstable_cache } from "next/cache";
const getPosts = unstable_cache(async () => {});
export default async function BlogPage() {
const posts = await getPosts();
return <ul>{posts.map()}</ul>
}
With the generated client code, we can easily implement its functionality.
import { unstable_cache } from "next/cache";
import Link from "next/link";
import { writeflow } from "@/utils";
const getPosts = unstable_cache(
async () => {
const posts = await writeflow({ apiKey: process.env.WRITEFLOW_API_KEY })
.content
.list({
fields: {
slug: true,
title: true
}
});
return posts;
}
);
export default async function BlogPage() {
const posts = await getPosts();
return (
<ul>
{
posts.map((post) => (
<li key={post.key}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))
}
</ul>
);
}
Then let's move to the post page. The post pages are generated from app/blog/[slug]/page.ts
, where we will fetch and display the content of a single post based on the slug.
import { writeflow } from "@/utils";
import { renderBlocks } from "@writeflow/react";
export default async function PostPage({ params }) {
const { slug } = params;
const post = await writeflow({ apiKey: process.env.WRITEFLOW_API_KEY })
.content
.bySlug(slug, {
fields: {
title: true,
body: true
}
});
return (
<article>
<h1>{post.title}</h1>
<p>{renderBlocks(post.body)}</p>
</article>
);
}
This setup will allow us to dynamically generate and display blog posts based on the URL slug.
Update with webhooks
When the content on your site changes, whether it is updated or deleted, it is crucial to ensure that these changes are reflected on the consumer website promptly. To achieve this, there’s an easy pattern that can be followed to implement this functionality using webhooks.
Webhooks allow your application to receive real-time updates whenever specific events occur, such as content modifications. By setting up a webhook to listen for content changes, you can automate the process of updating the consumer website without manual intervention.
Here is an example of how you can set up a webhook to revalidate the path of a specific route when the content changes:
import { revalidatePath } from "next/cache";
export async function POST(req: Request) {
revalidatePath("/blog");
}
In this example, the revalidatePath
function from the next/cache
module is used to revalidate the path /blog
whenever a POST request is received. This ensures that any changes to the content are immediately applied and reflected on the consumer website.