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 · Router · all subjects

router-settings

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

Sitemap auto-generated at /_sitemap route

Expo Router automatically injects a /_sitemap route that provides a list of all routes in the app. This route is useful for debugging purposes.

Custom root directory configuration via config plugin

You can customize the root directory using the Expo Router Config Plugin by setting the "root" property in the plugins array in app.json. For example: {"plugins": [["expo-router", {"root": "./src/routes"}]]}. This is discouraged and may lead to unexpected behavior, as many tools assume the root directory to be either app or src/app.

Custom root directory not officially supported

Changing the default root directory is highly discouraged. Bug reports regarding projects with custom root directories will not be accepted. Only tools in the exact version of Expo CLI will respect the custom root config plugin.

Fix missing files or source maps in React Native DevTools

If Chrome DevTools has exclusions in its ignore list, missing files or source maps can appear. To fix this: (1) Start React Native DevTools by pressing J from the development server terminal. (2) Open Settings by clicking the gear icon. (3) Under Extensions, click Restore defaults and reload. (4) Open Settings again and go to the Ignore List tab. (5) Uncheck any exclusions for /node_modules/.

EXPO_ROUTER_APP_ROOT not defined error

The error 'Invalid call at line 11: process.env.EXPO_ROUTER_APP_ROOT First argument of require.context should be a string' occurs when the Babel plugin expo-router/babel is not used in babel.config.js. Fix it by clearing the cache with 'npx expo start --clear' (npm), 'yarn expo start --clear' (yarn), 'pnpm expo start --clear' (pnpm), or 'bun expo start --clear' (bun).

Workaround for EXPO_ROUTER_APP_ROOT without babel plugin

If the expo-router/babel plugin cannot be used, create an index.js file at the project root with App component that calls require.context('./app') and wraps it in ExpoRoot, then export App and register it with registerRootComponent. Update package.json main field to 'index.js'. Do not use this to change the root directory as it won't account for usage in other places.

Example: index.js workaround for EXPO_ROUTER_APP_ROOT

import { registerRootComponent } from 'expo'; import { ExpoRoot } from 'expo-router'; export function App() { const ctx = require.context('./app'); return <ExpoRoot context={ctx} />; } registerRootComponent(App);

require.context not enabled error

This error occurs when using a custom version of @expo/metro-config that does not enable context modules. Expo Router requires the metro.config.js to use expo-router/metro as the default configuration. Fix by deleting metro.config.js or extending expo/metro-config.

Configure web output mode for data loaders

Data loaders work with both static rendering (web.output: 'static') and server rendering (web.output: 'server'). Set the output mode in the web configuration section of app.json.

Server headers known limitations

Server headers have two known limitations: headers do not apply to redirect responses, and headers are only applied to HTML and API route responses, not to static assets like images, fonts, or JavaScript bundles.

Server headers availability and requirements

Server headers are available in SDK 54 and later, and require expo-server to serve your exported application.

What server headers apply to in Expo Router

Server headers in Expo Router apply to HTML and API route responses only. Headers do not apply to static assets such as images, fonts, or JavaScript bundles.

Configure server headers in app.json

Server headers are configured in the expo-router plugin in app.json. Headers are specified as an object where keys are header names and values are either strings or arrays of strings. Example: {"expo": {"plugins": [["expo-router", {"headers": {"X-Frame-Options": "DENY"}}]]}}

Server headers header precedence rule

Headers defined in the expo-router plugin are applied globally but do not override headers set by API routes. If an API route returns a response with a header that is also defined in the plugin configuration, the route-specific header takes precedence.

Server headers output modes support

Server headers work with both output modes configured in app config: static mode where headers are applied when serving pre-rendered HTML files with expo-server, and server mode where headers are applied to dynamically rendered responses.

Security headers example configuration

Common security headers can be configured in app.json: {"expo": {"plugins": [["expo-router", {"headers": {"X-Frame-Options": "DENY", "X-Content-Type-Options": "nosniff", "Referrer-Policy": "strict-origin-when-cross-origin", "X-XSS-Protection": "1; mode=block"}}]]}}

Cross-Origin headers for SharedArrayBuffer

Some web APIs like SharedArrayBuffer require specific Cross-Origin headers. Configure in app.json: {"expo": {"plugins": [["expo-router", {"headers": {"Cross-Origin-Embedder-Policy": "credentialless", "Cross-Origin-Opener-Policy": "same-origin"}}]]}} This is required for features like expo-sqlite on web.

Cache-Control headers example

Set caching policies in app.json: {"expo": {"plugins": [["expo-router", {"headers": {"Cache-Control": "public, max-age=3600, s-maxage=86400"}}]]}}

Custom headers metadata example

Add custom headers with metadata in app.json: {"expo": {"plugins": [["expo-router", {"headers": {"X-App-Version": "1.0.0", "X-Environment": "production"}}]]}}

Set-Cookie headers as array example

Multiple Set-Cookie headers can be configured as an array of strings: {"Set-Cookie": ["session=abc123; HttpOnly", "preference=dark; Path=/"]}

Enable server-side rendering in app.json

To enable server-side rendering in Expo Router, set `web.output` to `"server"` in app.json and add the `expo-router` plugin with `unstable_useServerRendering: true` in the plugins array.

Server rendering requires SDK 55 or later

Server rendering is available in SDK 55 and later. It requires a deployed server for production use and is currently in alpha.

Export command for server rendering

To export your Expo Router app with server rendering enabled, run `npx expo export --platform web`. This creates a dist directory with client and server subdirectories instead of pre-generated HTML files.

Server rendering dist directory structure

When exporting with server rendering, the dist directory contains: (1) client directory with JavaScript and CSS bundles at `dist/client/_expo/static/js/web/entry-[hash].js` and `dist/client/_expo/static/css/[name]-[hash].css` for client-side hydration, and (2) server directory with routes manifest and server rendering module at `dist/server/_expo/routes.json` and `dist/server/_expo/server/render.js`.

Test production build locally with expo serve

To test a server-rendered production build locally, run `npx expo serve`. This starts a local server that renders pages on each request, simulating a production environment.

Server rendering requires deployed server

Server-side rendered Expo apps cannot be deployed to static hosting services like GitHub Pages. A runtime server is required to render pages on each request.

Server rendering deployment platforms and adapters

Server rendering is supported on multiple platforms with adapters: (1) EAS Hosting - Built-in support, (2) Node.js/Express - `expo-server/adapter/express`, (3) Cloudflare Workers - `expo-server/adapter/workerd`, (4) Vercel Edge Functions - `expo-server/adapter/vercel`, (5) Netlify Edge Functions - `expo-server/adapter/netlify`, (6) Bun - `expo-server/adapter/bun`.

Deploy server-rendered app to EAS Hosting

To deploy a server-rendered Expo Router app to EAS Hosting, run `npx expo export --platform web` followed by `npx eas-cli@latest hosting:deploy dist`. EAS Hosting supports server rendering out of the box.

Data loaders work with server rendering

Server rendering works with data loaders to fetch data on the server before rendering. With server-side rendering, data loaders are executed on the server for each request and the result is embedded in the HTML response.

Cannot mix server and static rendering in same project

Expo Router does not support mixing server and static rendering in the same project. You must choose a single output mode based on your requirements.

API routes work independently of rendering mode

API routes work with both server and static rendering. They are always executed on the server regardless of the rendering mode used for page routes.

Server rendering HTML generation timing

Server rendering generates HTML dynamically at request time, as opposed to static rendering which pre-renders HTML at build time. Server rendering delivers HTML progressively as a stream rather than a complete document.

Web output configuration for API routes

To use API routes, configure the project to use server output by setting `"output": "server"` in the `web` section of **app.json**. This configures export and production builds to generate both server and client bundles.

Enable asyncRoutes in app config

Enable async routes by setting the asyncRoutes option in the Expo Router config plugin of your app.json. The asyncRoutes option can be a boolean (true/false) or set to 'development' as a string value. Platform-specific settings can be configured using an object with keys: 'web', 'android', 'ios', and 'default'. Example: { "asyncRoutes": { "web": true, "android": false, "default": "development" } }

Files to update when adding new Expo config property

When adding a new property to the Expo config, update these files in order: 1) JSON Schema in universe at ../universe/server/www/xdl-schemas/UNVERSIONED-schema.json with description, type, pattern, and meta.bareWorkflow fields. 2) TypeScript types by running: cd packages/@expo/config-types && pnpm generate --path ../../../../universe/server/www/xdl-schemas/UNVERSIONED-schema.json. 3) Docs schema which is auto-generated from the universe schema via the Expo API server, updated by running: cd docs && pnpm run schema-sync unversioned after the universe schema is deployed. 4) Config plugin module if the property needs to be applied during prebuild, generally in packages/@expo/config-plugins/src and registered in packages/@expo/prebuild-config. 5) Tests including config plugin tests in packages/@expo/config-plugins/src/ios/__tests__/PropertyName-test.ts and prebuild config tests in packages/@expo/prebuild-config/src/plugins/__tests__/withDefaultPlugins-test.ts.

JSON schema property format for Expo config

When adding a property to UNVERSIONED-schema.json in the appropriate definition (IOS, Android, etc.), use this format: propertyName with description field containing human-readable description, type field containing JSON schema type, pattern field containing regex validation if applicable, and meta.bareWorkflow field containing instructions for bare workflow users.

Build commands for Expo config changes

After making Expo config changes, run these build and verification commands: cd packages/@expo/config-types && pnpm build to build config-types; cd packages/@expo/config-plugins && pnpm build && pnpm typecheck to build and type-check config-plugins; pnpm test src/ios/__tests__/PropertyName-test.ts to run config plugin tests; cd packages/@expo/prebuild-config && pnpm build && pnpm typecheck to build and type-check prebuild-config.

Config plugin test structure

Config plugin tests should be located in packages/@expo/config-plugins/src/ios/__tests__/PropertyName-test.ts and test the getter function and plugin behavior, including cases where the property is not set and where the value is provided.

Prebuild config tests for new properties

When adding a new property, update the prebuild config tests in packages/@expo/prebuild-config/src/plugins/__tests__/withDefaultPlugins-test.ts by adding the new property to the getLargeConfig() test fixture.

Give your agent this brain

router-settings (2/2) — Expo · Router