TanStack Start Quickstart
Create a new Flexkit Studio in a TanStack Start application and run it locally.
Create a new TanStack Start project
Terminal
pnpm create @tanstack/start@latest my-flexkit-app --package-manager pnpm
cd my-flexkit-appInstall Flexkit Studio packages
Terminal
pnpm add @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer lucide-reactCreate the Flexkit configuration
Create flexkit.config.tsx in the project root. This file defines your content schema and Studio configuration.
flexkit.config.tsx
import { Package, FolderTree } from 'lucide-react';
import { defineConfig, defineEntity } from '@flexkit/studio';
import { AssetManager } from '@flexkit/asset-manager';
import { Desk } from '@flexkit/desk';
import { Explorer } from '@flexkit/explorer';
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 default defineConfig([
{
title: 'My Studio',
projectId: 'your-project-id', // Replace with your unique project ID
basePath: '/studio',
menuGroups: [
{
title: 'Catalog',
name: 'catalog',
},
],
plugins: [
Desk(),
AssetManager(),
Explorer(),
// Add more plugins here as needed
],
schema: [products, categories],
},
]);Important: Replace
'your-project-id' with your Flexkit project ID.Create TanStack Start routes for Studio and API
Create the following files:
- index.tsx
- studio.tsx
- $.tsx
- $.tsx
src/routes/index.tsx
import { createFileRoute, redirect } from '@tanstack/react-router';
export const Route = createFileRoute('/')({
beforeLoad: () => {
throw redirect({ to: '/studio' });
},
});src/routes/studio.tsx
import { createFileRoute } from '@tanstack/react-router';
import { FlexkitStudio } from '@flexkit/studio';
import config from '../../flexkit.config';
export const Route = createFileRoute('/studio')({
ssr: false,
component: StudioPage,
});
function StudioPage(): JSX.Element {
return <FlexkitStudio config={config} />;
}src/routes/studio/$.tsx
import { createFileRoute } from '@tanstack/react-router';
import { FlexkitStudio } from '@flexkit/studio';
import config from '../../../flexkit.config';
export const Route = createFileRoute('/studio/$')({
ssr: false,
component: StudioPage,
});
function StudioPage(): JSX.Element {
return <FlexkitStudio config={config} />;
}src/routes/api/flexkit/$.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createFlexkitFetchHandler } from '@flexkit/studio/tanstack-start';
const flexkitHandler = createFlexkitFetchHandler();
export const Route = createFileRoute('/api/flexkit/$')({
component: () => null,
server: {
handlers: {
GET: async ({ request }) => {
return flexkitHandler(request);
},
POST: async ({ request }) => {
return flexkitHandler(request);
},
PUT: async ({ request }) => {
return flexkitHandler(request);
},
PATCH: async ({ request }) => {
return flexkitHandler(request);
},
DELETE: async ({ request }) => {
return flexkitHandler(request);
},
},
},
});Deploy your data schema
Install the Flexkit CLI to deploy your data schema.
flexkit deployRun your project
Terminal
pnpm devOpen your browser and navigate to http://localhost:3000/studio.
Last updated on