genko.meDocs
Frameworks and languagesNext.js

Get started

Connect genko.me to a Next.js App Router project and display a list and a single entry with List and View.

This guide connects genko.me to a Next.js App Router project and builds /blog and /blog/[id]. To create a workspace and blog API, follow steps 1–3 of the quickstart.

Prerequisites

  • A genko.me account and workspace. You need Owner access to create an API and issue an API key.
  • An API with at least one saved, published entry. The delivery API does not return drafts by default.
  • Node.js 20.12 or later and a working App Router project with Next.js 16 or later and React 19. The display components target the Node.js runtime.
  • A terminal open in the directory containing your project's package.json.

Replace your-workspace with your workspace ID and blog with your endpoint in the examples below. @/ is an import alias for the project root.

Install

The CLI installs the SDK and React components, then generates types and connection files from your schema.

bash
npx @genko-me/cli init

Enter your workspace ID and API key, then select the APIs to sync. The CLI generates these files. If your project depends on next, it also installs @genko-me/react.

FilePurpose
lib/schema.tsTypes and API definitions generated from the dashboard schema
lib/client.tsClient that connects to your workspace
genko.config.jsonConfiguration for the next type sync
.env.localAPI key storage, unless the environment variable already exists

For projects using src/app, files go into src/lib. To install the packages manually, see “Install without the CLI” in Display content with List and View.

Set the API key and workspace ID

Issue an API key in the dashboard under Settings and plan → API keys (/w/your-workspace/settings/api-keys). Copy it when it appears; you cannot view the full key again later.

The CLI writes it to .env.local, or uses an existing environment variable.

.env.local
GENKO_API_KEY=your-issued-key

The workspace ID is embedded in the generated lib/client.ts. If the dashboard URL is https://genko.me/w/your-workspace, the ID is your-workspace.

lib/client.ts
import "server-only";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;

Make sure Git does not track .env.local. Do not pass the key to client components or browser-exposed environment variables (NEXT_PUBLIC_). Set GENKO_API_KEY in your hosting environment for production.

Show a list

Put List in a server component. Its regular children define the layout for one entry.

app/blog/page.tsx
import { client } from "@/lib/client";import { List, ListItem, Pagination, Error, Null } from "@genko-me/react/next";
export default function BlogPage() {  return (    <main>      <h1>Blog</h1>      <List api={client.blog} limit={6} orders="-publishedAt" href="/blog/{id}">        <article>          <h2><ListItem id="title" /></h2>          <ListItem id="publishedAt" format="yyyy/MM/dd" timeZone="Asia/Tokyo" />        </article>        <Pagination />        <Error template />        <Null>No published entries yet.</Null>      </List>    </main>  );}

Start the development server and open /blog. With href, the entire item links to its entry. You can use publishedAt, createdAt, updatedAt, and revisedAt as IDs without adding them to the schema. The default time zone is UTC; set timeZone to display dates in Japan time.

If you omit Error or Null, nothing appears for that state. Keep them with template while checking the page.

Show a single entry

Pass the entry ID to View. Also pass the page's searchParams so the same page can preview drafts.

app/blog/[id]/page.tsx
import { client } from "@/lib/client";import { View, ViewItem, Error, Null } from "@genko-me/react/next";
type Props = {  params: Promise<{ id: string }>;  searchParams: Promise<Record<string, string | string[] | undefined>>;};
export default async function BlogDetail({ params, searchParams }: Props) {  const { id } = await params;  return (    <View api={client.blog} id={id} searchParams={searchParams}>      <h1><ViewItem id="title" /></h1>      <ViewItem id="body" />      <Error template />      <Null>Entry not found.</Null>    </View>  );}

The rich-text body renders as saved HTML. Set heading and paragraph spacing and image maximum width in your site's CSS. Omit id for object APIs.

Set notFound to show the Next.js 404 page when an entry is missing. Under Next.js streaming, the HTTP status may remain 200 after streaming starts.

tsx
<View api={client.blog} id={id} searchParams={searchParams} notFound>

Troubleshooting

SymptomCheck
Empty listIs an entry saved and Published? Has its publication end time passed?
401Is the API key still valid, and is GENKO_API_KEY available at runtime?
403Does the key belong to the workspace you are connecting to?
404Are the workspace ID and endpoint correct, and does the key allow this API?
No client.blogDid you create the API in the dashboard and run genko pull?

After changing the schema, run genko pull to sync types. See the CLI guide.

Next, use the tutorial to add pagination, draft previews, and webhook revalidation.

Last updated: October 6, 2026

On this page