### Minimal Keystatic Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md A minimal Keystatic configuration example demonstrating the setup of local storage and a basic 'posts' collection with title and slug fields. ```typescript import { config, collection, singleton, fields } from '@keystatic/core'; export default config({ storage: { kind: 'local' }, collections: { posts: collection({ label: 'Posts', path: 'posts/*', slugField: 'slug', schema: { title: fields.text({ label: 'Title' }), slug: fields.slug({ name: { label: 'Slug' } }), }, }), }, }); ``` -------------------------------- ### Example Keystatic Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/config.md Demonstrates how to set up storage, collections, singletons, and UI branding for a Keystatic project. ```typescript import { config, collection, singleton, fields } from '@keystatic/core'; export default config({ storage: { kind: 'github', repo: { owner: 'myorg', name: 'my-repo', }, }, collections: { posts: collection({ label: 'Blog Posts', path: 'content/posts/*', format: { contentField: 'content' }, slugField: 'slug', schema: { title: fields.text({ label: 'Title' }), content: fields.document({ label: 'Content' }), }, }), }, singletons: { homepage: singleton({ label: 'Homepage', path: 'content/homepage', schema: { title: fields.text({ label: 'Page Title' }), }, }), }, ui: { brand: { name: 'My CMS', }, }, }); ``` -------------------------------- ### Build and Start Remix for Production Source: https://github.com/thinkmill/keystatic/blob/main/templates/remix/README.md Commands to compile the application for production and launch the server. ```sh npm run build ``` ```sh npm start ``` -------------------------------- ### Install Keystatic Dependencies Source: https://github.com/thinkmill/keystatic/blob/main/templates/nextjs/README.md Run this command in your terminal to install the necessary project dependencies. ```bash npm install ``` -------------------------------- ### Install Keystatic with pnpm Source: https://github.com/thinkmill/keystatic/blob/main/README.md Install Keystatic dependencies using pnpm. Ensure you have Node.js v18 and pnpm installed. ```sh pnpm install ``` -------------------------------- ### Run Keystatic Development Server Source: https://github.com/thinkmill/keystatic/blob/main/templates/nextjs/README.md Execute this command to start the development server for your Next.js application with Keystatic. ```bash npm run dev ``` -------------------------------- ### Run Development Server Source: https://github.com/thinkmill/keystatic/blob/main/dev-projects/next-blocks-builder/README.md Use these commands to start the local development server for your Next.js project. Open http://localhost:3000 in your browser to view the application. ```bash npm run dev ``` ```bash yarn dev ``` ```bash pnpm dev ``` ```bash bun dev ``` -------------------------------- ### Define a Singleton Content Block Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/config.md Example of configuring a 'Site Settings' singleton with a label, path, format, and schema. ```typescript singleton({ label: 'Site Settings', path: 'content/settings', format: 'yaml', schema: { siteName: fields.text({ label: 'Site Name', validation: { isRequired: true }, }), tagline: fields.text({ label: 'Tagline', validation: { length: { max: 100 } }, }), logo: fields.image({ label: 'Logo', directory: 'public/images', }), }, }) ``` -------------------------------- ### Astro Content Collection Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Example of integrating Keystatic's reader with Astro's content collections. This function fetches all entries from a specified collection. ```typescript import { createReader } from '@keystatic/core/reader'; import config from '@/keystatic.config'; const reader = createReader(process.cwd(), config); export async function getCollection(name) { return reader.collections[name].all(); } ``` -------------------------------- ### Run Keystatic Development Project Source: https://github.com/thinkmill/keystatic/blob/main/README.md Navigate to a development project and start the development server using pnpm. This is for local development and testing of Keystatic features. ```sh cd dev-projects/{example} pnpm run dev ``` -------------------------------- ### Next.js Static Generation Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Example of using Keystatic's reader within a Next.js application for static site generation. It fetches all posts to generate static paths and then reads individual posts for page content. ```typescript import { createReader } from '@keystatic/core/reader'; import config from '@/keystatic.config'; export async function generateStaticParams() { const reader = createReader(process.cwd(), config); const posts = await reader.collections.posts.all(); return posts.map(post => ({ slug: post.slug })); } export default async function PostPage({ params }) { const reader = createReader(process.cwd(), config); const post = await reader.collections.posts.read(params.slug); const content = await post.content(); return (

{post.title}

); } ``` -------------------------------- ### Next.js API Route Handler Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/api-handler.md Example of setting up a Keystatic API route handler in a Next.js application. It uses makeGenericAPIRouteHandler and exports POST and GET methods. ```typescript import { makeGenericAPIRouteHandler } from '@keystatic/core/api/generic'; import config from '@/keystatic.config'; export const POST = makeGenericAPIRouteHandler({ config, clientId: process.env.KEYSTATIC_GITHUB_CLIENT_ID, clientSecret: process.env.KEYSTATIC_GITHUB_CLIENT_SECRET, secret: process.env.KEYSTATIC_SECRET, }); export const GET = POST; ``` -------------------------------- ### Basic Keystatic Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md A fundamental Keystatic configuration example demonstrating GitHub storage, a 'posts' collection with title, slug, and document fields, and a 'settings' singleton. ```typescript import { config, collection, singleton, fields } from '@keystatic/core'; export default config({ storage: { kind: 'github', repo: { owner: 'myorg', name: 'my-repo' }, }, collections: { posts: collection({ label: 'Blog Posts', path: 'content/posts/*', format: { contentField: 'content' }, slugField: 'slug', schema: { title: fields.text({ label: 'Title', validation: { isRequired: true }, }), slug: fields.slug({ name: { label: 'URL Slug' }, }), content: fields.document({ label: 'Content', formatting: true, }), }, }), }, singletons: { settings: singleton({ label: 'Site Settings', path: 'settings', schema: { siteName: fields.text({ label: 'Site Name' }), }, }), }, ui: { brand: { name: 'My CMS' }, navigation: ['posts', '---', 'settings'], }, }); ``` -------------------------------- ### Remix API Route Handler Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/api-handler.md Example of integrating the Keystatic API handler with a Remix application. It defines loader and action functions to handle requests and responses. ```typescript import { makeGenericAPIRouteHandler } from '@keystatic/core/api/generic'; import config from '@/keystatic.config'; import { json } from '@remix-run/node'; const handler = makeGenericAPIRouteHandler({ config, clientId: process.env.KEYSTATIC_GITHUB_CLIENT_ID, clientSecret: process.env.KEYSTATIC_GITHUB_CLIENT_SECRET, secret: process.env.KEYSTATIC_SECRET, }); export async function loader({ request }) { const response = await handler(request); return json(response.body, { status: response.status, headers: response.headers }); } export const action = loader; ``` -------------------------------- ### Sitemap Generation with GitHub Reader Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Example demonstrating how to generate a sitemap using the GitHub reader. It fetches a list of posts using `list()` and formats them for sitemap URLs. ```typescript import { createGitHubReader } from '@keystatic/core/reader/github'; import config from '@/keystatic.config'; export async function generateSitemap() { const reader = createGitHubReader(config, { repo: 'myorg/my-repo', token: process.env.GITHUB_TOKEN, }); const posts = await reader.collections.posts.list(); return posts.map(post => ({ url: `https://mysite.com/blog/${post.slug}`, lastmod: new Date(), })); } ``` -------------------------------- ### Define a Blog Post Collection Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/config.md Example of configuring a 'Blog Posts' collection with specified path, format, slug field, columns, preview URL, and schema. ```typescript collection({ label: 'Blog Posts', path: 'content/posts/*', format: { contentField: 'content' }, slugField: 'slug', columns: ['title', 'published'], previewUrl: 'https://mysite.com/blog/{slug}', schema: { title: fields.text({ label: 'Title', validation: { isRequired: true }, }), slug: fields.slug({ name: { label: 'URL Slug', }, }), published: fields.checkbox({ label: 'Published', }), content: fields.document({ label: 'Content', formatting: true, }), }, }) ``` -------------------------------- ### Set Keystatic Storage to Local for Development Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configures Keystatic to use local storage for development environments. This simplifies local setup by reducing credential requirements. ```bash # .env.local KEYSTATIC_STORAGE=local ``` -------------------------------- ### Creating Custom Inline and Block Renderers Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/renderer.md Provides examples of creating custom renderers for inline elements like links and bold text, and block elements such as headings and code blocks. ```typescript const customRenderers = { inline: { link: ({ href, children }) => ( {children} ), bold: ({ children }) => ( {children} ), // ... other inline renderers }, block: { heading: ({ level, children, textAlign }) => { const Tag = `h${level}` as const; return ( {children} ); }, code: ({ children, language }) => (
        {children}
      
), // ... other block renderers }, }; ``` -------------------------------- ### Basic Callout Component Block Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/component-blocks.md A simple example demonstrating how to create a 'Callout' component block with a title and content fields. The preview renders these fields within a styled div, and includes a remove button. ```typescript import { component, fields } from '@keystatic/core'; const Callout = component({ label: 'Callout', preview({ fields, onRemove }) { return (
{fields.title.value}
{fields.content.value}
); }, schema: { title: fields.text({ label: 'Title' }), content: fields.text({ label: 'Content', multiline: true }), }, }); ``` -------------------------------- ### Custom Document Renderer for Headings Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Extend default renderers to customize the rendering of heading blocks. This example applies a navy color style to headings. ```typescript const customRenderers = { ...defaultRenderers, block: { ...defaultRenderers.block, heading: ({ level, children }) => { const Tag = `h${level}` as const; return {children}; }, }, }; ``` -------------------------------- ### Custom Responsive Table Renderer Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/renderer.md An example of a custom table renderer that wraps the table in a div with 'overflowX: "auto"' and sets 'minWidth: "100%"' on the table. This ensures tables are responsive and scrollable on smaller viewports. ```typescript const customRenderers = { block: { table: ({ head, body }) => (
{head && ( {head.map((cell, i) => ( ))} )} {body.map((row, rowIdx) => ( {row.map((cell, cellIdx) => ( ))} ))}
{cell.children}
{cell.children}
), }, }; ``` -------------------------------- ### Slug Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.slug to generate URL-friendly identifiers. Configure label, description, and validation rules like length or regex patterns. ```typescript fields.slug({ name: { label: 'URL Slug', description: 'Auto-generated from title', validation: { length: { max: 50 } }, }, }) ``` -------------------------------- ### Custom Code Block Renderer with Syntax Highlighting Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/renderer.md Example of a custom renderer for code blocks that integrates prism-react-renderer for syntax highlighting. It applies the 'nightOwl' theme and handles language detection. ```typescript import { Highlight, themes } from 'prism-react-renderer'; const customRenderers = { block: { code: ({ children, language = 'text' }) => ( {({ className, style, tokens, getLineProps, getTokenProps }) => (
            {tokens.map((line, i) => (
              
{line.map((token, key) => ( ))}
))}
)}
), }, }; ``` -------------------------------- ### Form Fields API Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Provides all available field types for creating forms in Keystatic, with examples for text, numeric, selection, date/time, media, rich content, containers, and relationships. ```APIDOC ## Form Fields API ### Description Reference for all available field types in Keystatic, used for creating forms. Includes examples for various data types and structures. ### Field Types - **Text**: `text`, `slug`, `url` - **Numeric**: `integer`, `number` - **Selection**: `checkbox`, `select`, `multiselect` - **Date/Time**: `date`, `datetime` - **Media**: `image`, `file` - **Rich Content**: `document` (supports formatting, links, images, tables) - **Container**: `array`, `object`, `conditional` - **Relationship**: `relationship`, `multiRelationship` ``` -------------------------------- ### Component with Nested Fields Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/component-blocks.md Defines a component for code examples, featuring nested fields for title, language, code, and an explanation object with 'before' and 'after' text areas. The preview renders the code in a styled block. ```typescript const CodeExample = component({ label: 'Code Example', schema: { title: fields.text({ label: 'Title' }), language: fields.select({ label: 'Language', options: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'py' }, ], defaultValue: 'js', }), code: fields.text({ label: 'Code', multiline: true }), explanation: fields.object({ label: 'Explanation', fields: { before: fields.text({ label: 'Before', multiline: true }), after: fields.text({ label: 'After', multiline: true }), }, }), }, preview({ fields }) { return (
{fields.title.value}
          {fields.code.value}
        
); }, }); ``` -------------------------------- ### Error Handling Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Details common errors encountered when using the reader and provides an example of how to handle them. ```APIDOC ## Error Handling ### Common Errors | Error | |-------| | `Entry not found` | | `Failed to parse entry` | | `Validation failed` | | `Failed to fetch tree` | ### Example Error Handling ```typescript try { const post = await reader.collections.posts.read('missing'); } catch (error) { console.error('Failed to read post:', error.message); // Handle gracefully } ``` ``` -------------------------------- ### Create Keystatic Project Source: https://github.com/thinkmill/keystatic/blob/main/packages/create/README.md Use this command to initiate the creation of a new Keystatic project from your CLI. ```bash npx create @keystatic ``` -------------------------------- ### Run Keystatic Create Locally Source: https://github.com/thinkmill/keystatic/blob/main/packages/create/README.md To test local changes to the create package, run this command. You can specify absolute paths for project creation. ```bash pnpm dev:create ``` -------------------------------- ### Export Environment Variables for Production Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Demonstrates how to export GitHub credentials and the Keystatic secret as environment variables for production deployment. This is crucial for security. ```bash export KEYSTATIC_GITHUB_CLIENT_ID=... export KEYSTATIC_GITHUB_CLIENT_SECRET=... export KEYSTATIC_SECRET=... ``` -------------------------------- ### Select Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.select to create a single-choice dropdown. Ensure the defaultValue is one of the provided option values. ```typescript fields.select({ label: 'Content Type', options: [ { label: 'Blog Post', value: 'blog' }, { label: 'Tutorial', value: 'tutorial' }, { label: 'News', value: 'news' }, ], defaultValue: 'blog', }) ``` -------------------------------- ### Multiselect Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.multiselect to allow multiple selections from a list of options. The defaultValue should be an array of selected option values. ```typescript fields.multiselect({ label: 'Tags', options: [ { label: 'React', value: 'react' }, { label: 'TypeScript', value: 'typescript' }, { label: 'Performance', value: 'perf' }, ], defaultValue: ['react'], }) ``` -------------------------------- ### Using Default and Custom Renderers Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/renderer.md Demonstrates how to import and use default renderers directly or merge them with custom implementations to override specific element styles. ```typescript import { defaultRenderers } from '@keystatic/core/renderer'; // Use defaults directly const renderers = defaultRenderers; // Or merge with custom renderers const customRenderers = { ...defaultRenderers, block: { ...defaultRenderers.block, heading: ({ level, children, textAlign }) => { const Tag = `h${level}` as const; return ( {children} ); }, }, }; ``` -------------------------------- ### config() Function Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/config.md Creates a Keystatic configuration object with type-safe collections and singletons. It accepts a configuration object that includes storage settings, collections, singletons, UI options, and locale. ```APIDOC ## config() Function ### Description Creates a Keystatic configuration object with type-safe collections and singletons. It accepts a configuration object that includes storage settings, collections, singletons, UI options, and locale. ### Parameters #### config - **config** (`Config`) - Required - The configuration object containing storage settings, collections, singletons, UI options, and locale. ### Return Type Returns the same configuration object passed in, ensuring type safety through TypeScript generics. ### Storage Configuration The `config` function accepts a `storage` property that specifies where content is stored: - `local`: Development mode using the local file system - `github`: Remote storage using GitHub repository with OAuth authentication - `cloud`: Keystatic Cloud managed storage ### Example ```typescript import { config, collection, singleton, fields } from '@keystatic/core'; export default config({ storage: { kind: 'github', repo: { owner: 'myorg', name: 'my-repo', }, }, collections: { posts: collection({ label: 'Blog Posts', path: 'content/posts/*', format: { contentField: 'content' }, slugField: 'slug', schema: { title: fields.text({ label: 'Title' }), content: fields.document({ label: 'Content' }), }, }), }, singletons: { homepage: singleton({ label: 'Homepage', path: 'content/homepage', schema: { title: fields.text({ label: 'Page Title' }), }, }), }, ui: { brand: { name: 'My CMS', }, }, }); ``` ### Configuration Type Definition ```typescript type Config< Collections extends { [key: string]: Collection, string>; } = {}, Singletons extends { [key: string]: Singleton>; } = {} > = { storage: LocalStorageConfig | GitHubStorageConfig | CloudStorageConfig; collections?: Collections; singletons?: Singletons; locale?: Locale; cloud?: { project: string }; ui?: UserInterface; } ``` ### Storage Types #### LocalStorageConfig ```typescript { kind: 'local' } ``` Used for local development. Reads from the file system. #### GitHubStorageConfig ```typescript { kind: 'github'; repo: RepoConfig; pathPrefix?: string; branchPrefix?: string; } ``` Where `RepoConfig` is: ```typescript { owner: string; name: string; } ``` #### CloudStorageConfig ```typescript { kind: 'cloud'; pathPrefix?: string; branchPrefix?: string; } ``` ``` -------------------------------- ### Image Upload Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.image for image uploads. Specify a directory to organize uploaded files within the repository. isRequired validation can be applied. ```typescript fields.image({ label: 'Hero Image', directory: 'public/images', validation: { isRequired: true }, }) ``` -------------------------------- ### Datetime Picker Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.datetime for date and time input. Similar to fields.date, it supports isRequired validation and ISO 8601 format for defaultValue. ```typescript fields.datetime({ label: 'Last Updated', validation: { isRequired: true }, }) ``` -------------------------------- ### Import Core Keystatic Modules Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Import essential configuration builders, field types, and UI components from the core Keystatic package. Also shows how to import specific field types. ```typescript import { // Config builders config, collection, singleton, // Field namespace fields, // Component blocks component, // Types type Config, type Collection, type Singleton, type Reader, type Entry, // Block components BlockWrapper, NotEditable, ToolbarSeparator, } from '@keystatic/core'; // Reader API import { createReader } from '@keystatic/core/reader'; import { createGitHubReader } from '@keystatic/core/reader/github'; // API handler import { makeGenericAPIRouteHandler } from '@keystatic/core/api/generic'; import { defaultRenderers } from '@keystatic/core/renderer'; // Field types separately import { fields } from '@keystatic/core'; // or import { text, select, document } from '@keystatic/core/fields'; ``` -------------------------------- ### Set Up Environment Variables for Keystatic Dev App Source: https://github.com/thinkmill/keystatic/blob/main/dev-projects/next-app/README.md These environment variables are required to run the Keystatic development application. Ensure they are set in a `.env` file. ```bash KEYSTATIC_SECRET=... KEYSTATIC_GITHUB_CLIENT_ID=... KEYSTATIC_GITHUB_CLIENT_SECRET=... ``` -------------------------------- ### Date Picker Field Example Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/form-fields.md Use fields.date to create a date input. Set isRequired: true for mandatory date selection. The defaultValue should be in YYYY-MM-DD format. ```typescript fields.date({ label: 'Publish Date', validation: { isRequired: true }, }) ``` -------------------------------- ### Configuration Reference Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Details all configuration options and environment variables for Keystatic, including GitHub OAuth credentials, storage settings, API handler options, and data format choices. ```APIDOC ## Configuration Reference ### Description Details all available configuration options and environment variables for Keystatic. ### Environment Variables - `KEYSTATIC_GITHUB_CLIENT_ID`: GitHub OAuth app credentials. - `KEYSTATIC_GITHUB_CLIENT_SECRET`: GitHub OAuth app credentials. - `KEYSTATIC_SECRET`: Token encryption key. ### Configuration Options - **Storage**: local, GitHub (with `repo`, `pathPrefix`, `branchPrefix`), Cloud. - **API Handler**: Options for configuring the API handler. - **Collection Paths**: Glob patterns for defining collection paths. - **Data Formats**: YAML, JSON, hybrid. - **Localization**: Support for multiple languages. - **UI**: Navigation and branding customization. - **Validation**: Constraint rules for data validation. - **Environment Setup**: Development vs. production configurations. ``` -------------------------------- ### Complete Keystatic Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md This snippet shows a full Keystatic configuration, including collections, singletons, storage, cloud settings, and UI customization. ```typescript import { config, collection, singleton, fields, component } from '@keystatic/core'; const Callout = component({ label: 'Callout', preview({ fields }) { return
{fields.message.value}
; }, schema: { message: fields.text({ label: 'Message' }), }, }); export default config({ storage: { kind: 'github', repo: { owner: 'myorg', name: 'my-website', }, pathPrefix: 'content', branchPrefix: 'cms/', }, cloud: { project: 'my-project', }, locale: 'en', collections: { blog: collection({ label: 'Blog Posts', path: 'blog/*', format: { contentField: 'content' }, slugField: 'slug', entryLayout: 'content', previewUrl: 'https://mysite.com/blog/{slug}', columns: ['title', 'published', 'date'], template: '{slug}', parseSlugForSort: (slug) => { const date = slug.split('_')[0]; return new Date(date).getTime(); }, schema: { title: fields.text({ label: 'Title', validation: { isRequired: true, length: { max: 200 } }, }), slug: fields.slug({ name: { label: 'URL Slug', validation: { length: { max: 100 } }, }, }), date: fields.date({ label: 'Publish Date', validation: { isRequired: true }, }), published: fields.checkbox({ label: 'Published', defaultValue: false, }), tags: fields.multiselect({ label: 'Tags', options: [ { label: 'JavaScript', value: 'js' }, { label: 'React', value: 'react' }, { label: 'TypeScript', value: 'ts' }, ], }), author: fields.relationship({ label: 'Author', collection: 'authors', }), content: fields.document({ label: 'Content', formatting: true, images: { directory: 'public/blog' }, tables: true, componentBlocks: { callout: Callout, }, }), }, }), authors: collection({ label: 'Authors', path: 'authors/*', slugField: 'name', schema: { name: fields.text({ label: 'Name' }), bio: fields.text({ label: 'Bio', multiline: true }), avatar: fields.image({ label: 'Avatar', directory: 'public/avatars' }), }, }), }, singletons: { homepage: singleton({ label: 'Homepage', path: 'homepage', format: 'yaml', schema: { title: fields.text({ label: 'Page Title' }), description: fields.text({ label: 'Meta Description' }), hero: fields.object({ label: 'Hero Section', fields: { heading: fields.text({ label: 'Heading' }), subheading: fields.text({ label: 'Subheading' }), image: fields.image({ label: 'Hero Image' }), }, }), }, }), settings: singleton({ label: 'Site Settings', path: 'settings', schema: { siteName: fields.text({ label: 'Site Name' }), siteUrl: fields.url({ label: 'Site URL' }), socialLinks: fields.array({ label: 'Social Links', element: fields.object({ fields: { platform: fields.select({ label: 'Platform', options: [ { label: 'Twitter', value: 'twitter' }, { label: 'GitHub', value: 'github' }, { label: 'LinkedIn', value: 'linkedin' }, ], defaultValue: 'twitter', }), url: fields.url({ label: 'Profile URL' }), }, }), }), }, }), }, ui: { brand: { name: 'My CMS', mark: ({ colorScheme }) => (
📝
), }, navigation: [ 'blog', 'authors', '---', 'homepage', 'settings', ], }, }); ``` -------------------------------- ### Read Data from Local File System Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Demonstrates how to create a reader for local files, read single entries, all entries, list entry metadata, and read singletons. ```typescript import { createReader } from '@keystatic/core/reader'; import config from '@/keystatic.config'; const reader = createReader(process.cwd(), config); // Read single entry const post = await reader.collections.posts.read('my-post'); console.log(post.title, post.slug); const content = await post.content(); // Parse markdown // Read all entries const allPosts = await reader.collections.posts.all(); allPosts.forEach(post => console.log(post.slug)); // List entries (metadata only) const postList = await reader.collections.posts.list(); // Read singleton const settings = await reader.singletons.settings.read(); ``` -------------------------------- ### Environment Variables for GitHub Storage Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Lists the required and optional environment variables for configuring Keystatic with GitHub storage. ```bash # Required for GitHub storage KEYSTATIC_GITHUB_CLIENT_ID=your_github_app_client_id KEYSTATIC_GITHUB_CLIENT_SECRET=your_github_app_client_secret KEYSTATIC_SECRET=your_encryption_secret # Optional KEYSTATIC_GITHUB_TOKEN=optional_token_for_reading_from_github ``` -------------------------------- ### Alert Component Block with Custom Toolbar Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/component-blocks.md An advanced example of a component block for 'Alert Box' that includes a custom toolbar. The toolbar allows editing and removing the alert, and its appearance is controlled by the alert type. ```typescript const Alert = component({ label: 'Alert Box', schema: { message: fields.text({ label: 'Message' }), type: fields.select({ label: 'Alert Type', options: [ { label: 'Info', value: 'info' }, { label: 'Warning', value: 'warning' }, { label: 'Error', value: 'error' }, { label: 'Success', value: 'success' }, ], defaultValue: 'info', }), }, preview({ fields }) { const colors = { info: '#0066cc', warning: '#ff9900', error: '#cc0000', success: '#00aa00', }; const bgColors = { info: '#f0f7ff', warning: '#fffbf0', error: '#fff0f0', success: '#f0fff0', }; const type = fields.type.value as keyof typeof colors; return (
{fields.message.value}
); }, toolbar({ props, onShowEditMode, onRemove, isValid }) { return (
); }, }); ``` -------------------------------- ### Type-Safe Keystatic Configuration with TypeScript Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Illustrates how TypeScript provides full type checking for Keystatic configuration, enabling inferred collection and singleton types for enhanced developer experience. ```typescript // Fully typed - TypeScript infers collection and singleton types const config = config({ collections: { posts: collection({ /* ... */ }), }, }); // Now readers are fully typed: const reader = createReader(process.cwd(), config); // reader.collections.posts is properly typed ``` -------------------------------- ### Import Keystatic Core Components Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/types.md Imports major types and functions from the main Keystatic entry point. Includes configuration, collection and singleton definitions, field utilities, component creators, and reader types. ```typescript import { Config, Collection, Singleton, fields, // Namespace with all field functions component, // Component block creator Reader, Entry, // Reader types createReader, createGitHubReader, defaultRenderers, // Default renderers } from '@keystatic/core'; ``` -------------------------------- ### Keystatic Renderer Imports Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Import default renderers from the '@keystatic/core/renderer' sub-package for customizing document rendering. ```typescript // Renderer import { defaultRenderers } from '@keystatic/core/renderer'; ``` -------------------------------- ### Semantic Text Variant Definition Source: https://github.com/thinkmill/keystatic/blob/main/design-system/primitives/README.md Shows an example of defining text variants using semantic names like 'caption' instead of t-shirt sizes. This approach consolidates font properties such as color, family, size, weight, line height, and text transform under a single semantic token. ```json { "color": "{some.value}", "fontFamily": "{some.value}", "fontSize": "{some.value}", "fontWeight": "{some.value}", "lineHeight": "{some.value}", "textTransform": "{some.value}" } ``` -------------------------------- ### Configure Generic API Route Handler Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Set up the generic API route handler with necessary authentication credentials and Keystatic configuration. Environment variables are used for sensitive options. ```typescript makeGenericAPIRouteHandler({ clientId: process.env.KEYSTATIC_GITHUB_CLIENT_ID, clientSecret: process.env.KEYSTATIC_GITHUB_CLIENT_SECRET, secret: process.env.KEYSTATIC_SECRET, config, localBaseDirectory: process.cwd(), }) ``` -------------------------------- ### Configure Local Storage Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configure Keystatic to use local file system storage. This is suitable for local development and requires no environment variables. ```typescript export default config({ storage: { kind: 'local', }, }); ``` -------------------------------- ### Configure GitHub Storage with Path Prefix Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configure GitHub storage with a `pathPrefix` to specify a subdirectory for Keystatic content within the repository. This is useful for monorepos. ```typescript storage: { kind: 'github', repo: { owner: 'myorg', name: 'repo' }, pathPrefix: 'content', } ``` -------------------------------- ### Configure Cloud Storage Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configure Keystatic to use Keystatic Cloud storage by providing the project ID. Authentication is handled by Keystatic Cloud. ```typescript export default config({ storage: { kind: 'cloud', }, cloud: { project: 'your-project-id', }, }); ``` -------------------------------- ### Keystatic Format Options Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/config.md Illustrates the 'Format' type for controlling data serialization, including simple and extended options. ```typescript // Simple format type Format = 'json' | 'yaml'; // Extended format type Format = { data?: 'json' | 'yaml'; contentField?: string | [string, ...string[]]; }; ``` -------------------------------- ### Keystatic Architecture Flow Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Illustrates the typical data flow within Keystatic, from the Editor UI through the API Handler to the Git repository and back via the Reader API. ```text Editor → API Handler → Git Repo (or Local FS) ↓ Reader API → Content Access ↓ Render UI ``` -------------------------------- ### Configure GitHub Storage Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configure Keystatic to use GitHub as its storage backend, specifying the repository owner and name. This is done within the `keystatic.config.ts` file. ```typescript export default config({ storage: { kind: 'github', repo: { owner: 'your-org', name: 'your-repo', }, }, }); ``` -------------------------------- ### Create Local Reader Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Creates a reader for local file system access during build time or server-side operations. Requires the repository path and Keystatic configuration. ```typescript import { createReader } from '@keystatic/core/reader'; import config from '@/keystatic.config'; import path from 'path'; const reader = createReader( path.join(process.cwd()), config ); // Read a collection entry const post = await reader.collections.posts.read('my-first-post'); console.log(post.title, post.slug, post.content()); ``` -------------------------------- ### GitHub Storage Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Configure Keystatic to use GitHub for storage. This requires repository owner and name, and optionally a path prefix and branch prefix. OAuth credentials are also needed. ```typescript storage: { kind: 'github', repo: { owner: 'myorg', name: 'my-repo' }, pathPrefix?: 'content', branchPrefix?: 'keystatic/', } ``` -------------------------------- ### createGitHubReader() Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Creates a reader for accessing content from a GitHub repository, suitable for server-side rendering and static generation. ```APIDOC ## createGitHubReader() ### Description Creates a reader for accessing content from a GitHub repository, suitable for server-side rendering and static generation. ### Parameters #### Path Parameters - **config** (Config) - Required - Keystatic configuration object - **opts.repo** (string) - Required - Repository in format `owner/repo` - **opts.pathPrefix** (string) - Optional - Prefix path in repo (e.g., `content/`) - **opts.ref** (string) - Optional - Git ref (branch, tag, or commit SHA), defaults to 'HEAD' - **opts.token** (string) - Optional - GitHub personal access token for private repos ### Return Type Same as local reader: `Reader` ### Example ```typescript import { createGitHubReader } from '@keystatic/core/reader/github'; import config from '@/keystatic.config'; const reader = createGitHubReader(config, { repo: 'myorg/my-repo', pathPrefix: 'content', token: process.env.GITHUB_TOKEN, }); // Read from main branch const posts = await reader.collections.posts.all(); ``` ``` -------------------------------- ### Cloud Storage Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Configure Keystatic to use the managed Keystatic Cloud service for storage. Requires a project ID. ```typescript storage: { kind: 'cloud' }, cloud: { project: 'project-id' } ``` -------------------------------- ### Keystatic Reader API Imports Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Import functions for creating readers, including GitHub-specific readers, from the '@keystatic/core/reader' sub-package. ```typescript // Reader API import { createReader } from '@keystatic/core/reader'; import { createGitHubReader } from '@keystatic/core/reader/github'; ``` -------------------------------- ### Render Document Content with DocumentRenderer Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/renderer.md Fetches a post's content using the Keystatic reader and renders it using DocumentRenderer. Ensure you have customRenderers defined if needed. ```typescript import { createReader } from '@keystatic/core/reader'; import { DocumentRenderer } from '@keystatic/core/renderer'; import config from '@/keystatic.config'; export default async function Post({ params }) { const reader = createReader(process.cwd(), config); const post = await reader.collections.posts.read(params.slug); // Load content const content = await post.content(); return (

{post.title}

); } ``` -------------------------------- ### Local Storage Configuration Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Configure Keystatic to use the local file system for storage. This is suitable for development or static site generation. ```typescript storage: { kind: 'local' } ``` -------------------------------- ### Configure GitHub Storage with Branch Prefix Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/configuration.md Configure GitHub storage with a `branchPrefix` to add a prefix to all branch names created by Keystatic. This helps organize branches. ```typescript storage: { kind: 'github', repo: { owner: 'myorg', name: 'repo' }, branchPrefix: 'keystatic/', } ``` -------------------------------- ### createReader() Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Creates a reader for accessing content from the local file system during build time or server-side operations. ```APIDOC ## createReader() ### Description Creates a reader for accessing content from the local file system during build time or server-side operations. ### Parameters #### Path Parameters - **repoPath** (string) - Required - Absolute or relative path to the repository root - **config** (Config) - Required - Keystatic configuration object ### Return Type Returns a `Reader` object with the following structure: ```typescript type Reader = BaseReader & { repoPath: string; } ``` ### Reader Properties - **collections** (Object) - Object mapping collection names to collection readers - **singletons** (Object) - Object mapping singleton names to singleton readers - **config** (Config) - The configuration object passed to createReader - **repoPath** (string) - The repository root path ### Example ```typescript import { createReader } from '@keystatic/core/reader'; import config from '@/keystatic.config'; import path from 'path'; const reader = createReader( path.join(process.cwd()), config ); // Read a collection entry const post = await reader.collections.posts.read('my-first-post'); console.log(post.title, post.slug, post.content()); ``` ``` -------------------------------- ### Define Custom Component Blocks Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Shows how to define a custom component block with fields for message and type, and how to use it within a document field. ```typescript import { component, fields } from '@keystatic/core'; const Callout = component({ label: 'Callout Box', schema: { message: fields.text({ label: 'Message' }), type: fields.select({ label: 'Type', options: [ { label: 'Info', value: 'info' }, { label: 'Warning', value: 'warning' }, ], defaultValue: 'info', }), }, preview({ fields }) { return (
{fields.message.value}
); }, }); // Use in document field fields.document({ componentBlocks: { callout: Callout, }, }) ``` -------------------------------- ### Keystatic API Handler Import Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Import the generic API route handler function from the '@keystatic/core/api/generic' sub-package. ```typescript // API Handler import { makeGenericAPIRouteHandler } from '@keystatic/core/api/generic'; ``` -------------------------------- ### Config API Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/INDEX.md Defines your CMS structure using `config()`, `collection()`, and `singleton()` functions. Supports various storage configurations, UI customization, and data formats. ```APIDOC ## Config API ### Description Functions for defining your CMS structure, including collections and singletons. Supports storage configuration (local, GitHub, cloud), UI customization, and data formats (JSON, YAML, hybrid). ### Functions - `config()`: Main configuration function. - `collection()`: Defines a collection of content. - `singleton()`: Defines a single content item. ``` -------------------------------- ### Custom Document Renderers Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Illustrates how to extend default renderers to customize the appearance of document content, such as headings. ```typescript import { defaultRenderers } from '@keystatic/core/renderer'; // Custom renderers const renderers = { ...defaultRenderers, block: { ...defaultRenderers.block, heading: ({ level, children }) => { const Tag = `h${level}` as const; return {children}; }, }, }; // In your component export function Post({ document }) { return ( ); } ``` -------------------------------- ### Read Data from GitHub Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/quick-reference.md Shows how to create a reader for GitHub, specifying the repository, branch, and authentication token. ```typescript import { createGitHubReader } from '@keystatic/core/reader/github'; import config from '@/keystatic.config'; const reader = createGitHubReader(config, { repo: 'myorg/my-repo', ref: 'main', token: process.env.GITHUB_TOKEN, }); const post = await reader.collections.posts.read('my-post'); ``` -------------------------------- ### Create GitHub Reader Source: https://github.com/thinkmill/keystatic/blob/main/_autodocs/api-reference/reader.md Creates a reader for accessing content from a GitHub repository, suitable for server-side rendering and static generation. Requires configuration, repository details, and optionally a path prefix, ref, or token. ```typescript import { createGitHubReader } from '@keystatic/core/reader/github'; import config from '@/keystatic.config'; const reader = createGitHubReader(config, { repo: 'myorg/my-repo', pathPrefix: 'content', token: process.env.GITHUB_TOKEN, }); // Read from main branch const posts = await reader.collections.posts.all(); ```