Working with Web Support
1. Configuring Web Settings
| Property | Values | Description |
|---|---|---|
| web.build.output | static |
Directory where the built web files are output. |
| web.build.publicUrl | / |
Base URL for the built web application. |
| web.build.analyze | false |
Enables bundle analysis tool for performance insights. |
| web.build.minify | true |
Enables minification of the built files. |
| web.build.target | es2020 |
JavaScript target version for the web build. |
Example: Web Settings in app.json
{
"expo": {
"web": {
"build": {
"output": "dist",
"publicUrl": "/my-app/",
"analyze": true,
"minify": false,
"target": "es2020"
}
}
}
}
Note: The
web.build.publicUrl property is important for deploying to subdirectories or custom domains.2. Running on Web Platform
| Command | Description | Notes |
|---|---|---|
| expo start | Starts the development server for web platform | Automatically opens the web browser |
| expo start --web | Starts the development server specifically for web | Useful when you want to run only web |
| expo start --web-only | Starts the web server without starting the mobile dev server | Useful for isolated web development |
Note: Expo Web support is built on top of React Native Web, which allows you to run your Expo project in a web browser.
Warning: Not all Expo APIs are supported on the web. Some features might not work as expected.
3. Building for Web
| Command | Description | Notes |
|---|---|---|
| expo build:web | Builds the Expo project for web deployment | Requires a valid web configuration in app.json |
Note: The web build process uses
webpack under the hood to bundle your app.
Web Build Configuration
webinapp.jsonmust define the web-specific configuration- Supports custom webpack configuration via
webpack.config.js - Build artifacts are placed in the
web-builddirectory
4. Using Web-Specific Code
Example: Conditional Web Code
import { Platform } from 'react-native';
if (Platform.OS === 'web') {
// Web-specific logic
const webSocket = new WebSocket('wss://example.com');
const storage = localStorage;
} else {
// Native logic
const storage = await AsyncStorage.getItem('key');
}
| Platform | Access Method | Notes |
|---|---|---|
| Web | Platform.OS === 'web' |
Check for web environment |
| Native | Platform.OS === 'ios' || Platform.OS === 'android' |
Check for mobile platforms |
Note: Web-specific code should be isolated to avoid runtime errors on native platforms.
Example: Web-Only Component
import React from 'react';
import { Platform } from 'react-native';
const WebOnlyComponent = () => {
if (Platform.OS !== 'web') {
return null;
}
return (
<div>
<h2>Web-Only Content</h2>
<p>This component only renders on web.</p>
</div>
);
};
export default WebOnlyComponent;
Web-Specific Considerations
- Use
Platform.OS === 'web'to detect web environment - Web-specific logic should be isolated to prevent runtime errors on native platforms
- Some React Native APIs are not available on web (e.g.,
AsyncStorage) - Use browser APIs directly where appropriate (e.g.,
localStorage,WebSocket)
5. Configuring Webpack
Example: Basic Webpack Configuration
module.exports = {
resolve: {
extensions: ['.web.js', '.js', '.json']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
]
}
}
| Property | Description | Default |
|---|---|---|
| resolve.extensions | File extensions to resolve in order | ['.js', '.json'] |
| module.rules | Rules to process files | [] |
Note: Expo uses
.web.js extensions for web-specific code.
Warning: Make sure to exclude
node_modules in your loaders to avoid performance issues.
6. Setting Favicon
| Property | Value | Description |
|---|---|---|
| favicon | string |
Path to the favicon file (e.g., ./assets/favicon.ico) |
Example: Configuring Favicon in app.json
{
"expo": {
"name": "MyApp",
"slug": "my-app",
"favicon": "./assets/favicon.ico"
}
}
Note: The favicon should be a square image in
.ico, .png, or .svg format. For web builds, it will be used as the browser tab icon.7. Implementing PWA Features
| Feature | Description | Implementation |
|---|---|---|
| Service Worker | Enables background processing and caching | |
| Manifest | Defines app metadata for PWA installation | |
| Push Notifications | Enables push notifications via Firebase or Web Push API | |
Example: Adding PWA Support to Expo App
// app.json
{
"expo": {
"name": "MyPWAApp",
"web": {
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"output": "static",
"build": {
"outputDirectory": "dist"
}
}
}
}
Note: PWA features require the
web platform configuration in app.json.Warning: Service workers must be registered from the root of your domain to function correctly in browsers.
8. Handling Responsive Design
| Property | Description | Values | Notes |
|---|---|---|---|
| width | Defines the width of the element | auto, 100%, 50px |
Can be set in pixels, percentages, or auto |
| height | Defines the height of the element | auto, 100%, 50px |
Can be set in pixels, percentages, or auto |
| flex | Controls how a flex item grows or shrinks | 0 1 auto, 1 |
Shorthand for flex-grow, flex-shrink, and flex-basis |
| maxWidth | Defines the maximum width of an element | 100%, 500px |
Prevents the element from growing beyond this value |
| minWidth | Defines the minimum width of an element | 100%, 200px |
Prevents the element from shrinking below this value |
| padding | Space inside the element's border | 10px, 5% |
Can be set in pixels, percentages, or ems |
| margin | Space outside the element's border | 10px, 5% |
Can be set in pixels, percentages, or ems |
Example: Using Flexbox for Responsive Layout
{ "flexDirection": "column", "alignItems": "center", "justifyContent": "space-between" }
Note: When using Expo Web, ensure that all layout properties are compatible with both React Native and web rendering engines.
9. Optimizing Web Bundle
| Option | Values | Description |
|---|---|---|
| bundling.treeShake | true | false |
Enables or disables tree-shaking to reduce bundle size. NEW |
| bundling.minify | true | false |
Enables or disables minification of the web bundle. NEW |
Note: Tree-shaking is enabled by default in Expo Web projects.
Example: Using Webpack config for optimization
module.exports = { optimization: { usedExports: true } };
Optimization Tips
- Use
expo installto ensure only necessary packages are included. - Enable
treeShakein yourapp.json. - Use
process.env.NODE_ENVto conditionally include debug code.
10. Deploying to Hosting
| Platform | Deployment Method | Notes |
|---|---|---|
| Vercel | expo export --platform web followed by vercel |
Supports automatic deployment via Vercel CLI. Requires vercel.json configuration. |
| Netlify | expo export --platform web followed by netlify deploy |
Supports static site deployment. Requires netlify.toml or configuration in UI. |
| Firebase Hosting | expo export --platform web followed by firebase deploy |
Requires Firebase CLI. Supports custom domains and SSL. |
| AWS Amplify | expo export --platform web followed by amplify publish |
Supports continuous deployment from Git. Requires amplify.yml. |
| GitHub Pages | expo export --platform web followed by gh-pages |
Requires gh-pages package. Supports custom domains via CNAME. |
Note: Ensure that your
expo.config.js includes the correct web configuration before exporting.
Warning: Vercel's automatic deployment may not work with all Expo configurations. Verify that assets and routing are handled correctly.
11. Using Web-Only Components
Expo provides web-specific components and APIs that are not available in native mobile environments. These components are optimized for web browsers and can be used to enhance the web experience of your Expo project.
| Component | Description | Usage |
|---|---|---|
| WebImage | Displays images in a web browser with optimized loading and caching. | |
| WebVideo | Displays videos in a web browser with support for various formats and controls. | |
| WebWebView | Embeds a web view in your Expo project to display web content. | |
Note: These components are only available when running your Expo project in a web browser. They will not function on native mobile devices.
12. Handling Browser APIs
| API | Description | Availability | Notes |
|---|---|---|---|
| document | Provides access to the DOM | Browser | Expo does not provide a DOM. Use expo-web or react-native-web for DOM access. |
| window | Represents the browser window | Browser | Expo does not provide a window object. Use expo-web or react-native-web for window access. |
| navigator | Provides information about the browser | Browser | Expo does not provide a navigator object. Use expo-web or react-native-web for navigator access. |
| localStorage | Stores data in the browser | Browser | Expo does not provide localStorage. Use expo-web or react-native-web for localStorage access. |
| fetch | Fetches data from a server | Browser | Expo does not provide fetch. Use expo-web or react-native-web for fetch access. |
Example: Using fetch in a Web Environment
import 'expo-web';
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
};
fetchData();
Note: When using Expo with web support, you must ensure that the browser APIs are properly polyfilled or wrapped to avoid runtime errors.