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.