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.