'"Websocket connection failed" when proxying requests to Next.js app via Apache server

Since upgrading to Next.js 12 I'm getting the following error in the console when I run my Next.js app:

WebSocket connection to 'wss://mysite.local/_next/webpack-hmr' failed

I've discovered that this is related with Next.js 12 using web sockets for HMR connection (unlike previous Next.js versions). In the guide to upgrading to Next.js 12, the docs provide the following snippet as a fix when using Nginx:

location /_next/webpack-hmr {
    proxy_pass http://localhost:3000/_next/webpack-hmr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

However, I use Apache to proxy requests to my Next.js app and can't find an example on how to do this with Apache. I know very little about server configuration or web sockets, so I would appreciate some help in removing that annoying error.

I've searched around and tried a few things on my own, but had no success. Here's one attempt I've made (notice the rewrite rules at the bottom):

<VirtualHost *:443>
   ServerName mysite.local
   DocumentRoot "/Users/grazianodev/Projects/mysite"
   SSLEngine On
   SSLCertificateFile "/Users/grazianodev/Projects/.crt/mysite.local.pem"
   SSLCertificateKeyFile "/Users/grazianodev/Projects/.crt/mysite.local-key.pem"    
   ProxyPass / http://localhost:3000/
   ProxyPassReverse / http://localhost:3000/
   RewriteEngine on
   RewriteCond %{HTTP:Upgrade} websocket [NC]
   RewriteCond %{HTTP:Connection} upgrade [NC]
   RewriteRule ^/?(.*) "wss://mysite.local/$1" [P,L]   
</VirtualHost>


Solution 1:[1]

You can try something like the following for Apache. You might have to tweak the ports and I haven't tested it:

<VirtualHost *:443>
   ServerName mysite.local
   DocumentRoot "/Users/grazianodev/Projects/mysite"
   SSLEngine On
   SSLCertificateFile "/Users/grazianodev/Projects/.crt/mysite.local.pem"
   SSLCertificateKeyFile "/Users/grazianodev/Projects/.crt/mysite.local-key.pem"    
   ProxyPass / http://localhost:3000/
   ProxyPassReverse / http://localhost:3000/
   RewriteEngine on
   RewriteCond %{HTTP:Upgrade} websocket [NC]
   RewriteCond %{HTTP:Connection} upgrade [NC]
   
   ## Match webpack-hmr to mysite.local
   ProxyPreserveHost On
   ProxyPassMatch ^/(_next/webpack-hmr)$  wss://mysite.local/$1
</VirtualHost>

Solution 2:[2]

What i did to make it work:

<VirtualHost *:443>
 # ServerName yourwebsite.local
 ServerName "${WEBSITE_SERVER_NAME}"

 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000/

 # Next.js 12 uses websocket
 <Location /_next/webpack-hmr>
    RewriteEngine On
    RewriteCond %{QUERY_STRING} transport=websocket [NC]
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule /(.*) ws://localhost:3000/_next/webpack-hmr/$1 [P,L]
    ProxyPass ws://localhost:3000/_next/webpack-hmr retry=0 timeout=30
    ProxyPassReverse ws://localhost:3000/_next/webpack-hmr
 </Location>
</VirtualHost>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ouflak
Solution 2 Bogdan Le