With Astro
Start a new project with Astro
npm create astro@latest
Setting up credentials
.env
WRITEFLOW_API_KEY="YOUR-API-KEY"
Installing dependencies
To generate typed client code, you need to install @writeflow/types
first.
npm install -D @writeflow/types
After that, you can generate the typed client code with this command:
npx @writeflow/client --key <APIKEY> --outDir ./src/utils
Displaying a post list
src/pages/index.astro
---
import { writeflow } from "../utils/writeflow"
const allPosts = await writeflow({
apiKey: import.meta.env.WRITEFLOW_API_KEY,
}).content.list({
fields: {
slug: true,
title: true,
properties: true,
},
})
const posts = allPosts.filter(
(post) => post.properties.published.checkbox
).sort((a, b) => {
const aDate = a.properties.Date.date
const bDate = b.properties.Date.date
return (
(aDate ? new Date(aDate.start).getTime() : 0) -
(bDate ? new Date(bDate.start).getTime() : 0)
)
})
---
<!DOCTYPE html>
<html>
<head>
<title>Writeflow with Astro</title>
</head>
<body>
<ul>
{
posts.map((post) => (
<li>
<a href={`/post/${post.slug}`}>
{post.title}
</a>
</li>
))
}
</ul>
</body>
</html>
Generating post pages
You can render content data using the Renderer
component from @writeflow/astro
. This component also accepts your custom components for enhanced flexibility.
src/pages/post/[slug].astro
---
import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
import { writeflow } from "../../utils/writeflow";
import { Renderer } from "@writeflow/astro";
import Code from "../../components/custom/Code"
export const getStaticPaths = (async () => {
const posts = await writeflow({
apiKey: import.meta.env.WRITEFLOW_API_KEY,
}).content.list({
fields: {
title: true,
slug: true,
properties: true,
body: true,
},
});
return posts
.filter((post) => post.properties.published.checkbox)
.map((post) => ({
params: { slug: post.slug },
props: { post },
}))
}) satisfies GetStaticPaths
const props = Astro.props as InferGetStaticPropsType<typeof getStaticPaths>
const post = props.post
---
<!DOCTYPE html>
<html>
<head>
<title>{post.title}</title>
</head>
<body>
<h1>{post.title}</h1>
<Renderer
blocks={post.body}
components={{ code: Code }}
/>
</body>
</html>
In this example, I've incorporated a custom Code
component to render code blocks in my preferred style. You can customize the rendering of any block type to suit your needs.