# Render pages and forms

## Compose a documentation layout

```ts
import { renderDocsLayout, renderForm } from "@qentrah/templates";

const form = renderForm({
  action: "/articles",
  method: "POST",
  fields: [{ name: "title", label: "Title", type: "text", required: true }],
  submitButtons: [{ label: "Save", type: "submit" }],
});

const html = renderDocsLayout({
  title: "New article",
  content: form,
  currentPath: "/articles/new",
  navigation: [{ title: "Articles", path: "/articles" }],
});
```

Both functions return strings. The form action must point to a route implemented by your server. Rendering a form does not save a record.

## Form data contract

`fields` and `submitButtons` are required. Optional form settings include `id`, `action`, `method`, `hxPost`, `hxPut`, `hxTarget`, `title`, `description`, and `className`. Field types include text, email, textarea, select, checkbox, rich_text, number, date, multi_select and file.

## Input handling

The templates interpolate HTML. Validate and sanitize untrusted values in your application. Server handlers must perform their own authentication, authorization and input validation. Never treat a rendered interface as a security boundary.

## Existing template families

The root also exposes cache, database-table, content-edit, content-new, checkbox, FAQ, API-reference, field-types and content-list renderers. Inspect each declaration’s data type before calling it; the renderers do not share one universal parameter object.