# Reference - SSR websites

> Every export of the module am-ssr, every member of ctx, PageConfig, the props of pages, layouts and error pages, and what a page, a layout, a middleware and an endpoint export.

Source: https://docs.apimaker.dev/v4/docs/ssr/api-reference.html

The declarations are the module `am-ssr` (the panel gives them to its editor ; a commit writes them as `am-ssr.d.ts` next to each website).

## What a file exports

| File | Exports |
|---|---|
| A page (`pages/**/*.tsx`) | `default` (the component), `loader`, `action`, `config`, `head` |
| A layout (`_layout.tsx`) | `default` (gets `children`), `loader`, `config`, `head` |
| A middleware (`_middleware.ts`) | `default` (or `middleware`) : `(ctx) => answer | undefined` |
| `_404.tsx`, `_error.tsx` | `default` (gets `error`), `config`, `head` |
| An endpoint (`pages/**/*.ts`) | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `ALL`, `config` |
| `site.config.ts` | `default` : `defineSite({ ... })`, values only. See [settings](https://docs.apimaker.dev/v4/docs/ssr/site-config.html). |

## The module `am-ssr`

| Export | What it is |
|---|---|
| `raw(html)` | HTML written as it is. Never what a visitor wrote. |
| `url(path)` | An address of the website with its base path, for a value which is no attribute. |
| `asset(path)` | A file of `public/` with the hash of its content : kept a year by browsers. |
| `withoutBase(path)` | An address of the server outside the website. |
| `serialize(value)` | JSON a `<script>` can hold. |
| `escape(text)` | A text as HTML writes it. |
| `classNames(...values)` | `classNames('btn', active && 'active', { disabled })`. |
| `Fragment` | `<>…</>`. |
| `formatDate(value, pattern?, { utc, offsetMinutes })` | `formatDate(date, 'D MMM YYYY [at] HH:mm')` : `YYYY YY MMMM MMM MM M DD D dddd ddd HH H hh h mm m ss s SSS A a`. UTC by default. |
| `formatNumber(value, { decimals, thousands, decimal })` | `1,234.50` |
| `formatCurrency(value, currency?, options?)` | `formatCurrency(1234.5, 'USD')` is `$1,234.50`. |
| `timeAgo(value, now?)` | `5 minutes ago`, `in 2 days`. |
| `slugify(text)`, `truncate(text, length, more?)` | |
| `paginate({ page, perPage, total, window })` | `{ page, pages, total, perPage, skip, limit, items, hasPrevious, hasNext, previous, next }` : `items` are the numbers to show, `'…'` where some are left out. |
| `json(data, { status, headers })`, `text(body, init)` | An answer of an endpoint, an action or a middleware. |
| `Response` | `new Response(body, { status, headers, type })`. |
| `redirect(location, status?, { external })` | Stops the render : the browser goes there. Another host needs `{ external: true }`. |
| `notFound(message?)`, `forbidden(message?)`, `error(status, message?)` | Stop the render with the page of the error. |
| `HttpError` | What those throw, and what a refused call of `ctx.db` throws : `status`, `message`, `errors`. |
| `definePage(config)`, `defineSite(config)` | Typed settings. |
| `site` | `{ name, title }` of the website. |

## `ctx`

One per request : never keep it in a variable of a module.

| Member | What it is |
|---|---|
| `method`, `url`, `path` | The request : `path` without the base path (`/products`), `url` with the query. |
| `params` | The values of the parts of the path : `[id]` is `params.id`, `[...rest]` a list. |
| `query` | The query : texts, a list when a name is repeated. |
| `headers` | The headers, their names in small letters. |
| `body`, `form` | The body (a form, JSON) ; `form` its fields. |
| `files` | The files of a form of several parts : `{ fieldname, originalname, mimetype, size, path, filename }`. |
| `ip`, `locale` | The address of the visitor ; the language it prefers. |
| `csrf` | Its CSRF token (forms get it by themselves). |
| `dev` | The page renders for the preview of the panel. |
| `site` | `{ name, title, base, origin }` : `base` is `/ssr/<apiPath>/<name>` or nothing behind a domain, `origin` `https://host`. |
| `user` | The visitor who signed in, or `null`. |
| `auth` | `user`, `isLoggedIn`, `groups`, `hasGroup(...)`, `login({ provider, username, password })`, `logout()`, `setToken(kind, token)`. |
| `cookies` | `get(name)`, `all()`, `set(name, value, { maxAge, expires, path, httpOnly, secure, sameSite })`, `delete(name)`. The cookies of API Maker are not seen. |
| `db` | The tables the website lists : `getAll`, `getById`, `query`, `count`, `distinct`, `distinctQuery`, `aggregate`, `saveSingleOrMultiple`, `masterSave`, `arrayOperations`, `updateById`, `updateMany`, `replaceById`, `removeById`, `removeByQuery`, and `gen.*`. |
| `api` | `api.db` (the same words, as the visitor), `api.customApi(path, { method, body, query, headers })`. |
| `sys` | `g.sys`, when `data.allowSys` turns it on. |
| `cache` | `get`, `set(key, value, seconds)`, `remove`, `getOrSet(key, seconds, make)` : Redis, the keys of the website. |
| `fetch(address, { method, headers, body, timeout })` | To the hosts `data.fetch` lists : `{ status, headers, body, json }`. |
| `revalidate(...tags)` | Drops the kept pages of these tags. |
| `flashes`, `flash(type, text)` | The messages kept for this page ; a message for the next one. |
| `status(code)`, `setHeader(name, value)` | The status and the headers of the answer. |
| `redirect`, `notFound`, `forbidden`, `unauthorized`, `error` | As the functions of `am-ssr`. |
| `json(data, status)`, `text(body, status)`, `html(body, status)` | Answers. `html()` takes a text or what a component gives. |
| `link(path)`, `asset(path)`, `withoutBase(path)` | Addresses. |
| `log(...values)` | Writes to the console of the account. |

## `PageConfig`

| Field | What it is |
|---|---|
| `title`, `description`, `image`, `canonical` | The head. A value, or `(data, ctx) => value`. |
| `index` | `false` : not indexed. |
| `access` | `'public'`, `'authenticated'`, `{ authenticated, groups, providers, check }`. |
| `cache` | `{ maxAge, staleWhileRevalidate, scope, tags, query }`. |
| `libraries` | `false` for none, a list of names, every library of the list by default. |
| `csrf` | `false` : an endpoint which takes requests without the token. |
| `sitemap` | `false`, or `{ changefreq, priority }`. |

## `SiteConfig`

What `defineSite` of `site.config.ts` takes, typed setting by setting : every member says what it does, its default and the values the server takes, and the editor marks a setting of another name. See [settings](https://docs.apimaker.dev/v4/docs/ssr/site-config.html#typed-settings).

| Type | What it is |
|---|---|
| `SiteConfig` | `{ title, titleTemplate, description, lang, domains, auth, defaultAccess, data, cache, security, seo, redirects, trailingSlash, maintenance, limits }` |
| `SiteAuth` | `auth` : `{ providers, loginPath, sessionDays }`. `loginPath` is a path of the website (`` `/${string}` ``). |
| `SiteAccess` | `defaultAccess` : `'public'`, `'authenticated'`, `{ authenticated, groups, providers }`, without code. |
| `SiteData` | `data` : `{ read, write, apiUser, allowSys, fetch }`. |
| `TableName` | `` `${string}/${string}/${string}` `` : `'instance/database/table'`. |
| `TableRule` | `{ table, where, set, requireUser, fields, allow }`. |
| `TableWrite` | `'create'`, `'update'`, `'delete'`. |
| `SiteSecurity` | `security` : `{ csp, frameAncestors, headers }`. |
| `SiteSeo` | `seo` : `{ sitemap, robots, noIndex }`. |
| `SiteRedirect` | An item of `redirects` : `{ from, to, status }`, `from` a path. |
| `SiteMaintenance` | `maintenance` as an object : `{ message, allowGroups }`. |
| `SiteLimits` | `limits` : `{ memoryMb, cpuMs, timeoutMs }`. |

## Props

| | |
|---|---|
| `PageProps<typeof loader, ActionData>` | `{ data, ctx, params, actionData }` |
| `LayoutProps<typeof loader>` | `{ children, data, ctx, error }` |
| `ErrorProps` | `{ error: { status, message, stack, errors }, ctx }` |
| `Head` | `{ title, description, image, canonical, index, meta: [...], links: [...] }` |

## Inside the engine

A page runs in QuickJS, not in Node.js : the language of today (ES2023), `fetch`-less (use `ctx.fetch`), no `require` of npm packages, no file system. There are `URL`, `URLSearchParams`, `TextEncoder`, `TextDecoder`, `crypto.randomUUID()`, `crypto.getRandomValues()`, `structuredClone`, `queueMicrotask`, `atob`, `btoa`, `console`. Code shared by the pages is a file of the website (`lib/`) ; libraries for the browser are [UI libraries](https://docs.apimaker.dev/v4/docs/ssr/ui-libraries.html).
