# SSR websites

> Websites written in TSX and rendered by the API Maker server, next to your data - file routing, layouts, loaders, forms with CSRF protection, sign-in with your auth providers, row rules, page cache, UI libraries, SEO, git and templates.

Source: https://docs.apimaker.dev/v4/docs/ssr/index.html

A website of API Maker is a folder of files : pages written in TSX, the components and the code they share, files sent as they are, and its settings. The server renders the pages next to your data and sends HTML : the browser shows a page as it reads it, and nothing runs in it unless you add a script.

A website answers at `/ssr/<apiPath>/<name>/` of the server : the path of its account, as the addresses of its APIs have it, then its name, unique in the account. A reverse proxy shows it at the root of a domain of its own : see [deployment](https://docs.apimaker.dev/v4/docs/ssr/deployment.html).

| | |
|---|---|
| Where | Dashboard → **SSR Websites** : a website from a template, its files, the editor, the preview, its UI libraries, its routes, its settings. [The panel](https://docs.apimaker.dev/v4/docs/ssr/editor.html). |
| Pages | `pages/` : `index.tsx` is `/`, `blog/[slug].tsx` is `/blog/:slug`, a `.ts` file is an endpoint. [Routing](https://docs.apimaker.dev/v4/docs/ssr/pages-and-routing.html). |
| Data | A `loader` reads on the server ; `ctx.db` reaches the tables the website lists, with the rows each visitor may reach. [Data](https://docs.apimaker.dev/v4/docs/ssr/data.html). |
| Visitors | Sign-in with the auth providers of the account, `access` on a page or a layout, groups. [Authentication](https://docs.apimaker.dev/v4/docs/ssr/authentication.html). |
| Forms | An `action` takes a form ; every form carries a CSRF token by itself. [Forms](https://docs.apimaker.dev/v4/docs/ssr/forms.html). |
| Speed | Templates compiled when a file is saved, engines kept per website, pages kept by the server. [Cache](https://docs.apimaker.dev/v4/docs/ssr/caching.html). |
| Browser | Bootstrap, Tailwind, Chart.js, htmx… from a catalog with their hashes. [UI libraries](https://docs.apimaker.dev/v4/docs/ssr/ui-libraries.html). |
| Git | `src/ssr/<name>/` of the repository of the account : commit, pull, revert. [Git](https://docs.apimaker.dev/v4/docs/ssr/git.html). |

## Your first website

1. Dashboard → **SSR Websites** → **New website**.
2. Choose **Starter** : a page for every feature, each with comments which say why it is written so.
3. Name it `demo`. Its address is `/ssr/<apiPath>/demo/` : `/ssr/acme/demo/` for the account of the path `acme`.
4. Open `pages/index.tsx`, change a word, save with Ctrl+S : the preview reloads by itself.

A page :

**pages/products/index.tsx**

```tsx
import { formatCurrency } from 'am-ssr';
import type { PageConfig, PageContext, PageProps } from 'am-ssr';

export const config: PageConfig = {
    title: 'Products',
    // One page for every anonymous visitor, kept a minute.
    cache: { maxAge: 60, scope: 'public' },
};

// Runs on the server before the page renders : what it returns is `data`.
export async function loader(ctx: PageContext) {
    return {
        products: await ctx.db.query({ instance: 'mongodb', database: 'shop', table: 'products', limit: 20 }),
    };
}

export default function Products({ data }: PageProps<typeof loader>) {
    return (
        <ul>
            {data.products.map((product) => (
                <li>
                    <a href={`/products/${product.slug}`}>{product.name}</a> {formatCurrency(product.price, 'USD')}
                </li>
            ))}
        </ul>
    );
}
```

And its website lists the table it reads, in `site.config.ts` : a website reaches no table it does not name.

**site.config.ts**

```ts
import { defineSite } from 'am-ssr';

export default defineSite({
    title: 'My shop',
    titleTemplate: '%s · My shop',
    data: { read: ['mongodb/shop/products'] },
});
```

## The files of a website

```text
site.config.ts         the settings : tables ctx.db reaches, auth providers, CSP, cache, SEO, redirects
libraries.json         the UI libraries the pages load in the browser
pages/
  _layout.tsx          the HTML around every page
  _middleware.ts       code which runs before every page and endpoint
  _404.tsx  _error.tsx what a path no page answers shows, and what a page which failed shows
  index.tsx            /
  about.tsx            /about
  blog/[slug].tsx      /blog/:slug
  docs/[...path].tsx   /docs/a/b/c
  (shop)/cart.tsx      /cart, with the layout of (shop)/
  api/items.ts         an endpoint : GET, POST, PUT, PATCH, DELETE
components/            components the pages share : import Card from '@/components/Card'
lib/                   code the pages share
data/                  JSON the pages import : import posts from '@/data/posts.json'
public/                files sent as they are : public/logo.png is /logo.png
```

## What happens to a request

> Diagram : A request to an SSR website : route, access, cache, render, HTML
>
> The path of a request to an SSR website : the server finds the website and the route, checks who may open the page before any code of it runs, sends a page kept by the cache as it was kept, else renders it : middlewares, the action of a form, the loaders of the layouts and of the page at once, the page and its layouts. Then it writes the head, the CSRF token and the nonce of the CSP, and sends the HTML.

1. The server finds the website of `/ssr/<apiPath>/<name>`, built for its version : its files were compiled when they were saved.
2. Redirects of the settings, files of `public/`, `/robots.txt` and `/sitemap.xml` answer first.
3. The route of the path, and who may open it : the `access` of its layouts and of the page, read from their code when they were saved. A visitor who may not is refused **before any code of the page runs**.
4. A form of an unsafe method needs the CSRF token of its visitor.
5. A page kept by the cache is sent as it was kept.
6. The render, in an engine of the website : the middlewares, the `action` for a form, the loaders of the layouts and of the page at once, the page, then each layout around it.
7. The server writes the head (title, description, Open Graph, the UI libraries), the CSRF token and the nonce of the CSP into the page, and sends it.

## Safe by default

- Every value is escaped where it is written. HTML which is not is asked for by name (`raw()`).
- `ctx.db` reaches the tables `site.config.ts` lists, with the row rules it gives each : `{ customer_id: '$user._id' }` keeps every query to the rows of the visitor.
- Sessions are cookies sealed with AES-256-GCM, `HttpOnly`, `SameSite=Lax`, `Secure` over HTTPS.
- Every form has a CSRF token ; every `<script>` of a page has the nonce of the CSP ; `javascript:` addresses are refused.
- Each website runs in engines of its own, with a limit of memory and of time.

See [security](https://docs.apimaker.dev/v4/docs/ssr/security.html) for all of it.

## Read on

| Page | What it says |
|---|---|
| [The panel](https://docs.apimaker.dev/v4/docs/ssr/editor.html) | The files of a website (new files and folders, rename, drag and drop, uploads), the keys of the editor, the preview at the size of a device. |
| [Pages and routing](https://docs.apimaker.dev/v4/docs/ssr/pages-and-routing.html) | Files and paths, layouts, middlewares, 404 and error pages, endpoints, public files. |
| [Data](https://docs.apimaker.dev/v4/docs/ssr/data.html) | Loaders, `ctx.db`, `ctx.api`, `ctx.sys`, `ctx.fetch`, `ctx.cache`, JSON files. |
| [Forms](https://docs.apimaker.dev/v4/docs/ssr/forms.html) | Actions, checks, messages, the redirect after a post, uploads. |
| [Authentication](https://docs.apimaker.dev/v4/docs/ssr/authentication.html) | Sign-in, sign-up, sign-out, `access`, groups, row rules. |
| [Caching](https://docs.apimaker.dev/v4/docs/ssr/caching.html) | Pages kept by the server, tags, what is never kept. |
| [UI libraries](https://docs.apimaker.dev/v4/docs/ssr/ui-libraries.html) | The catalog, npm packages, self-hosting, the CSP. |
| [SEO](https://docs.apimaker.dev/v4/docs/ssr/seo.html) | Title, description, Open Graph, canonical, sitemap, robots, JSON-LD. |
| [Settings](https://docs.apimaker.dev/v4/docs/ssr/site-config.html) | Every setting of `site.config.ts`. |
| [Security](https://docs.apimaker.dev/v4/docs/ssr/security.html) | What the server does for you, and what is left to you. |
| [Deployment](https://docs.apimaker.dev/v4/docs/ssr/deployment.html) | Domains, reverse proxies, the settings of the server. |
| [Git](https://docs.apimaker.dev/v4/docs/ssr/git.html) | The websites in the repository : commit, pull, revert, editors. |
| [Templates](https://docs.apimaker.dev/v4/docs/ssr/templates.html) | The websites and the files a new one starts from. |
| [Examples](https://docs.apimaker.dev/v4/docs/ssr/examples.html) | Recipes for what websites do most. |
| [Reference](https://docs.apimaker.dev/v4/docs/ssr/api-reference.html) | The module `am-ssr`, `ctx`, `PageConfig`. |
| [Guide for AI](https://docs.apimaker.dev/v4/docs/ssr/ai-guide.html) | What an assistant needs to write a page right the first time. |
