Skip to main content

Overview

This guide covers exporting the DPM Delivery Mobile app for web deployment using Expo and hosting it on various static hosting platforms.

Prerequisites

  • Node.js 18 or higher
  • npm or yarn installed
  • Expo CLI
  • Static hosting platform account (Vercel, Netlify, AWS S3, etc.)

Web Configuration

App Configuration

The web configuration is defined in app.json:
{
  "expo": {
    "web": {
      "output": "static",
      "favicon": "./src/assets/images/favicon.png"
    }
  }
}

Output Type

  • Output: static - Generates static HTML/CSS/JS files
  • Favicon: Custom favicon from ./src/assets/images/favicon.png

App Metadata

  • Name: dpm-parcel-delivery-app
  • Slug: dpm-parcel-delivery-app
  • Version: 1.0.0
  • Scheme: dpmparceldeliveryapp

Export for Web

Basic Export

Export the app for web deployment:
npx expo export --platform web
This command:
  • Builds optimized production bundles
  • Generates static HTML, CSS, and JavaScript files
  • Outputs to dist/ directory by default
  • Includes favicon and manifest files

Development Web Server

Run the web app in development mode:
npm run web
Or with Expo CLI:
npm start -- --web
The app will be available at http://localhost:8081

Custom Output Directory

Specify a custom output directory:
npx expo export --platform web --output-dir build

Production Build Options

npx expo export --platform web \
  --clear \
  --output-dir dist
Options:
  • --clear: Clear the output directory before building
  • --output-dir: Specify output directory
  • --dev: Create development build instead of production

Environment Variables

Setup Environment Variables

Create environment-specific files: .env.production:
EXPO_PUBLIC_API_URL=https://api.dpmdelivery.com
EXPO_PUBLIC_WEB_URL=https://app.dpmdelivery.com
EXPO_PUBLIC_ENV=production
.env.staging:
EXPO_PUBLIC_API_URL=https://api-staging.dpmdelivery.com
EXPO_PUBLIC_WEB_URL=https://staging.dpmdelivery.com
EXPO_PUBLIC_ENV=staging

Access Environment Variables

In your code:
import Constants from 'expo-constants';

const apiUrl = process.env.EXPO_PUBLIC_API_URL;
// or
const apiUrl = Constants.expoConfig?.extra?.apiUrl;

Build with Environment

Load environment variables during build:
export $(cat .env.production | xargs) && npx expo export --platform web

Favicon and Manifest

Favicon Configuration

The favicon is configured in app.json:
{
  "web": {
    "favicon": "./src/assets/images/favicon.png"
  }
}
Favicon requirements:
  • Format: PNG or ICO
  • Size: 16x16, 32x32, or 48x48 pixels (or larger, will be resized)
  • Location: ./src/assets/images/favicon.png

Web Manifest

Expo automatically generates a manifest.json file with:
{
  "name": "dpm-parcel-delivery-app",
  "short_name": "DPM Delivery",
  "description": "DPM Parcel Delivery Application",
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait",
  "theme_color": "#f15925",
  "background_color": "#E6F4FE"
}

Custom Manifest Values

Add custom manifest configuration to app.json:
{
  "expo": {
    "web": {
      "favicon": "./src/assets/images/favicon.png",
      "name": "DPM Parcel Delivery",
      "shortName": "DPM Delivery",
      "description": "Fast and reliable parcel delivery service",
      "themeColor": "#f15925",
      "backgroundColor": "#E6F4FE",
      "lang": "en"
    }
  }
}

Static Hosting Setup

Vercel Deployment

  1. Install Vercel CLI:
    npm install -g vercel
    
  2. Build and Deploy:
    npx expo export --platform web
    vercel --prod
    
  3. Configure vercel.json:
    {
      "version": 2,
      "builds": [
        {
          "src": "package.json",
          "use": "@vercel/static-build",
          "config": {
            "distDir": "dist"
          }
        }
      ],
      "routes": [
        {
          "src": "/(.*)",
          "dest": "/"
        }
      ]
    }
    
  4. Add Build Script to package.json:
    {
      "scripts": {
        "build": "expo export --platform web"
      }
    }
    

Netlify Deployment

  1. Install Netlify CLI:
    npm install -g netlify-cli
    
  2. Create netlify.toml:
    [build]
      command = "npx expo export --platform web"
      publish = "dist"
    
    [[redirects]]
      from = "/*"
      to = "/index.html"
      status = 200
    
  3. Deploy:
    npx expo export --platform web
    netlify deploy --prod --dir=dist
    

AWS S3 + CloudFront

  1. Build the app:
    npx expo export --platform web
    
  2. Upload to S3:
    aws s3 sync dist/ s3://your-bucket-name/ --delete
    
  3. Configure S3 bucket:
    • Enable static website hosting
    • Set index document: index.html
    • Set error document: index.html (for SPA routing)
  4. Setup CloudFront:
    • Create CloudFront distribution
    • Set origin to S3 bucket
    • Configure custom error responses (404 → /index.html)
    • Add custom domain and SSL certificate

GitHub Pages

  1. Install gh-pages:
    npm install --save-dev gh-pages
    
  2. Add deploy script to package.json:
    {
      "scripts": {
        "predeploy": "npx expo export --platform web",
        "deploy": "gh-pages -d dist"
      },
      "homepage": "https://yourusername.github.io/dpm-parcel-delivery-app"
    }
    
  3. Deploy:
    npm run deploy
    

Firebase Hosting

  1. Install Firebase CLI:
    npm install -g firebase-tools
    
  2. Initialize Firebase:
    firebase init hosting
    
  3. Configure firebase.json:
    {
      "hosting": {
        "public": "dist",
        "ignore": [
          "firebase.json",
          "**/.*",
          "**/node_modules/**"
        ],
        "rewrites": [
          {
            "source": "**",
            "destination": "/index.html"
          }
        ]
      }
    }
    
  4. Deploy:
    npx expo export --platform web
    firebase deploy --only hosting
    

Performance Optimization

Enable Compression

Most hosting providers automatically enable gzip/brotli compression. Verify by checking response headers:
curl -H "Accept-Encoding: gzip" -I https://your-domain.com

Asset Optimization

  • Images are automatically optimized by Expo
  • Use expo-image for optimized image loading
  • Enable lazy loading for routes

Caching Strategy

Configure cache headers: For Vercel (vercel.json):
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}
For Netlify (netlify.toml):
[[headers]]
  for = "/*"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

Custom Domain Setup

Vercel Custom Domain

  1. Go to Vercel dashboard
  2. Select your project
  3. Go to Settings > Domains
  4. Add your custom domain
  5. Configure DNS records:
    • Type: A, Name: @, Value: 76.76.21.21
    • Type: CNAME, Name: www, Value: cname.vercel-dns.com

Netlify Custom Domain

  1. Go to Netlify dashboard
  2. Select your site
  3. Go to Domain Settings
  4. Add custom domain
  5. Configure DNS:
    • Type: A, Name: @, Value: 75.2.60.5
    • Type: CNAME, Name: www, Value: your-site.netlify.app

SSL Certificate

Most platforms provide automatic SSL:
  • Vercel: Automatic via Let’s Encrypt
  • Netlify: Automatic via Let’s Encrypt
  • CloudFront: Use AWS Certificate Manager
  • Firebase: Automatic SSL provisioning

Monitoring and Analytics

Add Analytics

Integrate web analytics:
import * as Analytics from 'expo-analytics';

// Google Analytics
Analytics.initialize('UA-XXXXXXXXX-X');
Analytics.logEvent('page_view', { page: '/home' });

Error Tracking

Add error tracking service:
import * as Sentry from '@sentry/react';

Sentry.init({
  dsn: 'your-sentry-dsn',
  environment: process.env.EXPO_PUBLIC_ENV,
});

Continuous Deployment

GitHub Actions for Vercel

name: Deploy to Vercel

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build for Web
        run: npx expo export --platform web
        env:
          EXPO_PUBLIC_API_URL: ${{ secrets.API_URL }}
          EXPO_PUBLIC_ENV: production
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'
          working-directory: ./dist

GitHub Actions for Netlify

name: Deploy to Netlify

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build for Web
        run: npx expo export --platform web
        env:
          EXPO_PUBLIC_API_URL: ${{ secrets.API_URL }}
      
      - name: Deploy to Netlify
        uses: netlify/actions/cli@master
        with:
          args: deploy --prod --dir=dist
        env:
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

Troubleshooting

Build Fails

Clear cache and rebuild:
npx expo export --platform web --clear
Check Node version:
node --version  # Should be 18 or higher

Assets Not Loading

  • Verify asset paths are relative
  • Check favicon path in app.json
  • Ensure assets are included in bundle
  • Check browser console for 404 errors

Routing Issues

  • Configure hosting platform for SPA routing
  • All routes should redirect to index.html
  • Verify expo-router configuration

Environment Variables Not Working

  • Prefix web env vars with EXPO_PUBLIC_
  • Rebuild after changing env vars
  • Verify env vars in hosting platform settings

Performance Issues

  • Enable compression (gzip/brotli)
  • Implement code splitting
  • Use lazy loading for routes
  • Optimize images and assets
  • Enable CDN caching

Next Steps

  • Set up automated deployments
  • Configure custom domain with SSL
  • Implement analytics and monitoring
  • Set up error tracking
  • Optimize for Core Web Vitals
  • Add PWA features (service workers, offline support)

Build docs developers (and LLMs) love