Get started
Add the genko.me SDK to Astro, render a list at build time, and show a single entry with share buttons.
This guide adds @genko-me/sdk to an Astro project to show a list and a single entry. Both pages are built ahead of time with the default output: 'static'. The detail page includes React ShareButtons as an island.
Steps 1–3 of the quickstart cover creating a workspace and blog API.
Prerequisites
- A genko.me account and workspace. You need the Owner role to create an API and issue an API key.
- An API with at least one saved and published entry. Drafts are not available through the delivery API.
- Node.js 22.12 or later. Astro supports even-numbered Node.js versions, not odd-numbered versions such as
v23. - An existing Astro project (created with
npm create astro@latest).
Replace your-workspace with your workspace ID and blog with your endpoint in the examples below.
Install
npm install @genko-me/sdkTo add share buttons to the detail page, install the React island packages too. npx astro add react produces the same setup, but this guide shows manual steps to avoid interactive prompts.
npm install @astrojs/react react react-dom @genko-me/reactimport { defineConfig } from "astro/config";import react from "@astrojs/react";
export default defineConfig({ integrations: [react()],});@genko-me/react declares React 19 as a peer dependency, but React itself is unnecessary on a page that only uses RichText. Here we use ShareButtons as an island, so we install it with @astrojs/react.
Configure an API key and workspace ID
Issue an API key in Settings and plan → API keys (/w/your-workspace/settings/api-keys). Scope it to blog under Selected APIs only. You cannot view its value again after creation.
GENKO_API_KEY=your-issued-keyAstro frontmatter and pages run on the server, either at build time or on request, so do not add PUBLIC_. That prefix exposes values to client JavaScript. Using it here would send the API key to the browser unnecessarily.
Keep the connection configuration in one place.
import { listApi } from "@genko-me/sdk";
export type Blog = { title: string; body: string };
export const apis = { blog: listApi<Blog>({ fields: [ { id: "title", type: "text" }, { id: "body", type: "richtext" }, ], }),};import { createGenko } from "@genko-me/sdk";import { apis } from "./schema";
export const genko = createGenko({ workspace: "your-workspace", apiKey: process.env.GENKO_API_KEY!, apis,});
export const client = genko.apis;This example uses process.env rather than import.meta.env. The tutorial explains why in its draft-preview section. Both pages here run at build time, but using the same style now avoids a rewrite if you later render a page on request.
Show a list
---import { client } from "../../lib/genko";
const { contents, totalCount } = await client.blog.list({ limit: 6, orders: "-publishedAt" });---<html lang="en"> <body> <main> <h1>Blog ({totalCount} entries)</h1> {contents.length === 0 ? ( <p>No published entries yet.</p> ) : ( <ul> {contents.map((post) => ( <li><a href={`/blog/${post.id}`}>{post.title}</a></li> ))} </ul> )} </main> </body></html>Run npm run dev and open /blog to check the list. Frontmatter await also runs during astro build; the result is written into static HTML.
Show a single entry
Put the detail page in the dynamic route src/pages/blog/[id].astro. With the default output: 'static', Astro builds the paths returned by getStaticPaths(). Use getAll() to enumerate entries.
---import { client } from "../../lib/genko";import { ShareButtons } from "@genko-me/react/share-buttons";
export async function getStaticPaths() { const posts = await client.blog.getAll(); return posts.map((post) => ({ params: { id: post.id }, props: { post } }));}
const { post } = Astro.props;---<html lang="en"> <body> <main> <h1>{post.title}</h1> <div set:html={post.body} /> <ShareButtons client:load url={`https://your-site.example/blog/${post.id}`} title={post.title} /> </main> </body></html>getStaticPaths() passes post through props, so you do not need another get() call. The body is an HTML string in post.body; render it with Astro's set:html (genko.me sanitizes rich text on the server when saving).
Import ShareButtons from its separate @genko-me/react/share-buttons subpath, which contains interactive components. Only the part with client:load sends JavaScript to the browser; the heading and body still arrive as plain HTML.
Run npm run build and check that dist/ has an HTML file for each entry. Open a detail page with npm run preview and test the share buttons.
Troubleshooting
| Symptom | Check |
|---|---|
| Empty list | Is the entry saved and published? Has its publication end date passed? |
401 | Is the API key still valid? Did you set the same environment variable in the build environment and keep .env out of Git? |
403 | Does the key belong to the workspace you are connecting to? |
| Build does not reflect an entry | astro build embeds content from build time. Rebuild after publishing or changing an entry (see webhooks in the tutorial) |
Next, the tutorial adds pagination, draft previews, and content-update handling.
Last updated: October 6, 2026