How I setup HTTPS on localhost for Nuxt

Having just gone through this setup for a client app; I found there isn't a full guide on how to setup your local Nuxt App to call endpoints via HTTPS. I was seeing SSL and 500 errors in my fetch requests.



TLDR:

  • Setup a proxy in your nuxt.config using routeRules: {}
  • Use mkcert localhost to create 2 certificates for your project
  • Update your dev command to run the following "NODE_TLS_REJECT_UNAUTHORIZED=0 nuxt dev --https --ssl-cert localhost.pem --ssl-key localhost-key.pem"


I'm currently building a web app using Nuxt 3 and, as per usual, it's running from localhost. I've setup a proxy for all fetch requests as they're hosted on a server on another domain. During development you can usually get away with using to use HTTP and a proxy, but this time I needed to use HTTPS to call endpoints outside of my dev environment.

Proxies

In your nuxt.config you need to add a new object called routeRules. This allows a proxy to be setup for client and server side (SSR). In this object we need to define the route that we want to proxy.

Adding ** ensures we capture all sub-url's for the api, e.g: /api/posts/1/comments:

export default defineNuxtConfig({
  ...
  routeRules: {
    'api/**': {
      proxy: 'https://jsonplaceholder.typicode.com/**'
    }
  },
  ...
})

Errors

You'll find there's no issues with SSL when calling that demo endpoint. It's an 'open' endpoint and I believe they don't have any restrictions in place for SSL/HTTPS requests.

If you were to call a secure endpoint outside of you dev environment then you'd find some errors with the fetch request. For me, they were along the lines of:

HTTP/1.1 500 Internal Server Error
https POST :3000/api/end/point/sub
https: error: SSLError: HTTPSConnectionPool(host='localhost', port=3000): Max retries exceeded with url: /api/end/point/sub (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)'))) while doing a POST request to URL: https://localhost:3000/api/end/point/sub
12:03:15 PM [vite] http proxy error: /api/end/point/sub
Error: unable to verify the first certificate
  at TLSSocket.onConnectSecure (node:_tls_wrap:1674:34)
  at TLSSocket.emit (node:events:519:28)
  at TLSSocket._finishInit (node:_tls_wrap:1085:8)
  at ssl.onhandshakedone (node:_tls_wrap:871:12)

I could see that there's an issue with Certificates and my requests were being rejected and/or not handled in Nitro or the server hosting the endpoints.

Postman threw me off a little as it didn't have any issues making the requests. I find that Postman can handle requests no matter what and it's a bit of a false positive when it comes to developing against new endpoints.

Resolution

It took a bit of trial-and-error and a lot of reading through many, outdated, StackOverflow posts but I was able to work out what I needed to do:

  • I needed local legit certificates setup within the project directory
  • Node needed to process the certificates when running the dev server
  • Node also needed to be configured, only on the Dev environment, to disable certificate validation

Certificates

This is based on MacOS, I'm not sure if this will work on Windows or Linux but I can't really see it being that different

  • Install mkcert on your system.
    • I installed it globally using their 'homebrew' instructions here
  • Create valid certificates by running the following in the root of your project: mkcert localhost
    • You'll find 2 new files: localhost-key.pem and localhost.pem.
    • Update your .gitignore so you don't commit them
  • In your project's package.json, update the nuxt dev script value to the following:
"scripts": {
  "dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 nuxt dev --https --ssl-cert localhost.pem --ssl-key localhost-key.pem"
}


You can now run your project using the dev command: npm run dev

Your project will now run on https://localhost:3000.

Wrap Up

I hope you find this useful for your projects. I found it difficult to find the exact answer I needed because there were two areas that needed to be resolved - the Proxy and the certificates.