new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo · EAS · all subjects

eas-hosting

132 notes in this subject, read out of this brain and free to use. This is page 2 of 3.

Custom domain supported types

EAS Hosting supports both apex domains and subdomains as custom domains. If you own example.com, you can assign either example.com as an apex domain, or anything.example.com as a subdomain.

One custom domain per project

Each EAS Hosting project can have exactly one custom domain, which is assigned to the production deployment.

DNS record verification refresh

After adding DNS records for your custom domain, press the refresh button in the EAS Hosting dashboard until all checks pass. Depending on your DNS provider, this typically takes only a couple of minutes.

Custom domain DNS records required

Three DNS records must be configured for a custom domain: a Verification TXT record to prove domain ownership, an SSL CNAME record for Domain Control Validation (DCV) to a certificate authority, and a third record (A record for apex domains or CNAME record for subdomains) that points the domain at the EAS Hosting production deployment.

Verification TXT record location and purpose

The Verification TXT record must be created on a subdomain of your custom domain to prove you own the domain. For apex domain example.com, create it on _cf-custom-hostname.example.com. For subdomain anything.example.com, create it on _cf-custom-hostname.anything.example.com. The record contains a custom token that can be read back to verify the domain is controlled by you.

SSL CNAME record location and purpose

The SSL CNAME record proves domain ownership to a certificate authority through Domain Control Validation (DCV). For apex domain example.com, create it on _acme-challenge.example.com. For subdomain anything.example.com, create it on _acme-challenge.anything.example.com. This is a CNAME record because renewal and validation are delegated to an automated process, preventing certificates from expiring.

Production deployment routing DNS records

The third DNS record points your custom domain to EAS Hosting. For apex domains, an A record is typically recommended pointing to 172.66.0.241. For subdomains, a CNAME record is typically recommended pointing to origin.expo.app. Both are equivalent, but some DNS providers do not allow CNAME records on apex domains.

Zero downtime custom domain DNS setup order

To ensure zero downtime when switching to a custom domain, add DNS records one by one in the order presented: first add the Verification TXT record and press Refresh until confirmed, then add the SSL CNAME record until confirmed, and finally set up the third routing record. If downtime is not a concern, all three records can be added at once.

Assigning custom domain in dashboard

To assign a custom domain, navigate to your project's Hosting settings at the URL pattern /accounts/[accountName]/projects/[projectName]/hosting/settings. If you do not have a production deployment, you will be prompted to assign one first. Then enter your custom domain under the Custom domain section.

Custom domain assignment prerequisites

To assign a custom domain in EAS Hosting, you must have an EAS Hosting project with a production deployment. The custom domain will always load the production deployment. You also need to own a domain name that you want to use.

Custom domain is a premium feature

Setting up a custom domain in EAS Hosting is a premium feature and is not available on the free plan.

Environment variables supported in EAS Hosting

With EAS Hosting, only plain text and sensitive environment variables can be used. Secrets cannot be deployed with EAS Hosting.

Local development environment variables for EAS Hosting

For local development, both client- and server-side environment variables are loaded from local .env files, which should be gitignored. If using EAS environment variables, use eas env:pull to retrieve environment variables for development, preview, or production.

Storing environment variables for EAS Hosting deployments

Running npx expo export --platform web will inline EXPO_PUBLIC_ variables in frontend code, so ensure .env.local has correct environment variables before running this command. Running eas deploy --environment production will include all variables for the given environment in API routes. EAS environment variables loaded with --environment flag take precedence over .env and .env.local files. Environment variables are per deployment and deployments are immutable, so after changing an environment variable, re-export the project and re-deploy.

Server-side environment variables in EAS Hosting

All code in API routes (files ending with +api.ts) runs on the server. Since this code is never visible to the app user, sensitive environment variables such as API keys and tokens can be safely used. Server-side environment variables are not inlined in the code; they are uploaded with the deployment when running the eas deploy command.

Client-side environment variables in EAS Hosting

All code that runs in the browser is client-side. In an Expo Router project, this includes all code that is not an API Route or server function. Client-side environment variables are inlined at build time when running npx expo export. All client-side environment variables must be prefixed with EXPO_PUBLIC_. When running npx expo export, all instances of process.env.EXPO_PUBLIC_* will be replaced with values from the environment.

Log in to Expo account with EAS CLI

To log in to your Expo account using EAS CLI, run `eas login`. If you are already signed in using Expo CLI, you can skip this step. You can verify your login status by running `eas whoami`.

EAS Hosting definition and purpose

EAS Hosting is a React hosting service that allows you to deploy an exported Expo web build to a preview or production URL. It is available to anyone with an Expo account, whether on the Free plan or a paid subscription.

EAS Hosting plan benefits and differences

Free plan users get basic EAS Hosting access. Paid subscribers can create more deployments, have more bandwidth, storage, and requests, and may set up a custom domain. Learn more about different plans and benefits at the EAS pricing page.

Create new Expo project for EAS Hosting

To create a new Expo project with the default template at SDK 57, run one of the following commands: `npx create-expo-app@latest my-app --template default@sdk-57` (npm), `yarn create expo-app my-app --template default@sdk-57` (yarn), `pnpm create expo-app my-app --template default@sdk-57` (pnpm), or `bun create expo my-app --template default@sdk-57` (bun).

Preview subdomain name in EAS Hosting

A preview subdomain name is a prefix used for the preview URL of your app. For example, if you choose `my-app` as the preview subdomain name, your preview URL would be something like `https://my-app--or1170q9ix.expo.app/` and your production URL would be `https://my-app.expo.app/`.

Deploy app to EAS Hosting

To publish your website to EAS Hosting, run `eas deploy`. The first time you run this command, it will prompt you to connect an EAS project if you haven't done so yet and ask you to choose a preview subdomain name.

Export web project for EAS Hosting

To export your web project into a dist directory before deployment, run one of these commands: `npx expo export --platform web` (npm), `yarn expo export --platform web` (yarn), `pnpm expo export --platform web` (pnpm), or `bun expo export --platform web` (bun). This command must be re-run every time before deploying.

Configure expo.web.output in app config

Set the `expo.web.output` field in your app config file to one of three values: `single` exports your app to a single-page app with only one `index.html` output; `static` exports your app to a statically generated web app; `server` supports server functions and API routes as well as static pages for your app. This setting can be changed later and the app re-deployed.

Install EAS CLI globally

EAS CLI is the command-line tool to interact with EAS services from your terminal. Install it globally using one of these commands: `npm install --global eas-cli` (npm), `yarn global add eas-cli` (yarn), `pnpm add --global eas-cli` (pnpm), or `bun add --global eas-cli` (bun). You can also use `npx eas-cli@latest` as an alternative to `eas` in documentation.

EAS Hosting supported output modes

EAS Hosting supports all three output modes configured in app config's expo.web.output: (1) single - exports to a single-page app with only one index.html output; (2) static - exports to a statically generated web app; (3) server - supports server functions and API routes as well as static pages.

Export web project for EAS Hosting deployment

To deploy your web app with EAS Hosting, first create a static build by running 'npx expo export --platform web' (or equivalent with yarn, pnpm, bun) to export your web project into a dist directory. Then run 'eas deploy' to publish your web app.

EAS Hosting overview

EAS Hosting is a service from EAS for quickly deploying web projects built using Expo Router and React Native web. It seamlessly integrates with Expo CLI and automates deployment of API routes, server functions, and server-side assets.

EAS Hosting deployment output

Once your deployment is complete, the EAS CLI outputs a preview URL to access your deployed web app.

When to use EAS Hosting

EAS Hosting is recommended for: deploying a web build without setting up a separate hosting provider, using API routes or server functions in your Expo Router app, maintaining consistent deployment workflows across Android, iOS and web, automating deployments using EAS Workflows, and built-in monitoring for server-side code crashes logs and requests. EAS Hosting is not recommended for: mobile-only projects with no web component, projects requiring full Node.js runtime compatibility (EAS Hosting uses Cloudflare Workers runtime with partial Node.js support), or when you already have established web infrastructure that meets your needs.

EAS Hosting with EAS Workflows

EAS Hosting integrates with EAS Workflows using the 'deploy' job type. You can add a deploy job to your workflow configuration specifying type: deploy with environment and params (such as prod: true for production deployment).

EAS Hosting caching

API routes can return Cache-Control directives that EAS Hosting uses to cache responses on its global CDN. Static assets are cached with a default browser cache time of 3600 seconds.

EAS Hosting monitoring capabilities

EAS Hosting provides built-in monitoring in the EAS dashboard: Crashes (view uncaught errors from API routes grouped by similarity), Logs (all console.log, console.info, and console.error output from API routes), and Requests (request metadata including status, browser, region, and duration).

EAS Hosting deployment aliases

EAS Hosting deployments are immutable and each deployment gets a unique preview URL. You can create aliases to assign custom names to deployments (such as staging or production). You can instantly roll back by reassigning an alias to a previous deployment ID using 'eas deploy:alias --prod --id=<deploymentId>'.

Custom domains in EAS Hosting

Custom domains are available on paid plans in EAS Hosting. Each project can have one custom domain assigned to the production deployment. Both apex domains and subdomains are supported.

EAS Hosting runtime

EAS Hosting is built on Cloudflare Workers, which runs on the V8 JavaScript engine. It uses V8 isolates instead of full Node.js processes. Node.js compatibility modules are available but with some limitations.

EAS Hosting API routes support

EAS Hosting fully supports API routes (files ending with +api.ts) when using the server output mode. You can monitor crashes, logs, and requests from your API routes in the EAS dashboard.

CDN-Cache-Control header for EAS Hosting-specific caching

To customize caching for EAS Hosting separately from the user's browser, you can respond with a CDN-Cache-Control header. When this header is used, it implicitly adds public to the directives and forces EAS Hosting to cache the response according to the directives. This allows setting different cache behavior for browsers and EAS Hosting simultaneously.

API route caching example with Cache-Control header

Example showing how to return a Cache-Control header from an API route: export async function GET(request) { return Response.json({ ... }, { headers: { 'Cache-Control': 'public, max-age=3600' } }); }. This sets EAS Hosting to cache the response for 3600 seconds.

Cached requests count against EAS Hosting billing quota

EAS Hosting bills per request in units of 1M requests. Cached requests still count against the quota and are charged for, even if they are cached by EAS Hosting. Metrics are not affected by caching. Cached requests are logged like any other request, and metrics in the EAS dashboard reflect and represent cached requests.

Asset caching defaults and behavior

For any assets a deployment responds with, a default cache time of 3600 seconds is applied for browser caches. To improve performance, per-deployment assets are cached indefinitely internally. Since deployments are immutable, this does not affect performance. EAS Hosting will ignore its cached assets when a new deployment is assigned to an alias. For example, when promoting a new deployment to production, the cache is ignored and asset responses switch over to the new deployment instantly.

CORS caching with Access-Control-Max-Age

For many web requests, browsers make CORS requests with the OPTIONS method to determine access control settings for a route. These requests are cacheable using the special Access-Control-Max-Age header. For example, Access-Control-Max-Age: 3600 will cache the OPTIONS response for 3600 seconds for both browsers and the EAS Hosting cache. This prevents excessive requests made by browsers and prevents API routes from being called excessively often for CORS requests.

Vary header for cache keys

By default, a GET or HEAD request is only cached by its URL, and a POST request is only cached by its URL and request body. The Vary header can be used to specify that the request should use request headers as a cache key. For example, if an API route responds with Vary: custom-header, then the cached response will only be used if the request's custom-header value matches the cached request's custom-header value.

Expires header support

EAS Hosting also supports caching using the older Expires header. It specifies an HTTP Date value until a response is cached. After the specified timestamp, the response is considered stale. As this will not mark the response as publicly cacheable, it is typically only used for unauthenticated GET responses.

POST request caching on EAS Hosting

In addition to caching GET and HEAD requests, EAS Hosting also supports caching POST requests. Provided a POST request with a request body smaller than 1MB is sent, the response may specify a Cache-Control header with the public directive to mark the request as cacheable.

max-stale and stale-if-error request directives

The max-stale directive specifies a maximum time acceptable for a client to accept a cached response. For example, if a response was cached using stale-while-revalidate=3600, a request may specify max-stale=1800 to only accept a stale response with a maximum age of 1800 seconds. The stale-if-error directive may be used in requests to customize the period for which stale responses are accepted if the API route would otherwise respond with an error. These directives can only reduce the amount of acceptable staleness, not increase it.

Request Cache-Control directives

Cache-Control headers can be sent as part of a request's headers and affect how EAS Hosting chooses to return cached responses. The only-if-cached directive will only return a response if it is cached, and otherwise abort the request with a 504 response. The no-store, no-cache, or max-age=0 directives will skip cached responses and always force EAS Hosting to ignore its request cache. The min-fresh directive will skip a cached response if it is older than the specified value. For example, min-fresh=360 will prevent a cached response from being returned if it has been cached longer than 360 seconds.

stale-if-error directive

The stale-if-error directive specifies a stale time period for a response to be returned if the underlying API route fails unexpectedly. This makes an API route fault-tolerant and applies when the API route crashes with a runtime error or returns a 500, 502, 503, or 504 response status. For example, max-age=1800, stale-if-error=3600 specifies that the response is cached for 1800 seconds. After 1800 seconds, if the API route responds with an error, the stale cached response is sent to clients instead of the error.

stale-while-revalidate directive

The stale-while-revalidate directive specifies a stale time period for a response. After a cached response is considered stale, it allows the response to still be returned to clients for the specified timeframe while re-validating the request in the background. For example, max-age=1800, stale-while-revalidate=3600 specifies that the response is cached for 1800 seconds. After 1800 seconds, if a new request is made for this response, it is returned if the request is made within 3600 seconds, but the request will also be sent onwards to the API route in the background.

Expiration directives: max-age and s-maxage

The max-age directive specifies how long a response is cached until it is considered stale. The s-maxage directive is used to indicate only to EAS Hosting how long it should cache a response. The no-cache directive is equivalent to specifying a max-age of zero. The immutable directive indicates that the response is indefinitely cacheable and should be cached for as long as possible and is never considered stale.

s-maxage directive for EAS Hosting vs browser caching

The s-maxage directive may be used to differentiate between what a browser and EAS Hosting may cache. Responding with s-maxage=3600 will allow EAS Hosting to cache the response for 3600 seconds, while the user's browser will not cache it at all.

Cache-Control cacheability directives

The public directive indicates any cache, including EAS Hosting, may store the response. Without it, the response is not shared between multiple requests. The private directive indicates the response is intended for a single user and may only be cached by a browser. The no-store or no-cache directives indicate that a response may never be cached or stored. Responses to requests with no Authorization header set and that are either HEAD or GET request methods are automatically considered publicly cacheable.

Cache-Control header syntax and usage

API routes can return Cache-Control directives in response headers that EAS Hosting uses to cache responses appropriately. Cache-Control headers are strings of comma-separated settings. If a directive accepts a parameter, it is followed by an equal sign and the parameter's value, such as max-age=3600. If a directive does not accept a parameter, it is listed without a value, such as public. Multiple cache directives are separated by commas, for example: public, max-age=3600.

Using Cache-Control and CDN-Cache-Control headers together

Example showing how to use both Cache-Control and CDN-Cache-Control headers together: export async function GET(request) { return Response.json({ ... }, { headers: { 'Cache-Control': 'no-store', 'CDN-Cache-Control': 'max-age=3600' } }); }. This prevents browsers from storing the response while allowing EAS Hosting to cache for 3600 seconds.

EAS Hosting default ETag header for asset caching

EAS Hosting automatically adds an ETag header to all asset responses. This allows browsers to re-validate their caches using if-none-match request headers.

EAS Hosting default Strict-Transport-Security header

EAS Hosting automatically adds the Strict-Transport-Security header if it is missing. The default value is set to 'max-age=31536000; includeSubDomains; preload'. This header tells browsers to only access a URL with the HTTPS protocol in the future.

EAS Hosting removes X-Powered-By and X-Aspnet-Version headers

By default, EAS Hosting removes and does not forward any X-Powered-By and X-Aspnet-Version headers. With API routes, these headers do not serve much purpose and unnecessarily expose internal information about the code being run.

EAS Hosting converts X-Frame-Options headers to Content-Security-Policy

If API routes respond with custom X-Frame-Options headers, EAS Hosting automatically converts them to Content-Security-Policy directives in the response.

EAS Hosting crash page behavior

If an API route throws an unhandled JavaScript error, EAS Hosting treats this as a crash and responds with an error page. The error page is rendered as HTML if the Accept: text/html request header was sent; otherwise, it responds with a plaintext response.

EAS Hosting request headers table

EAS Hosting adds the following headers to every request before forwarding to API routes: | Request header | Description | | --- | --- | | Forwarded | Comma-separated list of semicolon-separated for, host, and proto parameters. See MDN documentation on the HTTP Forwarded header for more information. | | X-Forwarded-For | Comma-separated list of forwarder IPs for a given request | | X-Forwarded-Proto | Protocol used to make the request. Typically, https | | X-Forwarded-Host | Hostname from the incoming request | | X-Real-IP | IP address from the incoming request | | Origin | URL Origin from the incoming request | | Host | Hostname of the forwarded request (matching request.url's hostname) | | eas-colo | Code of the Cloudflare data center that handled the request. For example, lhr | | eas-ip-continent | Two letter continent code of the client. One of: AF, AN, AS, EU, NA, OC, or SA | | eas-ip-country | Three letter country code of the client in ISO-3166 Alpha 2 format. For example, US or JP | | eas-ip-region | Region code of the client in ISO-3166-2 format, which has a maximum length of three characters | | eas-ip-city | Human-readable city name of the client (optional). For example, London or Chicago | | eas-ip-latitude | Best guess of the client's latitude (optional) | | eas-ip-longitude | Best guess of the client's longitude (optional) | | eas-ip-timezone | Timezone of the client. For example, Europe/London | | eas-ip-eu | Set to 1 when the request likely originated in the jurisdictional area of the European Union |

Give your agent this brain