---
source_hash: "f37faada"
title: "Chapter 3: Deployment"
weight: 690
---

# Chapter 3: Deployment

## 1. Environment variables

### Development

```bash
# mobile/.env.development
VITE_API_URL=http://localhost/dolibarr/custom/monmodule/pwa/api.php
```

### Production

```bash
# mobile/.env.production
VITE_API_URL=https://mondomaine.com/custom/monmodule/pwa/api.php
```

## 2. Production build

```bash
cd mobile

# Install dependencies
npm install

# Production build
npm run build
```

The files are generated in `mobile/dist/`.

## 3. Deploy the files

Copy the contents of `mobile/dist/` to `pwa/dist/`:

```bash
# From the mobile/ folder
cp -r dist/* ../pwa/dist/
```

Or use an npm script:

```json
{
  "scripts": {
    "build": "vite build",
    "deploy": "vite build && cp -r dist/* ../pwa/dist/"
  }
}
```

## 4. Final structure

```
monmodule/
├── pwa/
│   ├── api.php
│   └── dist/
│       ├── index.html
│       └── assets/
│           ├── index-abc123.js
│           └── index-def456.css
└── ...
```

## 5. Server configuration

### Apache (.htaccess)

In `pwa/dist/.htaccess`:

```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /custom/monmodule/pwa/dist/

  # Redirect to index.html for React routing
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . index.html [L]
</IfModule>

# Asset caching
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/jpeg "access plus 1 year"
</IfModule>
```

### Nginx

```nginx
location /custom/monmodule/pwa/dist/ {
    try_files $uri $uri/ /custom/monmodule/pwa/dist/index.html;

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
```

## 6. Accessing the application

The application is available at:

```
https://mondomaine.com/custom/monmodule/pwa/dist/
```

## 7. PWA (Progressive Web App)

### Manifest

Create `public/manifest.json`:

```json
{
  "name": "My Application",
  "short_name": "MyApp",
  "description": "Application description",
  "start_url": "/custom/monmodule/pwa/dist/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#1976d2",
  "icons": [
    {
      "src": "images/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
```

### Service Worker (optional)

For offline mode, use `vite-plugin-pwa`:

```bash
npm install vite-plugin-pwa
```

```javascript
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: 'My Application',
        short_name: 'MyApp',
        theme_color: '#1976d2'
      }
    })
  ]
});
```

## 8. Deployment checklist

- [ ] Production environment variables configured
- [ ] Build completed without errors
- [ ] Files copied to pwa/dist/
- [ ] .htaccess configured (Apache)
- [ ] API reachable (tested with curl)
- [ ] Application reachable in the browser
- [ ] Login working
- [ ] HTTPS enabled

## 9. Debugging in production

### Dolibarr logs

```php
// In a controller
dol_syslog("Debug: " . json_encode($payload), LOG_DEBUG);
```

The logs are in `documents/dolibarr.log`.

### Browser console

In production, JavaScript errors are visible in the browser console (F12).

[Previous Chapter](/training/module9-integration/frontend) | [Back to Module](/training/module9-integration) | [Next Module: Advanced Features ->](/training/module10-fonctionnalites-avancees)
