Markdown View
The markdown view renders a single entity's markdown field as formatted HTML. It is useful for blog posts, notes, or any rich-text content stored as markdown.
Getting Started with Vite
Vite is a next-generation frontend build tool that dramatically improves the development experience.
Why Vite?
Traditional bundlers process your entire codebase before serving. Vite serves source files over native ESM, making cold starts near-instant.
To create a new project, run:
npm create vite@latest my-appSpec
const spec: MarkdownViewSpec = {
entityEndpoint: { method: 'GET', url: '/posts/{id}' },
field: 'body',
metadata: { title: 'Post Preview' },
};How it works
The SPA navigates to #/{resource}/{id}/render and fetches a MarkdownViewSpec from the server:
{
"entityEndpoint": { "method": "GET", "url": "/posts/42" },
"field": "body"
}It then fetches the entity, extracts the body field, parses it with marked, and renders the HTML.
Setup (JS)
import type { MarkdownViewSpec } from '@retrofit-ui/builder-zod';
// URL prefix below is arbitrary — pick anything and match `apiBase` to it.
app.get('/pages/posts/:id/render', (req, res) => {
const spec: MarkdownViewSpec = {
entityEndpoint: { method: 'GET', url: `/posts/${req.params.id}` },
field: 'body',
metadata: { title: 'Post Preview' },
};
res.json(retrofit(spec));
});Linking from the table
Use rowAction on the table spec to add a per-row "Preview" button:
TableView.schema(PostSchema)
.rowAction({ label: 'Preview', routePattern: '/{id}/render' })
.list({ method: 'GET', url: '/posts' })
.find({ method: 'GET', url: '/posts/{id}' })
.build();routePattern is appended to #/{resource}/ in the hash router. With routePattern: '/{id}/render', clicking Preview on row 42 navigates to #/posts/42/render.
The back button
The markdown view renders a "← Back" button automatically. It navigates to #/{resource}/{id} (the edit form).
Markdown field type in forms
To let users edit the markdown source, use a fieldOverride to set the field type to 'markdown':
formSpec(PostSchema, UpdatePostSchema)
.fieldOverride('body', { type: 'markdown' })
// ...This renders a taller <sl-textarea> with "Markdown supported" as the help text.