documentField
Upload a document such as a PDF, a Word or Excel file, a presentation, or a CSV.
import { documentField } from 'nextjs-cms/core/fields'Basic usage
documentField({ name: 'brochure' })Accepts a PDF up to 2 MB.
With every option
documentField({
name: 'spec_sheet',
label: { en: 'Specification sheet', ar: 'ورقة المواصفات' },
required: true,
order: 8,
localized: true, // a different PDF per language
conditionalRules: [{ field: hasSpecs, condition: 'equals', value: true }],
fileType: ['pdf', 'docx', 'xlsx'],
maxFileSize: { size: 20, unit: 'mb' },
})Options
| Option | Type | Default | Description |
|---|---|---|---|
fileType | ('pdf' | 'doc' | 'docx' | 'xls' | 'xlsx' | 'ppt' | 'pptx' | 'txt' | 'csv')[] | ['pdf'] | Accepted formats. |
maxFileSize | { size: number; unit: 'kb' | 'mb' } | { size: 2, unit: 'mb' } | Largest accepted upload. |
Plus the common options.
Validation
- The extension must be in
fileType, and for binary formats the file's content must match it (magic bytes), so a renamed executable is rejected. - The size must be within
maxFileSize.
Examples
Downloadable price list
documentField({ name: 'price_list', fileType: ['pdf', 'xlsx'], maxFileSize: { size: 10, unit: 'mb' } })Localized legal documents
documentField({ name: 'terms_pdf', label: 'Terms (PDF)', fileType: ['pdf'], localized: true })Each locale gets its own file; see Localization.
A download link on your website
Files are stored without an extension, so give the browser a proper name and type when serving them:
website/app/downloads/[id]/route.ts
import { readFile } from 'node:fs/promises'
import path from 'node:path'
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
const product = await getProduct(Number((await params).id))
if (!product?.specSheet) return new Response('Not found', { status: 404 })
const file = await readFile(path.join(process.env.CMS_UPLOADS_DIR!, '.documents', 'products', product.specSheet))
return new Response(file, {
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${product.slug}-specs.pdf"`,
},
})
}Storage
| Column | VARCHAR(50) |
| Value | Generated file name (21 hex characters, no extension) |
| File | <uploads>/.documents/<section>/<name> |