Skip to content

Vite HTTPS on Localhost ​

Enable HTTPS for local development with Vite using trusted certificates and avoid browser security warnings.

Problem ​

When running Vite with HTTPS on localhost, Chrome displays an "invalid certificate" error even after configuring custom certificates. This occurs because browsers don't trust self-signed certificates by default, which are commonly used for local development.

The typical approach of manually generating certificates with OpenSSL and configuring Vite to use them:

js
import { defineConfig } from 'vite'
import fs from 'fs'

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync('localhost-key.pem'),
      cert: fs.readFileSync('localhost.pem')
    }
  }
})

Still results in browser security warnings that interrupt development workflows.

Solutions ​

The most popular and reliable solution is vite-plugin-mkcert, which automatically generates locally-trusted certificates.

Install the plugin:

bash
npm install vite-plugin-mkcert -D

Configure Vite:

js
import { defineConfig } from 'vite'
import mkcert from 'vite-plugin-mkcert'

export default defineConfig({
  server: {
    https: true
  },
  plugins: [mkcert()]
})

When you first run the dev server, the plugin will:

  • Generate a local Certificate Authority (CA)
  • Create domain-specific certificates for localhost
  • Install the CA in your system's trust store
  • Register with supported browsers (Chrome, Firefox, Safari)

TIP

You may be prompted for your system password on first run to install the CA certificate. This is a one-time setup.

2. Official Basic SSL Plugin ​

Vite provides an official basic SSL plugin for quick HTTPS setup:

bash
npm install -D @vitejs/plugin-basic-ssl
js
import { defineConfig } from 'vite'
import basicSsl from '@vitejs/plugin-basic-ssl'

export default defineConfig({
  plugins: [basicSsl()]
})

WARNING

This plugin generates self-signed certificates that browsers will still flag as insecure. You'll need to manually accept the security exception each time.

3. Manual Certificate Setup with mkcert ​

For more control over certificate generation, use mkcert directly:

Install mkcert:

bash
# macOS
brew install mkcert

# Windows (using Chocolatey)
choco install mkcert

# Linux (Ubuntu/Debian)
sudo apt install libnss3-tools
wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
sudo mv mkcert /usr/local/bin/

Generate certificates:

bash
# Install the local CA
mkcert -install

# Generate certificates for your project
mkdir -p .cert
mkcert -key-file .cert/key.pem -cert-file .cert/cert.pem localhost 127.0.0.1 ::1

Configure Vite:

js
import { defineConfig } from 'vite'
import fs from 'fs'

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync('./.cert/key.pem'),
      cert: fs.readFileSync('./.cert/cert.pem')
    }
  }
})

4. Testing on Mobile Devices ​

To test your local development server on mobile devices:

  1. Find your CA root certificate:

    bash
    mkcert -CAROOT
  2. Copy the rootCA.pem file from that directory to your device

  3. Install the certificate:

    • Android: Settings → Security → Encryption & credentials → Install a certificate → CA certificate
    • iOS: Open the certificate file, then go to Settings → General → Profile → Downloaded Profile → Install
  4. Access your site using your computer's local IP address:

    https://192.168.x.x:5173
bash
# macOS
ipconfig getifaddr en0

# Windows
ipconfig

# Linux
hostname -I
js
import { defineConfig } from 'vite'
import mkcert from 'vite-plugin-mkcert'

export default defineConfig({
  server: {
    https: true,
    host: '0.0.0.0' // Allow external connections
  },
  plugins: [mkcert()]
})

Troubleshooting ​

Certificate Still Not Trusted ​

If certificates still show as untrusted:

  1. Ensure you've restarted your browser after certificate installation
  2. Check that the certificate domain matches exactly what's in the address bar
  3. Verify the certificate hasn't expired

Docker Environments ​

For Docker-based development, mount pre-generated certificates:

js
import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    https: {
      key: '/path/to/ssl/SSLforMyHosts-key.pem',
      cert: '/path/to/ssl/SSLforMyHosts-certificate.pem'
    }
  }
})

Best Practices ​

  • Use vite-plugin-mkcert for the simplest setup with trusted certificates
  • Never use self-signed certificates in production
  • For production deployments, use services like Let's Encrypt or your cloud provider's SSL solution
  • Regularly update your local CA (mkcert auto-manages this)
  • Add certificate directories to your .gitignore file

Conclusion ​

For most local development scenarios, vite-plugin-mkcert provides the easiest path to HTTPS with trusted certificates. The automated setup handles certificate generation, system trust installation, and browser compatibility, eliminating security warnings and creating a smoother development experience.

For specialized needs or complex environments, manual certificate management with mkcert offers more control while maintaining browser trust.