---
title: App and areas
description: Register resources, navigation, and request handlers.
---

Use `defineApp` to register resources in named areas. Each area requires `label`,
`resources`, and `navigation`. An area can also have an `icon`.
Resource names must be unique across all areas. A request uses the resource
name, view or action name, and ordered arguments. It does not use the area name.

```ts title="app.ts"
import { defineApp } from '@backlit/sdk'

export default defineApp({
  preferences: { title: 'Operations' },
  areas: {
    sales: {
      label: 'Sales',
      icon: 'shopping-cart',
      resources: { orders: () => import('./orders.ts') },
      navigation: [
        { label: 'Orders', resource: 'orders', view: 'list' },
        {
          label: 'Reports',
          items: [
            {
              label: 'Summary',
              resource: 'orders',
              view: 'summary',
              icon: 'chart-line',
            },
          ],
        },
      ],
    },
  },
})
```

Keep resource module imports in loader functions. The app loads a resource when
a request needs it. Use the same key in the resource map and `defineResource`.
A navigation entry must name a registered resource. A group has a label and an
array of entries. Groups cannot contain other groups.

## Manifest and resource access

`app.toManifest()` returns preferences, areas, navigation, and extension identities.
`app.resourceNames()` returns registered names. Neither method loads resources.
`await app.loadResource(name)` loads one resource and returns its default export.

`preferences` accepts `title`, `logo`, `logoDark`, `logoVariant`, and `logoHeight`. See the generated
[AppConfig type](/reference/api/types#appconfig) for the complete configuration.

## Requests

These methods return protocol responses:

| Method         | Arguments after the method name                    |
| -------------- | -------------------------------------------------- |
| `renderView`   | `resource, view, args?, transport?, search?`       |
| `renderZone`   | `resource, view, zone, args?, transport?, search?` |
| `handleAction` | `resource, action, payload, args?, transport?`     |
| `handleLookup` | `resource, lookup, searchQuery, args?, transport?` |

Arguments are strings in parameter order. The argument count must match the
definition exactly. An unknown resource or endpoint returns a `404` response.
A missing zone returns `E_ZONE_NOT_FOUND`.

The app does not start an HTTP server. A host adapter maps requests to these
methods. Use [Request handling](/reference/requests) for middleware and transport.
Use [Search state](/reference/state) for the `search` argument.

## Extensions

Pass server extensions in `extensions`. They run before resource requests.
Pass lazy middleware imports in `middleware`. Middleware runs in registration
order for view, zone, action, and lookup requests.

See [Extensions](/advanced/extensions) and [Agent tools](/reference/agents).

## Complete app example

This example has a view, a zone, a lookup, an action, and middleware. The action
returns a notification and does not write to a database. The test suite calls
the app methods for valid requests, validation failures, and missing addresses.

<BacklitExample path="runtime/basic" view="list" />
