---
canonical: "https://agi-labo.com/en/tools/wings/docs/web-apps"
title: "Web Apps and sharing"
description: "Build a browser app and share it with people you choose."
section: "Core features"
order: 7
pageType: "how-to"
lastVerifiedVersion: "1.4.16"
lastVerifiedAt: "2026-10-15"
draft: false
surfaces: ["cli", "console", "api"]
plans: ["free", "member"]
---

A Web App lets people use a Handler from a browser.
Only the owner and people invited by email can open it.
There is no public mode that lets anyone in.

## 1. Save the code

Save this as `hello-web.js`:

```js
export default {
  async fetch(request, env) {
    return new Response('<!doctype html><h1>Hello, Wings</h1>', {
      headers: { 'Content-Type': 'text/html; charset=utf-8' },
    })
  },
}
```

## 2. Create the Web App

```sh
wings handler deploy --name hello-web --file hello-web.js
wings handler list
```

Replace `<handler-id>` with the ID from the list.
Then create a Web App and get its URL:

```sh
wings trigger add-web <handler-id> --slug hello-web
wings trigger list <handler-id>
wings trigger url <handler-id> <trigger-id>
```

Replace `<trigger-id>` with the ID from the Trigger list.
Open the returned URL in your browser and sign in through the Console.
You should see “Hello, Wings”.

## Signing in and out

An app session lasts 24 hours.
Signing out of the Console normally signs you out of the app too.
If you see a warning that Web App sign-out failed, the app session may remain active for up to 24 hours.
Check for that warning when using a shared computer.

Disabling or deleting the app also ends its sessions.
Removing a share ends that person's sessions.
Disabling keeps the sharing settings; deleting the app removes them.

## Invite people

```sh
wings trigger share <handler-id> <trigger-id> --email teammate@example.com
wings trigger shares <handler-id> <trigger-id>
wings trigger unshare <handler-id> <trigger-id> --email teammate@example.com
```

Wings does not send invitation emails.
After adding a share, give the person the app URL.
They sign in with an AGI Lab account using the invited address.
A free account is enough.
Viewing the app does not create a Wings workspace or start their Free allowance.

| Limit | Free | Member |
| --- | --- | --- |
| People per app | 5 | 20 |
| Distinct addresses across the account | 20 | 100 |
| Additions in the last 24 hours | 30 | 30 |

Removing a share does not reduce the number of additions in the last 24 hours.
Use `shares` to check the current count and limits.
If you receive `sharing_unavailable`, this account cannot add shares yet.
You can still list and remove them.

## Decide what invited people can do

Invited people run the owner's Handler.
Through that Handler, they use the owner's Connections, Secrets, and Databases.
Their use also counts toward the owner's time allowance.
Check permissions on actions that change data, as well as on what the page displays.

Use `env.WINGS_VIEWER` to identify the viewer.
It contains `email` and `role`: `owner` for the owner, or `member` for an invited person.
The Handler cannot change this value.
It is `undefined` in other Runs and in child Handlers.

Web App Runs do not count against the per-minute or per-hour Run limits.
They do use the daily time allowance and the separate Web App access limits.

## Development limits

- Each app has its own address under `agi-wings.app`. Its root is `/`.
- GET, HEAD, and POST are supported. Send POST requests from the app's own pages.
- Requests are limited to 256 KiB and responses to 1 MiB. `/_wings/` is reserved for the service.
- Do not change data on GET.
- Service Workers, embedding in an iframe, and fetches from other apps are not supported.
- Responses use `private, no-store` so the browser does not cache them.
- Redirects must stay within the same app. Redirects to external sites are rejected.

## If a Web App stops opening

Cookies saved by another app can prevent Web Apps from opening.
Clearing the site data for `agi-wings.app` in your browser's settings may fix this.

Clearing site data also deletes localStorage.
Keep data you need to retain in a [Database](/en/tools/wings/docs/databases-sql).

Use `env.WINGS_VIEWER` for authentication instead of your own cookies.
Another app on the same site can overwrite cookies created with JavaScript.
