# Publish web apps

A web app built with Flutter Web, React Native Web, or Next.js runs as a Docker container on your server, gets its dev address automatically, and uses your own domain in production.

> Source: https://www.application-platform.com/en/docs/publish-web-apps/

Web apps are the browser version of your app component. The pipeline builds a Docker image from Flutter Web, React Native Web (Expo), or Next.js and rolls it out to the [server]({{< relref "servers" >}}) of your project; for production you need a [domain]({{< relref "domain" >}}). The deploy flow is described in [Git workflow and deployment]({{< relref "git-workflow" >}}).

## How the web app is served

Traefik forwards requests to the web app's container based on the domain; the platform sets up the HTTPS certificates. Dev and production are separate environments with their own configuration in the `gitops-configuration` repository.

## Backend address and other variables

The platform writes the backend URL of each environment into `env/dev.generated.env` and `env/prod.generated.env`; values shared across stages, such as the Sentry DSN, live in `env/shared.generated.env`. These files are regenerated whenever the project changes and are not edited; your own variables belong in the matching `env/*.custom.env`. How the files are loaded during the build and by `ap run-local` is covered in [Environment variables]({{< relref "environment-setup" >}}).

## Your web app's addresses

| Environment | URL |
|-------------|-----|
| Dev | `<app>.dev.<project>.<organization-domain>`, assigned automatically |
| Production | your own domain from the project configuration |

For production, you enter your domain in the project; the platform shows the required DNS records in the domain detail and keeps checking whether they are set, as described in [Configure DNS]({{< relref "domain-how-to" >}}). If the domain is hosted at Cloudflare, the platform sets the records itself once Cloudflare is connected under **Connections**.

In a [whitelabel project]({{< relref "whitelabel-apps" >}}), every variant gets its own domains; without a custom domain, the platform assigns `<variant>.<project>.<organization-domain>`.

Errors from the web app show up in your Sentry project once you enable Sentry for the component under **Features** ([Error tracking]({{< relref "error-tracking" >}})).

