/article/add Page Summary
Access Control
- Server component (page.tsx) checks session on every request
- Non-admin users are immediately redirected to
/
Form Fields
(add-article-form.tsx)
| Field | Type | Behavior |
|---|
| Title | Text input | Required. Auto-generates slug as you type |
| Slug | Text input | Pre-filled from title (kebab-case). Becomes independent once manually edited |
| Date | Date picker | Defaults to today's date |
| Tags | Text input | Comma-separated string, split into string[] on submit |
| Body | Three-mode editor | See Body Modes below |
Body Modes
A toggle in the top-right corner of the body field switches between three modes. body state is always a markdown string and stays in sync across all modes.
| Mode | Description |
|---|
| Rich Text | Lexical WYSIWYG editor with full toolbar. Serializes to markdown via $convertToMarkdownString on every change. Remounts with $convertFromMarkdownString when switching back from Markdown mode. |
| Markdown | Plain monospace <textarea> that reads/writes body directly as raw markdown. |
| Preview | Rendered output via ArticlePreview, which supports headings, blockquotes, code blocks, tables, HR, and links. |
Lexical Toolbar
(lexical-editor.tsx)
| Group | Buttons |
|---|
| History | Undo, Redo (disabled when unavailable) |
| Text format | Bold, Italic, Underline, Strikethrough, Inline Code, Superscript, Subscript |
| Block type | Paragraph, H1, H2, H3, Blockquote, Code Block |
| Lists | Bullet list, Numbered list |
| Alignment | Left, Center, Right, Justify |
| Insert | Link (inline URL input), Horizontal Rule |
Submit Flow
- Submit button is disabled until title, slug, and body are all non-empty
- Calls
createArticle server action (article-actions.ts)
- Re-validates admin role server-side
- Inserts into the
articles table via Drizzle
- Revalidates
/article cache
- Success → shows "Article published successfully!" with a "Write another" button that resets the form
- Error → displays error message inline above the submit button
Key Files