# Navigation, Pagination, and SEO

Iwf includes small helpers for common server-rendered UI patterns. They target
Basecoat by default and expose options records for custom markup.

## 1. Navigation

Build navigation items:

```idris
mainNav : Html
mainNav =
  navigationNav "Main"
    [ navItem "Home" "/" True
    , navItem "New article" "/editor" False
    , navTextItem "Settings" False
    ]
```

Current items receive `aria-current="page"`.

Use custom options when the layout needs different classes:

```idris
customNav : Html
customNav =
  navigationNavWith options "Main" items
```

## 2. Breadcrumbs

```idris
articleBreadcrumbs : Html
articleBreadcrumbs =
  breadcrumbNav
    [ navItem "Home" "/" False
    , navItem "Articles" "/articles" False
    , navTextItem "Fullstack Idris" True
    ]
```

Use `breadcrumbNavWith` for custom classes or attributes.

## 3. Pagination

Compute pagination:

```idris
pagination : Pagination
pagination =
  paginate page 20 totalArticles
```

Use these values in SQL:

```idris
limit pagination
offset pagination
```

Render a nav:

```idris
articlesPagination : Pagination -> Html
articlesPagination pagination =
  paginationNav (\page => "/articles?page=" ++ show page) pagination
```

Useful helpers:

- `paginate`
- `offset`
- `limit`
- `totalPages`
- `hasPrevious`
- `hasNext`
- `previousPage`
- `nextPage`
- `pageNumbers`
- `paginationNav`
- `paginationNavWith`

## 4. Page Head

Add head entries in a top-level `<head>` returned by the page:

```idris
articlePageWithHead : Article -> Html
articlePageWithHead article =
  fragment
    [ <head>
      <title>{article.title}</title>
      {descriptionMeta article.description}
      {canonicalLink ("https://example.test/article/" ++ article.slug)}
      {openGraphTitle article.title}
      {openGraphDescription article.description}
    </head>
    , <main id="main-content">
        <h1>{article.title}</h1>
      </main>
    ]
```

Helpers:

- `descriptionMeta`
- `robotsMeta`
- `canonicalLink`
- `openGraphTitle`
- `openGraphDescription`
- `openGraphUrl`
- `openGraphImage`

## 5. Sitemap

Create sitemap XML:

```idris
sitemap : String
sitemap =
  sitemapXml
    [ sitemapUrl "https://example.test/"
    , sitemapUrl "https://example.test/articles"
    ]
```

Mount it as an `okHtml` or custom XML response from a normal route.

## Next

Read [Security and Deployment](security-and-deployment.md).
