Chapter 3: Deployment

1. Environment variables

Development

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

Production

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

2. Production build

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/:

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

Or use an npm script:

{
  "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:

<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

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:

{
  "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:

npm install vite-plugin-pwa
// 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

// 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 | Back to Module | Next Module: Advanced Features ->