Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/alineacms/alinea/llms.txt

Use this file to discover all available pages before exploring further.

Alinea’s dashboard is built with React and exposes three extension points where you can replace the default UI with your own components. Custom views let you embed bespoke editing interfaces, add contextual tooling alongside entries, or change how entries appear in content lists — all without leaving the Alinea configuration model.

Extension points

Extension pointWhere it appearsRegistered on
Entry viewReplaces the entire entry edit form when an entry of this type is openedType via the view option
Root viewReplaces the sidebar panel when a root is selected in the workspace treeRoot via the view option
Summary rowCustomises how an entry appears as a row in the content listType via the summaryRow option
Summary thumbCustomises how an entry appears as a thumbnail in the content gridType via the summaryThumb option

Specifying a view path

The view, summaryRow, and summaryThumb options all accept a string in the format:
'./path/to/Component.tsx#ExportName'
The path is resolved relative to your project root. The fragment (#ExportName) identifies the named export to use. If the component is the default export, you can omit the fragment. Alinea reads these paths at build time and bundles the referenced components into the dashboard. The components are only loaded in the dashboard — they are not included in your production application bundle.
View components are dashboard-only. They run inside the Alinea iframe and have access to dashboard hooks but are not part of your Next.js application bundle. Do not import heavy server-side or Node.js-only dependencies in view files.

Custom root view

A root view replaces the content panel that normally shows a list of entries. Use it to embed a custom landing page, analytics widget, or any React component inside the root navigation.
apps/dev/src/cms.tsx (root view registration)
import {Config} from 'alinea'
import {createCMS} from 'alinea/next'

export const cms = createCMS({
  schema,
  workspaces: {
    primary: Config.workspace('Primary workspace', {
      source: 'content/primary',
      roots: {
        custom: Config.root('Custom', {
          contains: [schema.CustomPage],
          view: './src/CustomRootView.tsx#CustomRootView'
        })
      }
    })
  }
})
The component itself is a plain React component that receives a root prop:
apps/dev/src/CustomRootView.tsx
export function CustomRootView() {
  return (
    <div style={{width: '100%', height: '100%', background: 'yellow'}}>
      Custom root view
    </div>
  )
}
view
string | ((props: {root: RootData}) => ReactNode)
A path string ('./path/to/File.tsx#Export') or an inline function component. The component receives a root prop containing the root’s metadata.

Custom entry view

An entry view replaces the default field-based edit form for entries of a specific type. The component receives an editor prop — the EntryEditor instance for the current entry.
Registering a custom entry view on a type
import {Config, Field} from 'alinea'

export const CustomPage = Config.document('Custom page', {
  fields: {
    title: Field.text('Title')
  },
  view: './src/schema/example/CustomEntryView.tsx'
})
apps/dev/src/schema/example/CustomEntryView.tsx
export default function CustomEntryView() {
  return (
    <div style={{width: '100%', height: '100%', background: 'red'}}>
      Custom entry view
    </div>
  )
}
view
string | ((props: EntryEditProps & {type: Type}) => ReactNode)
A path string or inline component. Receives editor (an EntryEditor) and type (the current Type). When a string is used, the referenced component can be a default or named export.

Custom view section (Field.view)

Instead of replacing the entire entry form, you can embed a custom component as a section between fields using Field.view. This lets you inject a React component at a specific position within the standard form layout.
apps/dev/src/schema/example/CustomViewExample.tsx
import {Config, Field} from 'alinea'

export const CustomViewExample = Config.document('Custom view', {
  fields: {
    ...Field.view('@/schema/example/CustomViewExample.view#CustomViewExample')
  }
})
apps/dev/src/schema/example/CustomViewExample.view.tsx
export function CustomViewExample() {
  return <div>Custom view example</div>
}
Field.view accepts the same path string format and inserts the component as an inline section between other fields. Use it for contextual help panels, live previews, data visualisations, or any interactive widget that should appear within the editing flow.

Summary views (summaryRow and summaryThumb)

The summaryRow and summaryThumb options customise how entries of a type appear in the content list. They accept the same path string format as view.
Custom summary row and thumbnail
import {Config, Field} from 'alinea'

export const Product = Config.document('Product', {
  fields: {
    title: Field.text('Title'),
    price: Field.number('Price')
  },
  summaryRow: './src/schema/ProductSummaryRow.tsx#ProductSummaryRow',
  summaryThumb: './src/schema/ProductSummaryThumb.tsx#ProductSummaryThumb'
})
Summary components receive a SummaryProps object with the entry’s metadata and (for MediaFile entries) image dimensions and preview data:
SummaryProps shape
type SummaryProps = {
  id: string
  type: string
  workspace: string
  root: string
  title: string
  path: string
  url: string
  // MediaFile-specific (empty string / 0 for non-media entries)
  extension: string
  size: number
  preview: string
  thumbHash: string
  averageColor: string
  focus: {x: number; y: number}
  width: number
  height: number
  parents: Array<{id: string; title: string}>
  childrenAmount: number
}
summaryRow
string | ((props: SummaryProps) => ReactNode)
Component rendered as a table row in the list view of the content browser.
summaryThumb
string | ((props: SummaryProps) => ReactNode)
Component rendered as a card in the thumbnail/grid view of the content browser.

View path resolution

All view path strings follow this convention:
'<module-specifier>#<ExportName>'
  • Module specifier — a file path relative to the project root, or any resolvable module alias (e.g. @/schema/...). Both ./src/MyView.tsx and @/schema/MyView.tsx work.
  • Export name — the name of the exported component (#MyComponent). Omit the fragment to use the default export.
Examples:
Path stringResolves to
'./src/CustomRootView.tsx#CustomRootView'Named export CustomRootView from ./src/CustomRootView.tsx
'./src/schema/example/CustomEntryView.tsx'Default export from CustomEntryView.tsx
'@/schema/example/CustomViewExample.view#CustomViewExample'Named export CustomViewExample via alias
Alinea collects all referenced view paths during the alinea build step and bundles them into the dashboard. If a path cannot be resolved, the build will fail with a clear error pointing to the missing file.

Build docs developers (and LLMs) love