For larger projects with multiple collections, use a configuration file to generate and manage them all at once.
There are two configuration formats available. Choose based on your needs:
| Use Case | Format | Key |
|---|---|---|
| All collections share the same schema | Simple format | schemaPath |
| Each collection has its own schema | Enhanced format | collections[] |
| Multiple layers with targets | Enhanced format | collections[] + targets[] |
schemaPath, it must point to a file, not a directory. If you have multiple schema files in a directory, use the enhanced format with collections[] instead.For quick prototyping when all collections use the same field structure:
// crouton.config.js
export default {
schemaPath: './my-schema.json', // Must be a FILE path
dialect: 'sqlite',
targets: [
{ layer: 'shop', collections: ['products'] }
]
}
For production projects where each collection has its own schema:
// crouton.config.js
export default {
collections: [
{ name: 'products', fieldsFile: './schemas/products.json' },
{ name: 'categories', fieldsFile: './schemas/categories.json' },
],
dialect: 'sqlite',
targets: [
{ layer: 'shop', collections: ['products', 'categories'] }
]
}
// crouton.config.js
export default {
// Define all collections
collections: [
{ name: 'products', fieldsFile: './schemas/product.json' },
{ name: 'categories', fieldsFile: './schemas/category.json', hierarchy: true },
{ name: 'orders', fieldsFile: './schemas/order.json' },
{ name: 'posts', fieldsFile: './schemas/post.json' },
{ name: 'slides', fieldsFile: './schemas/slide.json', sortable: true },
{ name: 'bookings', fieldsFile: './schemas/booking.json', collab: true },
{ name: 'users', fieldsFile: './schemas/user.json' },
{ name: 'roles', fieldsFile: './schemas/role.json' },
],
// Organize into layers
targets: [
{
layer: 'shop',
collections: ['products', 'categories', 'orders']
},
{
layer: 'blog',
collections: ['posts', 'slides']
},
{
layer: 'admin',
collections: ['users', 'roles']
}
],
// Database
dialect: 'sqlite', // or 'pg'
// Translations (i18n) - define translatable fields per collection
translations: {
collections: {
products: ['name', 'description'],
posts: ['title', 'content']
}
},
// Flags
flags: {
force: false, // Overwrite existing files?
noTranslations: false, // Skip translations?
noDb: false, // Skip database generation?
dryRun: false, // Preview only?
autoRelations: true, // Generate relation stubs?
useMetadata: true // Add createdAt/updatedAt?
}
}
# Generate all collections
npx crouton-generate config ./crouton.config.js
# With flags
npx crouton-generate config ./crouton.config.js --force --dry-run
Define all your collections in one place:
collections: [
{ name: 'products', fieldsFile: './schemas/product.json' },
{ name: 'categories', fieldsFile: './schemas/category.json' },
]
Each collection object requires:
name - Collection name (plural)fieldsFile - Path to schema JSON fileOptional collection properties:
hierarchy - Enable tree structure (adds parentId, path, depth, order fields)sortable - Enable drag-to-reorder (adds order field and reorder endpoint)collab - Enable presence indicators (shows who's editing items in realtime)Organize collections into layers:
targets: [
{
layer: 'shop',
collections: ['products', 'categories', 'orders']
},
{
layer: 'blog',
collections: ['posts', 'authors', 'comments']
}
]
This creates a clean domain-driven structure:
layers/
├── shop/
│ └── collections/
│ ├── products/
│ │ └── app/
│ │ ├── components/
│ │ └── composables/
│ ├── categories/
│ │ └── app/
│ │ ├── components/
│ │ └── composables/
│ └── orders/
│ └── app/
│ ├── components/
│ └── composables/
└── blog/
└── collections/
├── posts/
│ └── app/
│ ├── components/
│ └── composables/
├── authors/
│ └── app/
│ ├── components/
│ └── composables/
└── comments/
└── app/
├── components/
└── composables/
Specify your database type:
dialect: 'sqlite' // or 'pg'
This affects the generated migrations and database schema.
Define which fields should be translatable per collection:
translations: {
collections: {
// Products: translate name and description
products: ['name', 'description'],
// Posts: translate title and content
posts: ['title', 'content', 'excerpt'],
// Pages: full content translation
pages: ['title', 'content', 'metaTitle', 'metaDescription']
}
}
When translations are configured:
CroutonI18nInput in forms for per-language editing{ translations: { en: {...}, nl: {...} } }nuxt.config.tslayers/[layer]/i18n/locales/flags.noTranslations: true to skip all i18n code generation.Control the generation behavior:
flags: {
force: false, // Overwrite existing files?
noTranslations: false, // Skip translations?
noDb: false, // Skip database generation?
dryRun: false, // Preview only?
autoRelations: true, // Generate relation stubs?
useMetadata: true // Add createdAt/updatedAt?
}
Create reusable templates for common project types:
// templates/saas-starter.config.js
export default {
collections: [
{ name: 'users', fieldsFile: './schemas/user.json' },
{ name: 'teams', fieldsFile: './schemas/team.json' },
{ name: 'subscriptions', fieldsFile: './schemas/subscription.json' },
{ name: 'billing', fieldsFile: './schemas/billing.json' },
],
targets: [
{
layer: 'admin',
collections: ['users', 'teams', 'subscriptions', 'billing']
}
],
flags: {
useMetadata: true
}
}
// templates/ecommerce.config.js
export default {
collections: [
{ name: 'products', fieldsFile: './schemas/product.json' },
{ name: 'categories', fieldsFile: './schemas/category.json' },
{ name: 'orders', fieldsFile: './schemas/order.json' },
{ name: 'customers', fieldsFile: './schemas/customer.json' },
{ name: 'inventory', fieldsFile: './schemas/inventory.json' },
],
targets: [
{
layer: 'shop',
collections: ['products', 'categories', 'inventory']
},
{
layer: 'orders',
collections: ['orders', 'customers']
}
],
dialect: 'pg',
flags: {
useMetadata: true,
autoRelations: true
}
}
// templates/blog.config.js
export default {
collections: [
{ name: 'posts', fieldsFile: './schemas/post.json' },
{ name: 'authors', fieldsFile: './schemas/author.json' },
{ name: 'categories', fieldsFile: './schemas/category.json' },
{ name: 'tags', fieldsFile: './schemas/tag.json' },
{ name: 'comments', fieldsFile: './schemas/comment.json' },
],
targets: [
{
layer: 'blog',
collections: ['posts', 'authors', 'categories', 'tags', 'comments']
}
],
dialect: 'sqlite',
flags: {
noTranslations: false, // Enable translations for content
useMetadata: true
}
}
Copy a template to your project and generate:
# Copy template
cp templates/saas-starter.config.js ./crouton.config.js
# Customize as needed
nano crouton.config.js
# Generate collections
npx crouton-generate config ./crouton.config.js
Group related collections into layers:
targets: [
{ layer: 'shop', collections: ['products', 'categories'] },
{ layer: 'blog', collections: ['posts', 'authors'] },
{ layer: 'admin', collections: ['users', 'roles'] }
]
Preview changes before generating:
npx crouton-generate config ./crouton.config.js --dry-run
Commit your config file and schemas:
git add crouton.config.js schemas/
git commit -m "Add collection configuration"
Store schemas in a dedicated directory:
project/
├── crouton.config.js
└── schemas/
├── product.json
├── category.json
└── order.json
When you need to update generated code:
# Regenerate with force flag
npx crouton-generate config ./crouton.config.js --force
Using --force will overwrite existing files. Make sure to commit your changes first or back up any customizations.