Skip to Content
QuickstartAstroAstro

Astro Quickstart

Create a new Flexkit Studio in an Astro application and run it locally.

Create a new Astro project with React support

Terminal
pnpm create astro@latest my-flexkit-app --add react && cd my-flexkit-app

Install Flexkit Studio packages

Terminal
pnpm add @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer

Create the Flexkit configuration

Create a flexkit.config.tsx file in the root of your project. This file defines your content schema and Studio configuration.

React
flexkit.config.tsx
import { defineConfig, defineEntity } from '@flexkit/studio';
import { Desk } from '@flexkit/desk';
import { Package, FolderTree } from 'lucide-react';
 
const products = defineEntity({
  name: 'product',
  plural: 'products',
  menu: {
    label: 'Products',
    group: 'catalog',
    icon: <Package />,
  },
  attributes: [
    {
      name: 'name',
      label: 'Product Name',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      previewType: 'text',
      isPrimary: true,
      isSearchable: true,
      validation: (z) => z.string().min(1, { message: 'Name is required' }),
      defaultValue: '',
      options: {
        size: 260,
        comment: 'The name of the product',
      },
    },
    {
      name: 'sku',
      label: 'SKU',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      isUnique: true,
      isSearchable: true,
      validation: (z) => z.string().min(1, { message: 'SKU is required' }),
      defaultValue: '',
      options: {
        size: 130,
        comment: 'Unique product identifier',
      },
    },
    {
      name: 'description',
      label: 'Description',
      scope: 'global',
      dataType: 'string',
      inputType: 'editor',
      defaultValue: '',
      options: {
        size: 260,
        comment: 'Full product description',
      },
    },
    {
      name: 'price',
      label: 'Price',
      scope: 'global',
      dataType: 'float',
      inputType: 'number',
      previewType: 'text',
      validation: (z) => z.number().min(0, { message: 'Price must be positive' }),
      defaultValue: '',
      options: {
        size: 130,
        comment: 'Product price',
      },
    },
    {
      name: 'category',
      label: 'Category',
      scope: 'relationship',
      dataType: 'string',
      inputType: 'relationship',
      isSearchable: true,
      defaultValue: '',
      relationship: {
        mode: 'single',
        field: 'name',
        entity: 'category',
      },
      options: {
        size: 200,
        comment: 'Product category',
      },
    },
  ],
});
 
const categories = defineEntity({
  name: 'category',
  plural: 'categories',
  menu: {
    label: 'Categories',
    group: 'catalog',
    icon: <FolderTree />,
  },
  attributes: [
    {
      name: 'name',
      label: 'Category Name',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      previewType: 'text',
      isPrimary: true,
      isUnique: true,
      isSearchable: true,
      validation: (z) => z.string().min(1, { message: 'Name is required' }),
      defaultValue: '',
      options: {
        size: 200,
        comment: 'The name of the category',
      },
    },
    {
      name: 'slug',
      label: 'URL Slug',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      isUnique: true,
      validation: (z) => z.string().min(1, { message: 'Slug is required' }),
      defaultValue: '',
      options: {
        size: 200,
        comment: 'URL-friendly identifier',
      },
    },
    {
      name: 'description',
      label: 'Description',
      scope: 'global',
      dataType: 'string',
      inputType: 'textarea',
      defaultValue: '',
      options: {
        size: 260,
        comment: 'Category description',
      },
    },
  ],
});
 
// Export the Flexkit configuration
export default defineConfig([
  {
    title: 'My Studio',
    projectId: 'your-project-id', // Replace with your unique project ID
    basePath: '/studio',
    menuGroups: [
      {
        title: 'Catalog',
        name: 'catalog',
      },
    ],
    plugins: [
      Desk(),
      // Add more plugins here as needed
    ],
    schema: [products, categories],
  },
]);

Important: Replace 'your-project-id' with the unique project ID of your Flexkit project.

Create the API route handler

Create a new API route handler to serve the Flexkit API. Create the following file structure:

          • [...path].ts
React
src/pages/api/flexkit/[...path].ts
import { createFlexkitAstroHandler } from '@flexkit/studio/astro';
 
export const prerender = false;
 
const handler = createFlexkitAstroHandler();
 
export const GET = handler;
export const POST = handler;
export const PUT = handler;
export const PATCH = handler;
export const DELETE = handler;

Create the Studio page and component

Create a new Studio component and a page to render the Flexkit Studio interface. Create the following file structure:

      • studio.tsx
        • [...path].astro
React
src/components/studio.tsx
import { FlexkitStudio } from '@flexkit/studio';
import config from '../../flexkit.config';
 
export default function Studio() {
  return <FlexkitStudio config={config} />;
}
Astro
src/pages/studio/[...path].astro
---
import Studio from '../../components/studio';
---
 
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flexkit Studio</title>
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  </head>
  <body>
    <Studio client:only="react" />
  </body>
</html>

Deploy your data schema

Install the Flexkit CLI to deploy your data schema.
flexkit deploy

Run Your Project

Start the development server:

Terminal
pnpm run dev

Open your browser and navigate to http://localhost:4321/studio

Last updated on

© 2026