0
# Preview System
1
2
Live content editing system with field definitions, authentication, and real-time preview capabilities for content management workflows.
3
4
## Capabilities
5
6
### Field Definition
7
8
Creates preview-compatible field configurations for content editing interfaces.
9
10
```typescript { .api }
11
/**
12
* Helper to build preview-compatible field configuration
13
* @param config - Field configuration object
14
* @returns Configured preview field
15
*/
16
function field(config: FieldConfig): PreviewField;
17
18
interface FieldConfig {
19
/** Field input type */
20
type: PickerTypes;
21
/** Field identifier */
22
name: string;
23
/** Display label for field */
24
label?: string;
25
/** Whether field is required */
26
required?: boolean;
27
/** Default value */
28
default?: unknown;
29
/** Field validation rules */
30
validation?: ValidationRule[];
31
/** Field-specific options */
32
options?: FieldOptions;
33
}
34
35
interface PreviewField {
36
type: PickerTypes;
37
name: string;
38
label: string;
39
required: boolean;
40
default?: unknown;
41
validation: ValidationRule[];
42
options: FieldOptions;
43
}
44
```
45
46
**Usage Examples:**
47
48
```typescript
49
import { field } from '@nuxt/content/preview';
50
51
// Text input field
52
const titleField = field({
53
type: 'text',
54
name: 'title',
55
label: 'Article Title',
56
required: true,
57
validation: [
58
{ type: 'minLength', value: 5, message: 'Title must be at least 5 characters' },
59
{ type: 'maxLength', value: 100, message: 'Title must not exceed 100 characters' }
60
]
61
});
62
63
// Rich text editor
64
const contentField = field({
65
type: 'richtext',
66
name: 'content',
67
label: 'Article Content',
68
required: true,
69
options: {
70
toolbar: ['bold', 'italic', 'link', 'code'],
71
placeholder: 'Write your article content...'
72
}
73
});
74
75
// Select dropdown
76
const categoryField = field({
77
type: 'select',
78
name: 'category',
79
label: 'Category',
80
required: true,
81
options: {
82
choices: [
83
{ label: 'Technology', value: 'tech' },
84
{ label: 'Design', value: 'design' },
85
{ label: 'Business', value: 'business' }
86
]
87
}
88
});
89
90
// Date picker
91
const publishDateField = field({
92
type: 'date',
93
name: 'publishedAt',
94
label: 'Publish Date',
95
default: new Date(),
96
options: {
97
format: 'YYYY-MM-DD',
98
minDate: new Date()
99
}
100
});
101
```
102
103
### Group Definition
104
105
Groups preview fields with schema validation and organization.
106
107
```typescript { .api }
108
/**
109
* Groups preview fields with schema validation
110
* @param config - Group configuration object
111
* @returns Configured preview group
112
*/
113
function group(config: GroupConfig): PreviewGroup;
114
115
interface GroupConfig {
116
/** Group identifier */
117
name: string;
118
/** Display label for group */
119
label?: string;
120
/** Fields within this group */
121
fields: PreviewField[];
122
/** Group validation schema */
123
schema?: PartialSchema;
124
/** Group display options */
125
options?: GroupOptions;
126
}
127
128
interface PreviewGroup {
129
name: string;
130
label: string;
131
fields: PreviewField[];
132
schema: PartialSchema;
133
options: GroupOptions;
134
}
135
```
136
137
**Usage Examples:**
138
139
```typescript
140
import { field, group } from '@nuxt/content/preview';
141
142
// Article metadata group
143
const metadataGroup = group({
144
name: 'metadata',
145
label: 'Article Metadata',
146
fields: [
147
field({
148
type: 'text',
149
name: 'title',
150
label: 'Title',
151
required: true
152
}),
153
field({
154
type: 'textarea',
155
name: 'description',
156
label: 'Description',
157
options: { rows: 3 }
158
}),
159
field({
160
type: 'select',
161
name: 'status',
162
label: 'Status',
163
default: 'draft',
164
options: {
165
choices: [
166
{ label: 'Draft', value: 'draft' },
167
{ label: 'Published', value: 'published' },
168
{ label: 'Archived', value: 'archived' }
169
]
170
}
171
})
172
],
173
options: {
174
collapsible: true,
175
expanded: true
176
}
177
});
178
179
// Author information group
180
const authorGroup = group({
181
name: 'author',
182
label: 'Author Information',
183
fields: [
184
field({
185
type: 'text',
186
name: 'name',
187
label: 'Author Name',
188
required: true
189
}),
190
field({
191
type: 'email',
192
name: 'email',
193
label: 'Author Email'
194
}),
195
field({
196
type: 'image',
197
name: 'avatar',
198
label: 'Author Avatar',
199
options: {
200
accept: 'image/*',
201
maxSize: '2MB'
202
}
203
})
204
]
205
});
206
```
207
208
## Field Types
209
210
### Text Input Types
211
212
```typescript { .api }
213
type TextFieldTypes = 'text' | 'textarea' | 'email' | 'url' | 'password';
214
215
interface TextFieldOptions {
216
/** Placeholder text */
217
placeholder?: string;
218
/** Maximum character length */
219
maxLength?: number;
220
/** Minimum character length */
221
minLength?: number;
222
/** Input pattern regex */
223
pattern?: string;
224
/** Number of rows (textarea only) */
225
rows?: number;
226
/** Auto-resize textarea */
227
autoResize?: boolean;
228
}
229
```
230
231
### Rich Content Types
232
233
```typescript { .api }
234
type RichContentTypes = 'richtext' | 'markdown' | 'code';
235
236
interface RichTextOptions {
237
/** Toolbar buttons to show */
238
toolbar?: string[];
239
/** Editor placeholder */
240
placeholder?: string;
241
/** Enable code blocks */
242
codeBlocks?: boolean;
243
/** Custom editor extensions */
244
extensions?: EditorExtension[];
245
}
246
247
interface MarkdownOptions {
248
/** Enable live preview */
249
preview?: boolean;
250
/** Syntax highlighting theme */
251
theme?: string;
252
/** Supported languages for code blocks */
253
languages?: string[];
254
}
255
256
interface CodeOptions {
257
/** Programming language */
258
language?: string;
259
/** Show line numbers */
260
lineNumbers?: boolean;
261
/** Editor theme */
262
theme?: string;
263
/** Tab size */
264
tabSize?: number;
265
}
266
```
267
268
### Selection Types
269
270
```typescript { .api }
271
type SelectionTypes = 'select' | 'multiselect' | 'radio' | 'checkbox' | 'toggle';
272
273
interface SelectionOptions {
274
/** Available choices */
275
choices: Choice[];
276
/** Allow multiple selections */
277
multiple?: boolean;
278
/** Enable search/filtering */
279
searchable?: boolean;
280
/** Maximum selections (multiselect) */
281
maxSelections?: number;
282
}
283
284
interface Choice {
285
/** Display label */
286
label: string;
287
/** Option value */
288
value: string | number;
289
/** Option description */
290
description?: string;
291
/** Option disabled state */
292
disabled?: boolean;
293
/** Option group */
294
group?: string;
295
}
296
```
297
298
### Media Types
299
300
```typescript { .api }
301
type MediaTypes = 'image' | 'file' | 'video' | 'audio';
302
303
interface MediaOptions {
304
/** Accepted file types */
305
accept?: string;
306
/** Maximum file size */
307
maxSize?: string;
308
/** Image dimensions */
309
dimensions?: {
310
width?: number;
311
height?: number;
312
aspectRatio?: string;
313
};
314
/** Generate thumbnails */
315
thumbnails?: boolean;
316
/** Upload destination */
317
destination?: string;
318
}
319
```
320
321
### Date and Time Types
322
323
```typescript { .api }
324
type DateTimeTypes = 'date' | 'datetime' | 'time';
325
326
interface DateTimeOptions {
327
/** Date format */
328
format?: string;
329
/** Minimum date */
330
minDate?: Date;
331
/** Maximum date */
332
maxDate?: Date;
333
/** Enable time picker */
334
enableTime?: boolean;
335
/** Time format (12/24 hour) */
336
timeFormat?: '12' | '24';
337
/** Default timezone */
338
timezone?: string;
339
}
340
```
341
342
## Validation
343
344
### Validation Rules
345
346
```typescript { .api }
347
interface ValidationRule {
348
/** Validation type */
349
type: ValidationType;
350
/** Validation value/parameter */
351
value?: unknown;
352
/** Error message */
353
message: string;
354
/** Custom validation function */
355
validator?: (value: unknown) => boolean | Promise<boolean>;
356
}
357
358
type ValidationType =
359
| 'required' | 'minLength' | 'maxLength'
360
| 'min' | 'max' | 'email' | 'url'
361
| 'pattern' | 'custom';
362
```
363
364
**Usage Examples:**
365
366
```typescript
367
// Complex validation rules
368
const emailField = field({
369
type: 'email',
370
name: 'email',
371
label: 'Email Address',
372
required: true,
373
validation: [
374
{
375
type: 'required',
376
message: 'Email is required'
377
},
378
{
379
type: 'email',
380
message: 'Must be a valid email address'
381
},
382
{
383
type: 'custom',
384
message: 'Email domain not allowed',
385
validator: async (email) => {
386
const domain = email.split('@')[1];
387
const allowedDomains = ['company.com', 'partner.com'];
388
return allowedDomains.includes(domain);
389
}
390
}
391
]
392
});
393
```
394
395
## Preview Integration
396
397
### Content Form Configuration
398
399
```typescript
400
// content/blog/preview.config.ts
401
import { field, group } from '@nuxt/content/preview';
402
403
export default {
404
// Field groups for content editing
405
groups: [
406
group({
407
name: 'content',
408
label: 'Content',
409
fields: [
410
field({
411
type: 'text',
412
name: 'title',
413
label: 'Title',
414
required: true
415
}),
416
field({
417
type: 'richtext',
418
name: 'content',
419
label: 'Content',
420
required: true
421
})
422
]
423
}),
424
425
group({
426
name: 'meta',
427
label: 'Metadata',
428
fields: [
429
field({
430
type: 'date',
431
name: 'publishedAt',
432
label: 'Publish Date'
433
}),
434
field({
435
type: 'multiselect',
436
name: 'tags',
437
label: 'Tags',
438
options: {
439
choices: [
440
{ label: 'Vue.js', value: 'vue' },
441
{ label: 'Nuxt.js', value: 'nuxt' },
442
{ label: 'JavaScript', value: 'js' }
443
]
444
}
445
})
446
]
447
})
448
]
449
};
450
```
451
452
## Types
453
454
```typescript { .api }
455
type PickerTypes =
456
| 'text' | 'textarea' | 'email' | 'url' | 'password'
457
| 'richtext' | 'markdown' | 'code'
458
| 'select' | 'multiselect' | 'radio' | 'checkbox' | 'toggle'
459
| 'image' | 'file' | 'video' | 'audio'
460
| 'date' | 'datetime' | 'time'
461
| 'number' | 'range' | 'color';
462
463
interface PreviewFieldData {
464
/** Field type */
465
type: PickerTypes;
466
/** Field value */
467
value: unknown;
468
/** Field metadata */
469
meta: FieldMeta;
470
/** Validation state */
471
validation: ValidationState;
472
}
473
474
interface ConfigInputsTypes {
475
[fieldName: string]: PickerTypes;
476
}
477
478
interface PartialSchema {
479
/** Schema validation function */
480
validate: (data: unknown) => ValidationResult;
481
/** Schema transformation function */
482
transform?: (data: unknown) => unknown;
483
}
484
485
interface GroupOptions {
486
/** Group is collapsible */
487
collapsible?: boolean;
488
/** Group is expanded by default */
489
expanded?: boolean;
490
/** Group display order */
491
order?: number;
492
/** Group CSS classes */
493
className?: string;
494
/** Group conditional display */
495
conditional?: ConditionalRule;
496
}
497
498
interface ConditionalRule {
499
/** Field to watch for condition */
500
field: string;
501
/** Condition operator */
502
operator: '=' | '!=' | 'in' | 'not_in';
503
/** Condition value */
504
value: unknown;
505
}
506
```