Local print works—production does not?

The error you may see

Console or Network → WS:

WebSocket connection to 'ws://127.0.0.1:16794/websocket/standard' failed:
EnvironmentCommon?
Dev (localhost)Rare
Production HTTPYes (LNA silent deny)
Production HTTPS (trusted cert)Allow Local Network once, then usually OK

Cause

Chrome / Edge block non-local pages from reaching 127.0.0.1 (Local Network Access). Dev pages load from localhost; production origins do not.

Many deployments still use HTTP or LAN IP/domain. Since Chrome 142 (Oct 2025), Local Network Access (LNA) requires a secure context (HTTPS) before a public site may reach the machine or LAN; HTTP pages are silently denied. Since Chrome 147, the rule applies to WebSocket, so production pages cannot reach the print client at ws://127.0.0.1:16794/websocket/standard even when the desktop client is running. Chromium browsers (Edge, etc.) follow similar policies.

Solutions

Your app must run in a secure context (HTTPS) so the browser can request WebSocket access to 127.0.0.1 and show the Local Network permission prompt. Plain HTTP is silently denied, regardless of whether the desktop client is running.

After HTTPS is working (padlock, no certificate errors), users must click Allow on the first Local Network prompt when printing.

Scenario A: Public domain (Let's Encrypt)

server {
    listen 80;
    server_name erp.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name erp.example.com;

    ssl_certificate     /etc/letsencrypt/live/erp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/erp.example.com/privkey.pem;

    root /var/www/erp/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d erp.example.com
sudo certbot renew --dry-run

Scenario B: LAN / IP only (self-signed or internal CA)

Let's Encrypt cannot issue for private IPs or internal-only names. Use a self-signed cert or enterprise CA: deploy the root to each workstation trust store, then open the app via https://.

sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 825 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/erp.key \
  -out /etc/nginx/ssl/erp.crt \
  -subj "/CN=erp.lan" \
  -addext "subjectAltName=DNS:erp.lan"

# For https://192.168.1.10 include IP in SAN, e.g.:
# -addext "subjectAltName=DNS:erp.lan,IP:192.168.1.10"
server {
    listen 443 ssl;
    server_name erp.lan;

    ssl_certificate     /etc/nginx/ssl/erp.crt;
    ssl_certificate_key /etc/nginx/ssl/erp.key;

    root /var/www/erp/dist;
    location / { try_files $uri $uri/ /index.html; }
}

If the self-signed root is not trusted on the workstation, the page is not a secure context and WebSocket to localhost still fails. Use enterprise CA rollout or Option 2 (browser flags).

Verify

  • Open the app over https://; window.isSecureContext is true
  • Desktop client running; allow Local Network on first print
  • If it still fails, check firewall or use Option 2