> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shipnative.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Deployment

> Deploy your Shipnative app as a web application

Shipnative fully supports web deployment via Expo Web. Your React Native app runs on iOS, Android, **and** web from a single codebase.

> [!TIP]
>
> **Same code, three platforms.** You don't need to maintain a separate web app - your React Native code works on web automatically via react-native-web.

***

## Quick Start

Build and preview your web app:

```bash theme={null}
cd apps/app

# Development
yarn web              # Start dev server at localhost:19006

# Production build
yarn bundle:web       # Creates optimized build in web-build/
```

***

## What Works on Web

Everything! Shipnative's architecture ensures feature parity across platforms:

| Feature | Web Support |
| - | - |
| **UI Components** | Unistyles 3.0 fully supports web |
| **Authentication** | Supabase (email/password + OAuth) |
| **Social Login** | Google & Apple OAuth via browser redirect |
| **Payments** | RevenueCat Web Billing |
| **Analytics** | PostHog JavaScript SDK |
| **Error Tracking** | Sentry Browser SDK |
| **Dark Mode** | Automatic theme switching |
| **Navigation** | React Navigation web support |

***

## Deployment Options

### Vercel (Recommended)

1. Push your code to GitHub
2. Import project at [vercel.com](https://vercel.com)
3. Set **Root Directory** to `apps/app`
4. Set **Build Command** to `yarn bundle:web`
5. Set **Output Directory** to `web-build`
6. Add environment variables (from your `.env`)
7. Deploy!

### Netlify

1. Import repo at [netlify.com](https://netlify.com)
2. Set **Base directory** to `apps/app`
3. Set **Build command** to `yarn bundle:web`
4. Set **Publish directory** to `apps/app/web-build`
5. Add environment variables
6. Deploy!

### Other Platforms

The web build is a static site, so it works anywhere:

* Cloudflare Pages
* AWS Amplify
* GitHub Pages
* Firebase Hosting
* Any static host

***

## Environment Variables

Web builds need the same `EXPO_PUBLIC_*` variables as mobile:

```bash theme={null}
# Required for production
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-key

# Payments (RevenueCat Web Billing)
EXPO_PUBLIC_REVENUECAT_WEB_KEY=your-web-key

# Analytics
EXPO_PUBLIC_POSTHOG_API_KEY=your-posthog-key
EXPO_PUBLIC_POSTHOG_HOST=https://app.posthog.com

# Error tracking
EXPO_PUBLIC_SENTRY_DSN=your-sentry-dsn
```

> [!WARNING]
>
> **CORS Configuration:** Add your web domain to Supabase's allowed origins:
>
> 1. Go to Supabase Dashboard → Project Settings → API
> 2. Add your domain to "Allowed Origins (CORS)"
> 3. Include `http://localhost:19006` for local development

***

## Social Login on Web

Google and Apple OAuth work on web via browser redirects. See [Social Login → Web OAuth Setup](https://docs.shipnative.app/core-features/social-login.md#web-oauth-setup) for configuration details.

**Quick checklist:**

* Add redirect URLs to Supabase: `https://yourapp.com/auth/callback`
* Add JavaScript origins to Google Cloud Console: `https://yourapp.com`
* Ensure CORS is configured (see warning above)

***

## RevenueCat Web Billing

RevenueCat supports web subscriptions via their Web Billing feature:

1. Enable Web Billing in your RevenueCat project
2. Connect a payment gateway (Stripe recommended)
3. Add `EXPO_PUBLIC_REVENUECAT_WEB_KEY` to your environment
4. Create web-specific products in RevenueCat dashboard

The `PaywallScreen` automatically detects the web platform and uses the web SDK.

***

## Web-Specific Considerations

### Responsive Design

Shipnative uses Unistyles breakpoints for responsive layouts:

```typescript theme={null}
const styles = StyleSheet.create((theme, runtime) => ({
  container: {
    // Mobile-first
    flexDirection: 'column',
    padding: theme.spacing.md,
    
    // Tablet+
    variants: {
      breakpoint: {
        md: {
          flexDirection: 'row',
          maxWidth: 800,
        },
      },
    },
  },
}))
```

### Navigation on Web

React Navigation handles web routing automatically:

* Screen names become URL paths
* Back button works with browser history
* Deep linking supported

### SEO

For better SEO, consider:

* Adding meta tags via `expo-document-picker` or custom HTML
* Using semantic HTML elements
* Implementing proper heading hierarchy

***

## Troubleshooting

> [accordion] Vercel: 'Missing required environment variables' error
>
> **Issue:** Expo web builds deployed to Vercel fail with:
>
> ```
> Missing required environment variables: supabaseUrl, supabasePublishableKey
> ```
>
> **Why this happens:** Metro doesn't inline `process.env.EXPO_PUBLIC_*` variables for web builds the way it does for native. The app falls back to reading from `Constants.expoConfig.extra`, which requires the variables to be explicitly passed in `app.config.ts`.
>
> **Solution:** This is already fixed in the boilerplate. The `app.config.ts` includes an `extra` section that passes all `EXPO_PUBLIC_*` variables through to `Constants.expoConfig.extra`. Just make sure you have the latest boilerplate version.
>
> If you're on an older version, add this to your `app.config.ts`:
>
> ```typescript theme={null}
> return {
>   ...baseConfig,
>   extra: {
>     ...baseConfig.extra,
>     supabase_url: process.env.EXPO_PUBLIC_SUPABASE_URL,
>     supabase_publishable_key: process.env.EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY,
>     // ... other env vars
>   },
>   // ... rest of config
> }
> ```

> [accordion] CORS errors
>
> Add your domain to Supabase's allowed origins:
>
> * Dashboard → Project Settings → API → Allowed Origins
> * Include both development (`localhost:19006`) and production URLs

> [accordion] Styles look different on web
>
> Some React Native styles don't translate perfectly to web. Check:
>
> * Shadow properties (use `boxShadow` for web)
> * Touch feedback (may need web-specific hover states)
> * Fonts (ensure web fonts are loaded)

> [accordion] Build fails with 'window is not defined'
>
> Some native-only packages reference `window`. Fix:
>
> 1. Check if the package supports web
> 2. Use platform-specific imports: `MyComponent.web.tsx` / `MyComponent.tsx`
> 3. Add to Metro's `resolver.resolveRequest` if needed

***

## Marketing Page vs App Web Build

Shipnative includes **two** web experiences:

| | App Web Build | Marketing Page |
| - | - | - |
| **Location** | `apps/app` (this guide) | `apps/web` |
| **Purpose** | Full app running in browser | Landing/waitlist page |
| **Framework** | Expo Web + react-native-web | Vite + React + Tailwind |
| **Styling** | Unistyles 3.0 | Tailwind CSS |
| **Deploy** | Your app domain | Your marketing domain |

[Learn about the marketing page →](https://docs.shipnative.app/getting-started/marketing-page.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.